|
@@ -1206,21 +1206,69 @@ static int arbel_get_guid_info ( struct arbel *arbel,
|
1206
|
1206
|
return 0;
|
1207
|
1207
|
}
|
1208
|
1208
|
|
1209
|
|
-static int arbel_get_port_gid ( struct arbel *arbel, struct ib_gid *gid ) {
|
1210
|
|
- struct ib_mad_port_info port_info;
|
1211
|
|
- struct ib_mad_guid_info guid_info;
|
|
1209
|
+static int arbel_get_pkey_table ( struct arbel *arbel,
|
|
1210
|
+ struct ib_mad_pkey_table *pkey_table ) {
|
|
1211
|
+ union arbelprm_mad mad;
|
|
1212
|
+ struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
|
|
1213
|
+ int rc;
|
|
1214
|
+
|
|
1215
|
+ memset ( &mad, 0, sizeof ( mad ) );
|
|
1216
|
+ hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
|
|
1217
|
+ hdr->class_version = 1;
|
|
1218
|
+ hdr->method = IB_MGMT_METHOD_GET;
|
|
1219
|
+ hdr->attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE );
|
|
1220
|
+ if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
|
|
1221
|
+ DBGC ( arbel, "Arbel %p could not get pkey table: %s\n",
|
|
1222
|
+ arbel, strerror ( rc ) );
|
|
1223
|
+ return rc;
|
|
1224
|
+ }
|
|
1225
|
+ memcpy ( pkey_table, &mad.mad.pkey_table, sizeof ( *pkey_table ) );
|
|
1226
|
+ return 0;
|
|
1227
|
+}
|
|
1228
|
+
|
|
1229
|
+static int arbel_get_port_gid ( struct arbel *arbel,
|
|
1230
|
+ struct ib_gid *port_gid ) {
|
|
1231
|
+ union {
|
|
1232
|
+ /* This union exists just to save stack space */
|
|
1233
|
+ struct ib_mad_port_info port_info;
|
|
1234
|
+ struct ib_mad_guid_info guid_info;
|
|
1235
|
+ } u;
|
1212
|
1236
|
int rc;
|
1213
|
1237
|
|
1214
|
|
- if ( ( rc = arbel_get_port_info ( arbel, &port_info ) ) != 0 )
|
|
1238
|
+ /* Port info gives us the first half of the port GID */
|
|
1239
|
+ if ( ( rc = arbel_get_port_info ( arbel, &u.port_info ) ) != 0 )
|
1215
|
1240
|
return rc;
|
1216
|
|
- if ( ( rc = arbel_get_guid_info ( arbel, &guid_info ) ) != 0 )
|
|
1241
|
+ memcpy ( &port_gid->bytes[0], u.port_info.gid_prefix, 8 );
|
|
1242
|
+
|
|
1243
|
+ /* GUID info gives us the second half of the port GID */
|
|
1244
|
+ if ( ( rc = arbel_get_guid_info ( arbel, &u.guid_info ) ) != 0 )
|
1217
|
1245
|
return rc;
|
1218
|
|
- memcpy ( &gid->bytes[0], port_info.gid_prefix, 8 );
|
1219
|
|
- memcpy ( &gid->bytes[8], guid_info.gid_local, 8 );
|
|
1246
|
+ memcpy ( &port_gid->bytes[8], u.guid_info.gid_local, 8 );
|
|
1247
|
+
|
1220
|
1248
|
return 0;
|
1221
|
1249
|
}
|
1222
|
1250
|
|
|
1251
|
+static int arbel_get_broadcast_gid ( struct arbel *arbel,
|
|
1252
|
+ struct ib_gid *broadcast_gid ) {
|
|
1253
|
+ static const struct ib_gid ipv4_broadcast_gid = {
|
|
1254
|
+ { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
|
|
1255
|
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }
|
|
1256
|
+ };
|
|
1257
|
+ struct ib_mad_pkey_table pkey_table;
|
|
1258
|
+ int rc;
|
|
1259
|
+
|
|
1260
|
+ /* Start with the IPv4 broadcast GID */
|
|
1261
|
+ memcpy ( broadcast_gid, &ipv4_broadcast_gid,
|
|
1262
|
+ sizeof ( *broadcast_gid ) );
|
1223
|
1263
|
|
|
1264
|
+ /* Add partition key */
|
|
1265
|
+ if ( ( rc = arbel_get_pkey_table ( arbel, &pkey_table ) ) != 0 )
|
|
1266
|
+ return rc;
|
|
1267
|
+ memcpy ( &broadcast_gid->bytes[4], &pkey_table.pkey[0][0],
|
|
1268
|
+ sizeof ( pkey_table.pkey[0][0] ) );
|
|
1269
|
+
|
|
1270
|
+ return 0;
|
|
1271
|
+}
|
1224
|
1272
|
|
1225
|
1273
|
/**
|
1226
|
1274
|
* Probe PCI device
|
|
@@ -1282,6 +1330,14 @@ static int arbel_probe ( struct pci_device *pci,
|
1282
|
1330
|
goto err_get_port_gid;
|
1283
|
1331
|
}
|
1284
|
1332
|
|
|
1333
|
+ /* Get broadcast GID */
|
|
1334
|
+ if ( ( rc = arbel_get_broadcast_gid ( arbel,
|
|
1335
|
+ &ibdev->broadcast_gid ) ) != 0 ){
|
|
1336
|
+ DBGC ( arbel, "Arbel %p could not determine broadcast GID: "
|
|
1337
|
+ "%s\n", arbel, strerror ( rc ) );
|
|
1338
|
+ goto err_get_broadcast_gid;
|
|
1339
|
+ }
|
|
1340
|
+
|
1285
|
1341
|
struct ud_av_st *bcast_av = ib_data.bcast_av;
|
1286
|
1342
|
struct arbelprm_ud_address_vector *bav =
|
1287
|
1343
|
( struct arbelprm_ud_address_vector * ) &bcast_av->av;
|
|
@@ -1294,8 +1350,6 @@ static int arbel_probe ( struct pci_device *pci,
|
1294
|
1350
|
av->gid_present = 1;
|
1295
|
1351
|
memcpy ( &av->gid, ( ( void * ) bav ) + 16, 16 );
|
1296
|
1352
|
|
1297
|
|
- memcpy ( &ibdev->broadcast_gid, &ib_data.bcast_gid, 16 );
|
1298
|
|
-
|
1299
|
1353
|
/* Add IPoIB device */
|
1300
|
1354
|
if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
|
1301
|
1355
|
DBGC ( arbel, "Arbel %p could not add IPoIB device: %s\n",
|
|
@@ -1306,6 +1360,7 @@ static int arbel_probe ( struct pci_device *pci,
|
1306
|
1360
|
return 0;
|
1307
|
1361
|
|
1308
|
1362
|
err_ipoib_probe:
|
|
1363
|
+ err_get_broadcast_gid:
|
1309
|
1364
|
err_get_port_gid:
|
1310
|
1365
|
err_query_dev_lim:
|
1311
|
1366
|
ib_driver_close ( 0 );
|