~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/ipxe/src/net/infiniband/ib_sma.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 ) {
 
58
        struct ib_node_info *node_info = &mad->smp.smp_data.node_info;
 
59
        int rc;
 
60
 
 
61
        /* Fill in information */
 
62
        memset ( node_info, 0, sizeof ( *node_info ) );
 
63
        node_info->base_version = IB_MGMT_BASE_VERSION;
 
64
        node_info->class_version = IB_SMP_CLASS_VERSION;
 
65
        node_info->node_type = IB_NODE_TYPE_HCA;
 
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 */
 
77
        mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
 
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 ) {
 
97
        struct ib_node_desc *node_desc = &mad->smp.smp_data.node_desc;
 
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 ) );
 
107
        snprintf ( node_desc->node_string, sizeof ( node_desc->node_string ),
 
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 */
 
115
        mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
 
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 ) {
 
135
        struct ib_guid_info *guid_info = &mad->smp.smp_data.guid_info;
 
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 */
 
144
        mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
 
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 );
 
173
        if ( ( link_width_enabled = port_info->link_width_enabled ) )
 
174
                ibdev->link_width_enabled = link_width_enabled;
 
175
        if ( ( link_speed_enabled =
 
176
               ( port_info->link_speed_active__link_speed_enabled & 0xf ) ) )
 
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 ) {
 
205
        struct ib_port_info *port_info = &mad->smp.smp_data.port_info;
 
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 =
 
212
                              htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR );
 
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;
 
224
        port_info->link_width_enabled = ibdev->link_width_enabled;
 
225
        port_info->link_width_supported = ibdev->link_width_supported;
 
226
        port_info->link_width_active = ibdev->link_width_active;
 
227
        port_info->link_speed_supported__port_state =
 
228
                ( ( ibdev->link_speed_supported << 4 ) | ibdev->port_state );
 
229
        port_info->port_phys_state__link_down_def_state =
 
230
                ( ( IB_PORT_PHYS_STATE_POLLING << 4 ) |
 
231
                  IB_PORT_PHYS_STATE_POLLING );
 
232
        port_info->link_speed_active__link_speed_enabled =
 
233
                ( ( ibdev->link_speed_active << 4 ) |
 
234
                  ibdev->link_speed_enabled );
 
235
        port_info->neighbour_mtu__mastersm_sl =
 
236
                ( ( IB_MTU_2048 << 4 ) | ibdev->sm_sl );
 
237
        port_info->vl_cap__init_type = ( IB_VL_0 << 4 );
 
238
        port_info->init_type_reply__mtu_cap = IB_MTU_2048;
 
239
        port_info->operational_vls__enforcement = ( IB_VL_0 << 4 );
 
240
        port_info->guid_cap = 1;
 
241
 
 
242
        /* Send GetResponse */
 
243
        mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
 
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 ) {
 
262
        struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table;
 
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 ) {
 
291
        struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table;
 
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 =
 
298
                              htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR );
 
299
                        /* Fall through to generate GetResponse */
 
300
                }
 
301
        }
 
302
 
 
303
        /* Fill in information */
 
304
        mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
 
305
        memset ( pkey_table, 0, sizeof ( *pkey_table ) );
 
306
        pkey_table->pkey[0] = htons ( ibdev->pkey );
 
307
 
 
308
        /* Send GetResponse */
 
309
        mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
 
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
        {
 
320
                .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
 
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
}