iPXE
ib_smc.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 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
24FILE_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 <unistd.h>
31#include <byteswap.h>
32#include <ipxe/infiniband.h>
33#include <ipxe/ib_smc.h>
34
35/**
36 * @file
37 *
38 * Infiniband Subnet Management Client
39 *
40 */
41
42/**
43 * Issue local MAD
44 *
45 * @v ibdev Infiniband device
46 * @v attr_id Attribute ID, in network byte order
47 * @v attr_mod Attribute modifier, in network byte order
48 * @v local_mad Method for issuing local MADs
49 * @v mad Management datagram to fill in
50 * @ret rc Return status code
51 */
52static int ib_smc_mad ( struct ib_device *ibdev, uint16_t attr_id,
54 union ib_mad *mad ) {
55 int rc;
56
57 /* Construct MAD */
58 memset ( mad, 0, sizeof ( *mad ) );
59 mad->hdr.base_version = IB_MGMT_BASE_VERSION;
60 mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
61 mad->hdr.class_version = 1;
62 mad->hdr.method = IB_MGMT_METHOD_GET;
63 mad->hdr.attr_id = attr_id;
64 mad->hdr.attr_mod = attr_mod;
65
66 /* Issue MAD */
67 if ( ( rc = local_mad ( ibdev, mad ) ) != 0 )
68 return rc;
69
70 return 0;
71}
72
73/**
74 * Get node information
75 *
76 * @v ibdev Infiniband device
77 * @v local_mad Method for issuing local MADs
78 * @v mad Management datagram to fill in
79 * @ret rc Return status code
80 */
81static int ib_smc_get_node_info ( struct ib_device *ibdev,
82 ib_local_mad_t local_mad,
83 union ib_mad *mad ) {
84 int rc;
85
86 /* Issue MAD */
87 if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_NODE_INFO ), 0,
88 local_mad, mad ) ) != 0 ) {
89 DBGC ( ibdev, "IBDEV %s could not get node info: %s\n",
90 ibdev->name, strerror ( rc ) );
91 return rc;
92 }
93 return 0;
94}
95
96/**
97 * Get port information
98 *
99 * @v ibdev Infiniband device
100 * @v local_mad Method for issuing local MADs
101 * @v mad Management datagram to fill in
102 * @ret rc Return status code
103 */
104static int ib_smc_get_port_info ( struct ib_device *ibdev,
105 ib_local_mad_t local_mad,
106 union ib_mad *mad ) {
107 int rc;
108
109 /* Issue MAD */
110 if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PORT_INFO ),
111 htonl ( ibdev->port ), local_mad, mad )) !=0){
112 DBGC ( ibdev, "IBDEV %s could not get port info: %s\n",
113 ibdev->name, strerror ( rc ) );
114 return rc;
115 }
116 return 0;
117}
118
119/**
120 * Get GUID information
121 *
122 * @v ibdev Infiniband device
123 * @v local_mad Method for issuing local MADs
124 * @v mad Management datagram to fill in
125 * @ret rc Return status code
126 */
127static int ib_smc_get_guid_info ( struct ib_device *ibdev,
128 ib_local_mad_t local_mad,
129 union ib_mad *mad ) {
130 int rc;
131
132 /* Issue MAD */
133 if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_GUID_INFO ), 0,
134 local_mad, mad ) ) != 0 ) {
135 DBGC ( ibdev, "IBDEV %s could not get GUID info: %s\n",
136 ibdev->name, strerror ( rc ) );
137 return rc;
138 }
139 return 0;
140}
141
142/**
143 * Get partition key table
144 *
145 * @v ibdev Infiniband device
146 * @v local_mad Method for issuing local MADs
147 * @v mad Management datagram to fill in
148 * @ret rc Return status code
149 */
150static int ib_smc_get_pkey_table ( struct ib_device *ibdev,
151 ib_local_mad_t local_mad,
152 union ib_mad *mad ) {
153 int rc;
154
155 /* Issue MAD */
156 if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PKEY_TABLE ), 0,
157 local_mad, mad ) ) != 0 ) {
158 DBGC ( ibdev, "IBDEV %s could not get pkey table: %s\n",
159 ibdev->name, strerror ( rc ) );
160 return rc;
161 }
162 return 0;
163}
164
165/**
166 * Get Infiniband parameters using SMC
167 *
168 * @v ibdev Infiniband device
169 * @v local_mad Method for issuing local MADs
170 * @ret rc Return status code
171 */
172static int ib_smc_get ( struct ib_device *ibdev, ib_local_mad_t local_mad ) {
173 union ib_mad mad;
174 struct ib_node_info *node_info = &mad.smp.smp_data.node_info;
175 struct ib_port_info *port_info = &mad.smp.smp_data.port_info;
176 struct ib_guid_info *guid_info = &mad.smp.smp_data.guid_info;
177 struct ib_pkey_table *pkey_table = &mad.smp.smp_data.pkey_table;
178 int rc;
179
180 /* Node info gives us the node GUID */
181 if ( ( rc = ib_smc_get_node_info ( ibdev, local_mad, &mad ) ) != 0 )
182 return rc;
183 memcpy ( &ibdev->node_guid, &node_info->node_guid,
184 sizeof ( ibdev->node_guid ) );
185
186 /* Port info gives us the link state, the first half of the
187 * port GID and the SM LID.
188 */
189 if ( ( rc = ib_smc_get_port_info ( ibdev, local_mad, &mad ) ) != 0 )
190 return rc;
191 memcpy ( &ibdev->gid.s.prefix, port_info->gid_prefix,
192 sizeof ( ibdev->gid.s.prefix ) );
193 ibdev->lid = ntohs ( port_info->lid );
194 ibdev->sm_lid = ntohs ( port_info->mastersm_lid );
195 ibdev->link_width_enabled = port_info->link_width_enabled;
196 ibdev->link_width_supported = port_info->link_width_supported;
197 ibdev->link_width_active = port_info->link_width_active;
198 ibdev->link_speed_supported =
199 ( port_info->link_speed_supported__port_state >> 4 );
200 ibdev->port_state =
201 ( port_info->link_speed_supported__port_state & 0xf );
202 ibdev->link_speed_active =
203 ( port_info->link_speed_active__link_speed_enabled >> 4 );
204 ibdev->link_speed_enabled =
205 ( port_info->link_speed_active__link_speed_enabled & 0xf );
206 ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf );
207
208 /* GUID info gives us the second half of the port GID */
209 if ( ( rc = ib_smc_get_guid_info ( ibdev, local_mad, &mad ) ) != 0 )
210 return rc;
211 memcpy ( &ibdev->gid.s.guid, guid_info->guid[0],
212 sizeof ( ibdev->gid.s.guid ) );
213
214 /* Get partition key */
215 if ( ( rc = ib_smc_get_pkey_table ( ibdev, local_mad, &mad ) ) != 0 )
216 return rc;
217 ibdev->pkey = ntohs ( pkey_table->pkey[0] );
218
219 DBGC ( ibdev, "IBDEV %s port GID is " IB_GID_FMT "\n",
220 ibdev->name, IB_GID_ARGS ( &ibdev->gid ) );
221
222 return 0;
223}
224
225/**
226 * Initialise Infiniband parameters using SMC
227 *
228 * @v ibdev Infiniband device
229 * @v local_mad Method for issuing local MADs
230 * @ret rc Return status code
231 */
232int ib_smc_init ( struct ib_device *ibdev, ib_local_mad_t local_mad ) {
233 int rc;
234
235 /* Get MAD parameters */
236 if ( ( rc = ib_smc_get ( ibdev, local_mad ) ) != 0 )
237 return rc;
238
239 return 0;
240}
241
242/**
243 * Update Infiniband parameters using SMC
244 *
245 * @v ibdev Infiniband device
246 * @v local_mad Method for issuing local MADs
247 * @ret rc Return status code
248 */
249int ib_smc_update ( struct ib_device *ibdev, ib_local_mad_t local_mad ) {
250 int rc;
251
252 /* Get MAD parameters */
253 if ( ( rc = ib_smc_get ( ibdev, local_mad ) ) != 0 )
254 return rc;
255
256 /* Notify Infiniband core of potential link state change */
257 ib_link_state_changed ( ibdev );
258
259 return 0;
260}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
union ib_mad mad
Definition arbel.h:1
unsigned short uint16_t
Definition stdint.h:11
unsigned int uint32_t
Definition stdint.h:12
Error codes.
#define DBGC(...)
Definition compiler.h:505
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
uint16_t attr_id
Definition ib_mad.h:7
#define IB_SMP_ATTR_NODE_INFO
Definition ib_mad.h:46
struct ib_pkey_table pkey_table
Definition ib_mad.h:4
uint32_t attr_mod
Definition ib_mad.h:9
#define IB_MGMT_CLASS_SUBN_LID_ROUTED
Definition ib_mad.h:556
#define IB_MGMT_BASE_VERSION
Definition ib_mad.h:553
struct ib_guid_info guid_info
Definition ib_mad.h:2
#define IB_MGMT_METHOD_GET
Definition ib_mad.h:570
struct ib_port_info port_info
Definition ib_mad.h:3
#define IB_SMP_ATTR_GUID_INFO
Definition ib_mad.h:48
#define IB_SMP_ATTR_PORT_INFO
Definition ib_mad.h:49
struct ib_node_info node_info
Definition ib_mad.h:1
#define IB_SMP_ATTR_PKEY_TABLE
Definition ib_mad.h:50
#define IB_GID_ARGS(gid)
Infiniband Global Identifier debug message arguments.
Definition ib_packet.h:49
#define IB_GID_FMT
Infiniband Global Identifier debug message format.
Definition ib_packet.h:46
static int ib_smc_get_pkey_table(struct ib_device *ibdev, ib_local_mad_t local_mad, union ib_mad *mad)
Get partition key table.
Definition ib_smc.c:150
static int ib_smc_get_port_info(struct ib_device *ibdev, ib_local_mad_t local_mad, union ib_mad *mad)
Get port information.
Definition ib_smc.c:104
static int ib_smc_get_guid_info(struct ib_device *ibdev, ib_local_mad_t local_mad, union ib_mad *mad)
Get GUID information.
Definition ib_smc.c:127
static int ib_smc_mad(struct ib_device *ibdev, uint16_t attr_id, uint32_t attr_mod, ib_local_mad_t local_mad, union ib_mad *mad)
Issue local MAD.
Definition ib_smc.c:52
int ib_smc_init(struct ib_device *ibdev, ib_local_mad_t local_mad)
Initialise Infiniband parameters using SMC.
Definition ib_smc.c:232
int ib_smc_update(struct ib_device *ibdev, ib_local_mad_t local_mad)
Update Infiniband parameters using SMC.
Definition ib_smc.c:249
static int ib_smc_get(struct ib_device *ibdev, ib_local_mad_t local_mad)
Get Infiniband parameters using SMC.
Definition ib_smc.c:172
static int ib_smc_get_node_info(struct ib_device *ibdev, ib_local_mad_t local_mad, union ib_mad *mad)
Get node information.
Definition ib_smc.c:81
Infiniband Subnet Management Client.
int(* ib_local_mad_t)(struct ib_device *ibdev, union ib_mad *mad)
Definition ib_smc.h:14
#define htonl(value)
Definition byteswap.h:134
#define htons(value)
Definition byteswap.h:136
#define ntohs(value)
Definition byteswap.h:137
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void ib_link_state_changed(struct ib_device *ibdev)
Notify of Infiniband link state change.
Definition infiniband.c:637
Infiniband protocol.
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An Infiniband device.
Definition infiniband.h:399
uint8_t sm_sl
Subnet manager SL.
Definition infiniband.h:448
uint8_t link_width_enabled
Link width enabled.
Definition infiniband.h:430
char name[IBDEV_NAME_LEN]
Name of this Infiniband device.
Definition infiniband.h:409
uint8_t link_speed_active
Link speed active.
Definition infiniband.h:438
uint8_t link_speed_supported
Link speed supported.
Definition infiniband.h:434
uint16_t sm_lid
Subnet manager LID.
Definition infiniband.h:446
union ib_guid node_guid
Node GUID.
Definition infiniband.h:440
uint16_t pkey
Partition key.
Definition infiniband.h:450
uint8_t link_width_active
Link width active.
Definition infiniband.h:432
uint8_t link_speed_enabled
Link speed enabled.
Definition infiniband.h:436
uint8_t link_width_supported
Link width supported.
Definition infiniband.h:428
uint16_t lid
Port LID.
Definition infiniband.h:444
uint8_t port_state
Port state.
Definition infiniband.h:426
union ib_gid gid
Port GID (comprising GID prefix and port GUID)
Definition infiniband.h:442
unsigned int port
Port number.
Definition infiniband.h:419
A GUID Information attribute.
Definition ib_mad.h:97
A Node Information attribute.
Definition ib_mad.h:74
A Partition Key Table attribute.
Definition ib_mad.h:176
A Port Information attribute.
Definition ib_mad.h:105
struct ib_gid::@251011351113275240012301235177256303262052134237 s
union ib_guid prefix
Definition ib_packet.h:40
union ib_guid guid
Definition ib_packet.h:41
A management datagram.
Definition ib_mad.h:611