iPXE
ib_sma.c
Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <byteswap.h>
33 #include <ipxe/settings.h>
34 #include <ipxe/infiniband.h>
35 #include <ipxe/iobuf.h>
36 #include <ipxe/ib_mi.h>
37 #include <ipxe/ib_sma.h>
38 
39 /**
40  * @file
41  *
42  * Infiniband Subnet Management Agent
43  *
44  */
45 
46 /**
47  * Node information
48  *
49  * @v ibdev Infiniband device
50  * @v mi Management interface
51  * @v mad Received MAD
52  * @v av Source address vector
53  */
54 static void ib_sma_node_info ( struct ib_device *ibdev,
55  struct ib_mad_interface *mi,
56  union ib_mad *mad,
57  struct ib_address_vector *av ) {
59  int rc;
60 
61  /* Fill in information */
62  memset ( node_info, 0, sizeof ( *node_info ) );
66  node_info->num_ports = ib_count_ports ( ibdev );
67  memcpy ( &node_info->sys_guid, &ibdev->node_guid,
68  sizeof ( node_info->sys_guid ) );
69  memcpy ( &node_info->node_guid, &ibdev->node_guid,
70  sizeof ( node_info->node_guid ) );
71  memcpy ( &node_info->port_guid, &ibdev->gid.s.guid,
72  sizeof ( node_info->port_guid ) );
73  node_info->partition_cap = htons ( 1 );
74  node_info->local_port_num = ibdev->port;
75 
76  /* Send GetResponse */
78  if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
79  DBGC ( mi, "SMA %p could not send NodeInfo GetResponse: %s\n",
80  mi, strerror ( rc ) );
81  return;
82  }
83 }
84 
85 /**
86  * Node description
87  *
88  * @v ibdev Infiniband device
89  * @v mi Management interface
90  * @v mad Received MAD
91  * @v av Source address vector
92  */
93 static void ib_sma_node_desc ( struct ib_device *ibdev,
94  struct ib_mad_interface *mi,
95  union ib_mad *mad,
96  struct ib_address_vector *av ) {
98  union ib_guid *guid = &ibdev->node_guid;
99  char hostname[ sizeof ( node_desc->node_string ) ];
100  int hostname_len;
101  int rc;
102 
103  /* Fill in information */
104  memset ( node_desc, 0, sizeof ( *node_desc ) );
105  hostname_len = fetch_string_setting ( NULL, &hostname_setting,
106  hostname, sizeof ( hostname ) );
108  "iPXE %s%s%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (%s)",
109  hostname, ( ( hostname_len >= 0 ) ? " " : "" ),
110  guid->bytes[0], guid->bytes[1], guid->bytes[2],
111  guid->bytes[3], guid->bytes[4], guid->bytes[5],
112  guid->bytes[6], guid->bytes[7], ibdev->dev->name );
113 
114  /* Send GetResponse */
116  if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
117  DBGC ( mi, "SMA %p could not send NodeDesc GetResponse: %s\n",
118  mi, strerror ( rc ) );
119  return;
120  }
121 }
122 
123 /**
124  * GUID information
125  *
126  * @v ibdev Infiniband device
127  * @v mi Management interface
128  * @v mad Received MAD
129  * @v av Source address vector
130  */
131 static void ib_sma_guid_info ( struct ib_device *ibdev,
132  struct ib_mad_interface *mi,
133  union ib_mad *mad,
134  struct ib_address_vector *av ) {
136  int rc;
137 
138  /* Fill in information */
139  memset ( guid_info, 0, sizeof ( *guid_info ) );
140  memcpy ( guid_info->guid[0], &ibdev->gid.s.guid,
141  sizeof ( guid_info->guid[0] ) );
142 
143  /* Send GetResponse */
145  if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
146  DBGC ( mi, "SMA %p could not send GuidInfo GetResponse: %s\n",
147  mi, strerror ( rc ) );
148  return;
149  }
150 }
151 
152 /**
153  * Set port information
154  *
155  * @v ibdev Infiniband device
156  * @v mi Management interface
157  * @v mad Received MAD
158  * @ret rc Return status code
159  */
160 static int ib_sma_set_port_info ( struct ib_device *ibdev,
161  struct ib_mad_interface *mi,
162  union ib_mad *mad ) {
163  const struct ib_port_info *port_info = &mad->smp.smp_data.port_info;
164  unsigned int link_width_enabled;
165  unsigned int link_speed_enabled;
166  int rc;
167 
168  /* Set parameters */
169  memcpy ( &ibdev->gid.s.prefix, port_info->gid_prefix,
170  sizeof ( ibdev->gid.s.prefix ) );
171  ibdev->lid = ntohs ( port_info->lid );
172  ibdev->sm_lid = ntohs ( port_info->mastersm_lid );
175  if ( ( link_speed_enabled =
177  ibdev->link_speed_enabled = link_speed_enabled;
178  ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf );
179  DBGC ( mi, "SMA %p set LID %d SMLID %d link width %d speed %d\n",
180  mi, ibdev->lid, ibdev->sm_lid, ibdev->link_width_enabled,
181  ibdev->link_speed_enabled );
182 
183  /* Update parameters on device */
184  if ( ( rc = ib_set_port_info ( ibdev, mad ) ) != 0 ) {
185  DBGC ( mi, "SMA %p could not set port information: %s\n",
186  mi, strerror ( rc ) );
187  return rc;
188  }
189 
190  return 0;
191 }
192 
193 /**
194  * Port information
195  *
196  * @v ibdev Infiniband device
197  * @v mi Management interface
198  * @v mad Received MAD
199  * @v av Source address vector
200  */
201 static void ib_sma_port_info ( struct ib_device *ibdev,
202  struct ib_mad_interface *mi,
203  union ib_mad *mad,
204  struct ib_address_vector *av ) {
206  int rc;
207 
208  /* Set parameters if applicable */
209  if ( mad->hdr.method == IB_MGMT_METHOD_SET ) {
210  if ( ( rc = ib_sma_set_port_info ( ibdev, mi, mad ) ) != 0 ) {
211  mad->hdr.status =
213  /* Fall through to generate GetResponse */
214  }
215  }
216 
217  /* Fill in information */
218  memset ( port_info, 0, sizeof ( *port_info ) );
219  memcpy ( port_info->gid_prefix, &ibdev->gid.s.prefix,
220  sizeof ( port_info->gid_prefix ) );
221  port_info->lid = ntohs ( ibdev->lid );
222  port_info->mastersm_lid = ntohs ( ibdev->sm_lid );
223  port_info->local_port_num = ibdev->port;
228  ( ( ibdev->link_speed_supported << 4 ) | ibdev->port_state );
230  ( ( IB_PORT_PHYS_STATE_POLLING << 4 ) |
233  ( ( ibdev->link_speed_active << 4 ) |
234  ibdev->link_speed_enabled );
236  ( ( IB_MTU_2048 << 4 ) | ibdev->sm_sl );
237  port_info->vl_cap__init_type = ( IB_VL_0 << 4 );
240  port_info->guid_cap = 1;
241 
242  /* Send GetResponse */
244  if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
245  DBGC ( mi, "SMA %p could not send PortInfo GetResponse: %s\n",
246  mi, strerror ( rc ) );
247  return;
248  }
249 }
250 
251 /**
252  * Set partition key table
253  *
254  * @v ibdev Infiniband device
255  * @v mi Management interface
256  * @v mad Received MAD
257  * @ret rc Return status code
258  */
259 static int ib_sma_set_pkey_table ( struct ib_device *ibdev,
260  struct ib_mad_interface *mi,
261  union ib_mad *mad ) {
263  int rc;
264 
265  /* Set parameters */
266  ibdev->pkey = ntohs ( pkey_table->pkey[0] );
267  DBGC ( mi, "SMA %p set pkey %04x\n", mi, ibdev->pkey );
268 
269  /* Update parameters on device */
270  if ( ( rc = ib_set_pkey_table ( ibdev, mad ) ) != 0 ) {
271  DBGC ( mi, "SMA %p could not set pkey table: %s\n",
272  mi, strerror ( rc ) );
273  return rc;
274  }
275 
276  return 0;
277 }
278 
279 /**
280  * Partition key table
281  *
282  * @v ibdev Infiniband device
283  * @v mi Management interface
284  * @v mad Received MAD
285  * @v av Source address vector
286  */
287 static void ib_sma_pkey_table ( struct ib_device *ibdev,
288  struct ib_mad_interface *mi,
289  union ib_mad *mad,
290  struct ib_address_vector *av ) {
292  int rc;
293 
294  /* Set parameters, if applicable */
295  if ( mad->hdr.method == IB_MGMT_METHOD_SET ) {
296  if ( ( rc = ib_sma_set_pkey_table ( ibdev, mi, mad ) ) != 0 ) {
297  mad->hdr.status =
299  /* Fall through to generate GetResponse */
300  }
301  }
302 
303  /* Fill in information */
305  memset ( pkey_table, 0, sizeof ( *pkey_table ) );
306  pkey_table->pkey[0] = htons ( ibdev->pkey );
307 
308  /* Send GetResponse */
310  if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
311  DBGC ( mi, "SMA %p could not send PKeyTable GetResponse: %s\n",
312  mi, strerror ( rc ) );
313  return;
314  }
315 }
316 
317 /** Subnet management agent */
318 struct ib_mad_agent ib_sma_agent[] __ib_mad_agent = {
319  {
321  .class_version = IB_SMP_CLASS_VERSION,
322  .attr_id = htons ( IB_SMP_ATTR_NODE_INFO ),
323  .handle = ib_sma_node_info,
324  },
325  {
326  .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
327  .class_version = IB_SMP_CLASS_VERSION,
328  .attr_id = htons ( IB_SMP_ATTR_NODE_DESC ),
329  .handle = ib_sma_node_desc,
330  },
331  {
332  .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
333  .class_version = IB_SMP_CLASS_VERSION,
334  .attr_id = htons ( IB_SMP_ATTR_GUID_INFO ),
335  .handle = ib_sma_guid_info,
336  },
337  {
338  .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
339  .class_version = IB_SMP_CLASS_VERSION,
340  .attr_id = htons ( IB_SMP_ATTR_PORT_INFO ),
341  .handle = ib_sma_port_info,
342  },
343  {
344  .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
345  .class_version = IB_SMP_CLASS_VERSION,
346  .attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ),
347  .handle = ib_sma_pkey_table,
348  },
349 };
350 
351 /**
352  * Create subnet management agent and interface
353  *
354  * @v ibdev Infiniband device
355  * @v mi Management interface
356  * @ret rc Return status code
357  */
358 int ib_create_sma ( struct ib_device *ibdev, struct ib_mad_interface *mi ) {
359 
360  /* Nothing to do */
361  DBGC ( ibdev, "IBDEV %s SMA using SMI %p\n", ibdev->name, mi );
362 
363  return 0;
364 }
365 
366 /**
367  * Destroy subnet management agent and interface
368  *
369  * @v ibdev Infiniband device
370  * @v mi Management interface
371  */
372 void ib_destroy_sma ( struct ib_device *ibdev __unused,
373  struct ib_mad_interface *mi __unused ) {
374  /* Nothing to do */
375 }
int ib_set_pkey_table(struct ib_device *ibdev, union ib_mad *mad)
Set partition key table.
Definition: infiniband.c:867
void ib_destroy_sma(struct ib_device *ibdev __unused, struct ib_mad_interface *mi __unused)
Destroy subnet management agent and interface.
Definition: ib_sma.c:372
struct ib_node_info node_info
Definition: ib_mad.h:182
uint8_t method
Definition: ib_mad.h:542
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Infiniband management interfaces.
Infiniband protocol.
#define IB_PORT_PHYS_STATE_POLLING
Definition: ib_mad.h:157
uint8_t num_ports
Definition: ib_mad.h:77
#define IB_MTU_2048
Definition: ib_mad.h:162
char name[IBDEV_NAME_LEN]
Name of this Infiniband device.
Definition: infiniband.h:408
union ib_guid guid
Definition: ib_packet.h:40
union ib_gid gid
Port GID (comprising GID prefix and port GUID)
Definition: infiniband.h:439
static int ib_sma_set_pkey_table(struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad)
Set partition key table.
Definition: ib_sma.c:259
uint8_t link_width_enabled
Definition: ib_mad.h:113
#define IB_SMP_ATTR_NODE_INFO
Definition: ib_mad.h:45
uint8_t port_phys_state__link_down_def_state
Definition: ib_mad.h:117
Error codes.
uint8_t link_width_active
Definition: ib_mad.h:115
I/O buffers.
uint16_t lid
Port LID.
Definition: infiniband.h:441
uint16_t mastersm_lid
Definition: ib_mad.h:108
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:75
union ib_smp_data smp_data
Definition: ib_mad.h:590
union ib_guid node_guid
Definition: ib_mad.h:79
struct device * dev
Underlying device.
Definition: infiniband.h:410
int ib_set_port_info(struct ib_device *ibdev, union ib_mad *mad)
Set port information.
Definition: infiniband.c:842
uint16_t lid
Definition: ib_mad.h:107
A Node Description attribute.
Definition: ib_mad.h:65
#define ntohs(value)
Definition: byteswap.h:136
static void ib_sma_pkey_table(struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av)
Partition key table.
Definition: ib_sma.c:287
static void ib_sma_guid_info(struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av)
GUID information.
Definition: ib_sma.c:131
#define IB_MGMT_METHOD_SET
Definition: ib_mad.h:570
An Infiniband management interface.
Definition: ib_mi.h:88
int ib_create_sma(struct ib_device *ibdev, struct ib_mad_interface *mi)
Create subnet management agent and interface.
Definition: ib_sma.c:358
uint8_t link_speed_enabled
Link speed enabled.
Definition: infiniband.h:433
static void ib_sma_node_info(struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av)
Node information.
Definition: ib_sma.c:54
#define IB_MGMT_CLASS_SUBN_LID_ROUTED
Definition: ib_mad.h:555
uint8_t link_width_enabled
Link width enabled.
Definition: infiniband.h:427
uint8_t link_speed_active__link_speed_enabled
Definition: ib_mad.h:119
struct ib_port_info port_info
Definition: ib_mad.h:14
uint8_t node_type
Definition: ib_mad.h:76
uint8_t link_width_supported
Link width supported.
Definition: infiniband.h:425
uint8_t base_version
Definition: ib_mad.h:74
struct ib_port_info port_info
Definition: ib_mad.h:184
uint8_t guid[8][8]
Definition: ib_mad.h:97
An Infiniband device.
Definition: infiniband.h:398
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void ib_sma_node_desc(struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av)
Node description.
Definition: ib_sma.c:93
uint8_t local_port_num
Definition: ib_mad.h:84
uint8_t link_speed_supported__port_state
Definition: ib_mad.h:116
static void ib_sma_port_info(struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av)
Port information.
Definition: ib_sma.c:201
#define IB_SMP_CLASS_VERSION
Subnet management class version.
Definition: ib_mad.h:34
A Node Information attribute.
Definition: ib_mad.h:73
uint16_t sm_lid
Subnet manager LID.
Definition: infiniband.h:443
An Infiniband management agent.
Definition: ib_mi.h:21
int ib_count_ports(struct ib_device *ibdev)
Count Infiniband HCA ports.
Definition: infiniband.c:822
int fetch_string_setting(struct settings *settings, const struct setting *setting, char *data, size_t len)
Fetch value of string setting.
Definition: settings.c:840
#define IB_NODE_TYPE_HCA
Definition: ib_mad.h:88
uint8_t link_width_enabled
Definition: ib_mad.h:19
uint16_t pkey[32]
Definition: ib_mad.h:176
#define IB_MGMT_METHOD_GET_RESP
Definition: ib_mad.h:571
uint8_t sm_sl
Subnet manager SL.
Definition: infiniband.h:445
Configuration settings.
union ib_guid prefix
Definition: ib_packet.h:39
unsigned int port
Port number.
Definition: infiniband.h:418
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct ib_mad_smp smp
Definition: ib_mad.h:612
#define IB_SMP_ATTR_GUID_INFO
Definition: ib_mad.h:47
struct ib_node_info node_info
Definition: ib_mad.h:12
uint8_t neighbour_mtu__mastersm_sl
Definition: ib_mad.h:120
struct ib_node_desc node_desc
Definition: ib_mad.h:11
An Infiniband Globally Unique Identifier.
Definition: ib_packet.h:18
char node_string[64]
Definition: ib_mad.h:66
struct ib_pkey_table pkey_table
Definition: ib_mad.h:15
union ib_guid node_guid
Node GUID.
Definition: infiniband.h:437
#define IB_SMP_ATTR_PKEY_TABLE
Definition: ib_mad.h:49
uint8_t guid_cap
Definition: ib_mad.h:131
struct ib_mad_agent ib_sma_agent [] __ib_mad_agent
Subnet management agent.
Definition: ib_sma.c:318
uint8_t link_width_active
Link width active.
Definition: infiniband.h:429
#define IB_SMP_ATTR_NODE_DESC
Definition: ib_mad.h:44
uint8_t gid_prefix[8]
Definition: ib_mad.h:106
uint8_t class_version
Definition: ib_mad.h:75
#define IB_VL_0
Definition: ib_mad.h:165
uint64_t guid
GUID.
Definition: edd.h:30
#define IB_SMP_ATTR_PORT_INFO
Definition: ib_mad.h:48
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
uint8_t link_width_supported
Definition: ib_mad.h:114
struct ib_mad_hdr hdr
Definition: ib_mad.h:611
uint8_t link_speed_active
Link speed active.
Definition: infiniband.h:435
uint8_t mgmt_class
Management class.
Definition: ib_mi.h:23
struct ib_guid_info guid_info
Definition: ib_mad.h:183
uint8_t port_state
Port state.
Definition: infiniband.h:423
struct ib_node_desc node_desc
Definition: ib_mad.h:181
Infiniband subnet management agent.
#define IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR
Definition: ib_mad.h:583
union ib_guid port_guid
Definition: ib_mad.h:80
A management datagram.
Definition: ib_mad.h:610
#define IB_MGMT_BASE_VERSION
Definition: ib_mad.h:552
uint8_t link_speed_supported
Link speed supported.
Definition: infiniband.h:431
struct ib_pkey_table pkey_table
Definition: ib_mad.h:185
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
uint16_t pkey
Partition key.
Definition: infiniband.h:447
uint16_t partition_cap
Definition: ib_mad.h:81
An Infiniband Address Vector.
Definition: infiniband.h:72
A Partition Key Table attribute.
Definition: ib_mad.h:175
uint8_t local_port_num
Definition: ib_mad.h:112
uint8_t init_type_reply__mtu_cap
Definition: ib_mad.h:125
A GUID Information attribute.
Definition: ib_mad.h:96
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
union ib_guid sys_guid
Definition: ib_mad.h:78
uint8_t operational_vls__enforcement
Definition: ib_mad.h:127
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
A Port Information attribute.
Definition: ib_mad.h:104
uint8_t vl_cap__init_type
Definition: ib_mad.h:121
#define htons(value)
Definition: byteswap.h:135
int ib_mi_send(struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av)
Transmit MAD.
Definition: ib_mi.c:187
union ib_mad mad
Definition: arbel.h:12
uint16_t status
Definition: ib_mad.h:543
static int ib_sma_set_port_info(struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad)
Set port information.
Definition: ib_sma.c:160
void * memset(void *dest, int character, size_t len) __nonnull
struct ib_guid_info guid_info
Definition: ib_mad.h:13
struct ib_gid::@532 s