|
@@ -662,7 +662,7 @@ static int arbel_create_cq ( struct ib_device *ibdev,
|
662
|
662
|
log_cq_size, fls ( cq->num_cqes - 1 ) );
|
663
|
663
|
MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eq.eqn );
|
664
|
664
|
MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
|
665
|
|
- MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
|
|
665
|
+ MLX_FILL_1 ( &cqctx, 7, l_key, arbel->lkey );
|
666
|
666
|
MLX_FILL_1 ( &cqctx, 12, cqn, cq->cqn );
|
667
|
667
|
MLX_FILL_1 ( &cqctx, 13,
|
668
|
668
|
cq_ci_db_record, arbel_cq->ci_doorbell_idx );
|
|
@@ -799,6 +799,24 @@ static void arbel_free_qpn ( struct ib_device *ibdev,
|
799
|
799
|
arbel_bitmask_free ( arbel->qp_inuse, qpn_offset );
|
800
|
800
|
}
|
801
|
801
|
|
|
802
|
+/**
|
|
803
|
+ * Calculate transmission rate
|
|
804
|
+ *
|
|
805
|
+ * @v av Address vector
|
|
806
|
+ * @ret arbel_rate Arbel rate
|
|
807
|
+ */
|
|
808
|
+static unsigned int arbel_rate ( struct ib_address_vector *av ) {
|
|
809
|
+ return ( ( ( av->rate >= IB_RATE_2_5 ) && ( av->rate <= IB_RATE_120 ) )
|
|
810
|
+ ? ( av->rate + 5 ) : 0 );
|
|
811
|
+}
|
|
812
|
+
|
|
813
|
+/** Queue pair transport service type map */
|
|
814
|
+static uint8_t arbel_qp_st[] = {
|
|
815
|
+ [IB_QPT_SMI] = ARBEL_ST_MLX,
|
|
816
|
+ [IB_QPT_GSI] = ARBEL_ST_MLX,
|
|
817
|
+ [IB_QPT_UD] = ARBEL_ST_UD,
|
|
818
|
+};
|
|
819
|
+
|
802
|
820
|
/**
|
803
|
821
|
* Dump queue pair context (for debugging only)
|
804
|
822
|
*
|
|
@@ -832,8 +850,8 @@ arbel_dump_qpctx ( struct arbel *arbel, struct ib_queue_pair *qp ) {
|
832
|
850
|
*/
|
833
|
851
|
static int arbel_create_send_wq ( struct arbel_send_work_queue *arbel_send_wq,
|
834
|
852
|
unsigned int num_wqes ) {
|
835
|
|
- struct arbelprm_ud_send_wqe *wqe;
|
836
|
|
- struct arbelprm_ud_send_wqe *next_wqe;
|
|
853
|
+ union arbel_send_wqe *wqe;
|
|
854
|
+ union arbel_send_wqe *next_wqe;
|
837
|
855
|
unsigned int wqe_idx_mask;
|
838
|
856
|
unsigned int i;
|
839
|
857
|
|
|
@@ -849,8 +867,8 @@ static int arbel_create_send_wq ( struct arbel_send_work_queue *arbel_send_wq,
|
849
|
867
|
/* Link work queue entries */
|
850
|
868
|
wqe_idx_mask = ( num_wqes - 1 );
|
851
|
869
|
for ( i = 0 ; i < num_wqes ; i++ ) {
|
852
|
|
- wqe = &arbel_send_wq->wqe[i].ud;
|
853
|
|
- next_wqe = &arbel_send_wq->wqe[ ( i + 1 ) & wqe_idx_mask ].ud;
|
|
870
|
+ wqe = &arbel_send_wq->wqe[i];
|
|
871
|
+ next_wqe = &arbel_send_wq->wqe[ ( i + 1 ) & wqe_idx_mask ];
|
854
|
872
|
MLX_FILL_1 ( &wqe->next, 0, nda_31_6,
|
855
|
873
|
( virt_to_bus ( next_wqe ) >> 6 ) );
|
856
|
874
|
MLX_FILL_1 ( &wqe->next, 1, always1, 1 );
|
|
@@ -957,10 +975,8 @@ static int arbel_create_qp ( struct ib_device *ibdev,
|
957
|
975
|
memset ( &qpctx, 0, sizeof ( qpctx ) );
|
958
|
976
|
MLX_FILL_3 ( &qpctx, 2,
|
959
|
977
|
qpc_eec_data.de, 1,
|
960
|
|
- qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
|
961
|
|
- qpc_eec_data.st,
|
962
|
|
- ( ( qp->type == IB_QPT_UD ) ?
|
963
|
|
- ARBEL_ST_UD : ARBEL_ST_MLX ) );
|
|
978
|
+ qpc_eec_data.pm_state, ARBEL_PM_STATE_MIGRATED,
|
|
979
|
+ qpc_eec_data.st, arbel_qp_st[qp->type] );
|
964
|
980
|
MLX_FILL_4 ( &qpctx, 4,
|
965
|
981
|
qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
|
966
|
982
|
qpc_eec_data.log_rq_stride,
|
|
@@ -973,7 +989,7 @@ static int arbel_create_qp ( struct ib_device *ibdev,
|
973
|
989
|
MLX_FILL_1 ( &qpctx, 10, qpc_eec_data.primary_address_path.port_number,
|
974
|
990
|
ibdev->port );
|
975
|
991
|
MLX_FILL_1 ( &qpctx, 27, qpc_eec_data.pd, ARBEL_GLOBAL_PD );
|
976
|
|
- MLX_FILL_1 ( &qpctx, 29, qpc_eec_data.wqe_lkey, arbel->reserved_lkey );
|
|
992
|
+ MLX_FILL_1 ( &qpctx, 29, qpc_eec_data.wqe_lkey, arbel->lkey );
|
977
|
993
|
MLX_FILL_1 ( &qpctx, 30, qpc_eec_data.ssc, 1 );
|
978
|
994
|
MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
|
979
|
995
|
MLX_FILL_1 ( &qpctx, 34, qpc_eec_data.snd_wqe_base_adr_l,
|
|
@@ -1137,7 +1153,7 @@ static void arbel_ring_doorbell ( struct arbel *arbel,
|
1137
|
1153
|
unsigned int offset ) {
|
1138
|
1154
|
|
1139
|
1155
|
DBGC2 ( arbel, "Arbel %p ringing doorbell %08x:%08x at %lx\n",
|
1140
|
|
- arbel, db_reg->dword[0], db_reg->dword[1],
|
|
1156
|
+ arbel, ntohl ( db_reg->dword[0] ), ntohl ( db_reg->dword[1] ),
|
1141
|
1157
|
virt_to_phys ( arbel->uar + offset ) );
|
1142
|
1158
|
|
1143
|
1159
|
barrier();
|
|
@@ -1178,8 +1194,7 @@ static size_t arbel_fill_ud_send_wqe ( struct ib_device *ibdev,
|
1178
|
1194
|
ud_address_vector.rlid, av->lid,
|
1179
|
1195
|
ud_address_vector.g, av->gid_present );
|
1180
|
1196
|
MLX_FILL_2 ( &wqe->ud.ud, 2,
|
1181
|
|
- ud_address_vector.max_stat_rate,
|
1182
|
|
- ( ( av->rate >= 3 ) ? 0 : 1 ),
|
|
1197
|
+ ud_address_vector.max_stat_rate, arbel_rate ( av ),
|
1183
|
1198
|
ud_address_vector.msg, 3 );
|
1184
|
1199
|
MLX_FILL_1 ( &wqe->ud.ud, 3, ud_address_vector.sl, av->sl );
|
1185
|
1200
|
gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
|
|
@@ -1187,7 +1202,7 @@ static size_t arbel_fill_ud_send_wqe ( struct ib_device *ibdev,
|
1187
|
1202
|
MLX_FILL_1 ( &wqe->ud.ud, 8, destination_qp, av->qpn );
|
1188
|
1203
|
MLX_FILL_1 ( &wqe->ud.ud, 9, q_key, av->qkey );
|
1189
|
1204
|
MLX_FILL_1 ( &wqe->ud.data[0], 0, byte_count, iob_len ( iobuf ) );
|
1190
|
|
- MLX_FILL_1 ( &wqe->ud.data[0], 1, l_key, arbel->reserved_lkey );
|
|
1205
|
+ MLX_FILL_1 ( &wqe->ud.data[0], 1, l_key, arbel->lkey );
|
1191
|
1206
|
MLX_FILL_1 ( &wqe->ud.data[0], 3,
|
1192
|
1207
|
local_address_l, virt_to_bus ( iobuf->data ) );
|
1193
|
1208
|
|
|
@@ -1223,19 +1238,18 @@ static size_t arbel_fill_mlx_send_wqe ( struct ib_device *ibdev,
|
1223
|
1238
|
MLX_FILL_5 ( &wqe->mlx.ctrl, 0,
|
1224
|
1239
|
c, 1 /* generate completion */,
|
1225
|
1240
|
icrc, 0 /* generate ICRC */,
|
1226
|
|
- max_statrate, ( ( ( av->rate < 2 ) || ( av->rate > 10 ) )
|
1227
|
|
- ? 8 : ( av->rate + 5 ) ),
|
|
1241
|
+ max_statrate, arbel_rate ( av ),
|
1228
|
1242
|
slr, 0,
|
1229
|
1243
|
v15, ( ( qp->ext_qpn == IB_QPN_SMI ) ? 1 : 0 ) );
|
1230
|
1244
|
MLX_FILL_1 ( &wqe->mlx.ctrl, 1, rlid, av->lid );
|
1231
|
1245
|
MLX_FILL_1 ( &wqe->mlx.data[0], 0,
|
1232
|
1246
|
byte_count, iob_len ( &headers ) );
|
1233
|
|
- MLX_FILL_1 ( &wqe->mlx.data[0], 1, l_key, arbel->reserved_lkey );
|
|
1247
|
+ MLX_FILL_1 ( &wqe->mlx.data[0], 1, l_key, arbel->lkey );
|
1234
|
1248
|
MLX_FILL_1 ( &wqe->mlx.data[0], 3,
|
1235
|
1249
|
local_address_l, virt_to_bus ( headers.data ) );
|
1236
|
1250
|
MLX_FILL_1 ( &wqe->mlx.data[1], 0,
|
1237
|
1251
|
byte_count, ( iob_len ( iobuf ) + 4 /* ICRC */ ) );
|
1238
|
|
- MLX_FILL_1 ( &wqe->mlx.data[1], 1, l_key, arbel->reserved_lkey );
|
|
1252
|
+ MLX_FILL_1 ( &wqe->mlx.data[1], 1, l_key, arbel->lkey );
|
1239
|
1253
|
MLX_FILL_1 ( &wqe->mlx.data[1], 3,
|
1240
|
1254
|
local_address_l, virt_to_bus ( iobuf->data ) );
|
1241
|
1255
|
|
|
@@ -1316,7 +1330,7 @@ static int arbel_post_send ( struct ib_device *ibdev,
|
1316
|
1330
|
/* Ring doorbell register */
|
1317
|
1331
|
MLX_FILL_4 ( &db_reg.send, 0,
|
1318
|
1332
|
nopcode, ARBEL_OPCODE_SEND,
|
1319
|
|
- f, 1,
|
|
1333
|
+ f, 0,
|
1320
|
1334
|
wqe_counter, ( wq->next_idx & 0xffff ),
|
1321
|
1335
|
wqe_cnt, 1 );
|
1322
|
1336
|
MLX_FILL_2 ( &db_reg.send, 1,
|
|
@@ -1361,7 +1375,7 @@ static int arbel_post_recv ( struct ib_device *ibdev,
|
1361
|
1375
|
|
1362
|
1376
|
/* Construct work queue entry */
|
1363
|
1377
|
MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
|
1364
|
|
- MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
|
|
1378
|
+ MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->lkey );
|
1365
|
1379
|
MLX_FILL_1 ( &wqe->data[0], 3,
|
1366
|
1380
|
local_address_l, virt_to_bus ( iobuf->data ) );
|
1367
|
1381
|
|
|
@@ -1396,8 +1410,9 @@ static int arbel_complete ( struct ib_device *ibdev,
|
1396
|
1410
|
struct arbel_recv_work_queue *arbel_recv_wq;
|
1397
|
1411
|
struct arbelprm_recv_wqe *recv_wqe;
|
1398
|
1412
|
struct io_buffer *iobuf;
|
1399
|
|
- struct ib_address_vector av;
|
|
1413
|
+ struct ib_address_vector recv_av;
|
1400
|
1414
|
struct ib_global_route_header *grh;
|
|
1415
|
+ struct ib_address_vector *av;
|
1401
|
1416
|
unsigned int opcode;
|
1402
|
1417
|
unsigned long qpn;
|
1403
|
1418
|
int is_send;
|
|
@@ -1414,9 +1429,12 @@ static int arbel_complete ( struct ib_device *ibdev,
|
1414
|
1429
|
if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
|
1415
|
1430
|
/* "s" field is not valid for error opcodes */
|
1416
|
1431
|
is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR );
|
1417
|
|
- DBGC ( arbel, "Arbel %p CQN %#lx syndrome %x vendor %x\n",
|
1418
|
|
- arbel, cq->cqn, MLX_GET ( &cqe->error, syndrome ),
|
|
1432
|
+ DBGC ( arbel, "Arbel %p CQN %#lx %s QPN %#lx syndrome %#x "
|
|
1433
|
+ "vendor %#x\n", arbel, cq->cqn,
|
|
1434
|
+ ( is_send ? "send" : "recv" ), qpn,
|
|
1435
|
+ MLX_GET ( &cqe->error, syndrome ),
|
1419
|
1436
|
MLX_GET ( &cqe->error, vendor_code ) );
|
|
1437
|
+ DBGC_HDA ( arbel, virt_to_phys ( cqe ), cqe, sizeof ( *cqe ) );
|
1420
|
1438
|
rc = -EIO;
|
1421
|
1439
|
/* Don't return immediately; propagate error to completer */
|
1422
|
1440
|
}
|
|
@@ -1474,18 +1492,28 @@ static int arbel_complete ( struct ib_device *ibdev,
|
1474
|
1492
|
l_key, ARBEL_INVALID_LKEY );
|
1475
|
1493
|
assert ( len <= iob_tailroom ( iobuf ) );
|
1476
|
1494
|
iob_put ( iobuf, len );
|
1477
|
|
- assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
|
1478
|
|
- grh = iobuf->data;
|
1479
|
|
- iob_pull ( iobuf, sizeof ( *grh ) );
|
1480
|
|
- /* Construct address vector */
|
1481
|
|
- memset ( &av, 0, sizeof ( av ) );
|
1482
|
|
- av.qpn = MLX_GET ( &cqe->normal, rqpn );
|
1483
|
|
- av.lid = MLX_GET ( &cqe->normal, rlid );
|
1484
|
|
- av.sl = MLX_GET ( &cqe->normal, sl );
|
1485
|
|
- av.gid_present = MLX_GET ( &cqe->normal, g );
|
1486
|
|
- memcpy ( &av.gid, &grh->sgid, sizeof ( av.gid ) );
|
|
1495
|
+ switch ( qp->type ) {
|
|
1496
|
+ case IB_QPT_SMI:
|
|
1497
|
+ case IB_QPT_GSI:
|
|
1498
|
+ case IB_QPT_UD:
|
|
1499
|
+ assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
|
|
1500
|
+ grh = iobuf->data;
|
|
1501
|
+ iob_pull ( iobuf, sizeof ( *grh ) );
|
|
1502
|
+ /* Construct address vector */
|
|
1503
|
+ av = &recv_av;
|
|
1504
|
+ memset ( av, 0, sizeof ( *av ) );
|
|
1505
|
+ av->qpn = MLX_GET ( &cqe->normal, rqpn );
|
|
1506
|
+ av->lid = MLX_GET ( &cqe->normal, rlid );
|
|
1507
|
+ av->sl = MLX_GET ( &cqe->normal, sl );
|
|
1508
|
+ av->gid_present = MLX_GET ( &cqe->normal, g );
|
|
1509
|
+ memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) );
|
|
1510
|
+ break;
|
|
1511
|
+ default:
|
|
1512
|
+ assert ( 0 );
|
|
1513
|
+ return -EINVAL;
|
|
1514
|
+ }
|
1487
|
1515
|
/* Hand off to completion handler */
|
1488
|
|
- ib_complete_recv ( ibdev, qp, &av, iobuf, rc );
|
|
1516
|
+ ib_complete_recv ( ibdev, qp, av, iobuf, rc );
|
1489
|
1517
|
}
|
1490
|
1518
|
|
1491
|
1519
|
return rc;
|
|
@@ -1583,7 +1611,7 @@ static int arbel_create_eq ( struct arbel *arbel ) {
|
1583
|
1611
|
start_address_l, virt_to_phys ( arbel_eq->eqe ) );
|
1584
|
1612
|
MLX_FILL_1 ( &eqctx, 3, log_eq_size, fls ( ARBEL_NUM_EQES - 1 ) );
|
1585
|
1613
|
MLX_FILL_1 ( &eqctx, 6, pd, ARBEL_GLOBAL_PD );
|
1586
|
|
- MLX_FILL_1 ( &eqctx, 7, lkey, arbel->reserved_lkey );
|
|
1614
|
+ MLX_FILL_1 ( &eqctx, 7, lkey, arbel->lkey );
|
1587
|
1615
|
if ( ( rc = arbel_cmd_sw2hw_eq ( arbel, arbel_eq->eqn,
|
1588
|
1616
|
&eqctx ) ) != 0 ) {
|
1589
|
1617
|
DBGC ( arbel, "Arbel %p EQN %#lx SW2HW_EQ failed: %s\n",
|
|
@@ -2429,7 +2457,7 @@ static int arbel_setup_mpt ( struct arbel *arbel ) {
|
2429
|
2457
|
|
2430
|
2458
|
/* Derive key */
|
2431
|
2459
|
key = ( arbel->limits.reserved_mrws | ARBEL_MKEY_PREFIX );
|
2432
|
|
- arbel->reserved_lkey = ( ( key << 8 ) | ( key >> 24 ) );
|
|
2460
|
+ arbel->lkey = ( ( key << 8 ) | ( key >> 24 ) );
|
2433
|
2461
|
|
2434
|
2462
|
/* Initialise memory protection table */
|
2435
|
2463
|
memset ( &mpt, 0, sizeof ( mpt ) );
|