Procházet zdrojové kódy

[hermon] Add support for RC queue pairs

tags/v0.9.8
Michael Brown před 15 roky
rodič
revize
bb2cf3c8d7

+ 190
- 68
src/drivers/infiniband/hermon.c Zobrazit soubor

@@ -201,9 +201,10 @@ static int hermon_cmd ( struct hermon *hermon, unsigned long command,
201 201
 		     opcode_modifier, op_mod,
202 202
 		     go, 1,
203 203
 		     t, hermon->toggle );
204
-	DBGC ( hermon, "Hermon %p issuing command:\n", hermon );
205
-	DBGC_HDA ( hermon, virt_to_phys ( hermon->config + HERMON_HCR_BASE ),
206
-		   &hcr, sizeof ( hcr ) );
204
+	DBGC ( hermon, "Hermon %p issuing command %04x\n",
205
+	       hermon, opcode );
206
+	DBGC2_HDA ( hermon, virt_to_phys ( hermon->config + HERMON_HCR_BASE ),
207
+		    &hcr, sizeof ( hcr ) );
207 208
 	if ( in_len && ( command & HERMON_HCR_IN_MBOX ) ) {
208 209
 		DBGC2 ( hermon, "Input mailbox:\n" );
209 210
 		DBGC2_HDA ( hermon, virt_to_phys ( in_buffer ), in_buffer,
@@ -417,6 +418,15 @@ hermon_cmd_2rst_qp ( struct hermon *hermon, unsigned long qpn ) {
417 418
 			    0x03, NULL, qpn, NULL );
418 419
 }
419 420
 
421
+static inline int
422
+hermon_cmd_query_qp ( struct hermon *hermon, unsigned long qpn,
423
+		      struct hermonprm_qp_ee_state_transitions *ctx ) {
424
+	return hermon_cmd ( hermon,
425
+			    HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_QP,
426
+						 1, sizeof ( *ctx ) ),
427
+			    0, NULL, qpn, ctx );
428
+}
429
+
420 430
 static inline int
421 431
 hermon_cmd_conf_special_qp ( struct hermon *hermon, unsigned int internal_qps,
422 432
 			     unsigned long base_qpn ) {
@@ -828,6 +838,7 @@ static int hermon_alloc_qpn ( struct ib_device *ibdev,
828 838
 		qp->qpn = ( hermon->special_qpn_base + 2 + port_offset );
829 839
 		return 0;
830 840
 	case IB_QPT_UD:
841
+	case IB_QPT_RC:
831 842
 		/* Find a free queue pair number */
832 843
 		qpn_offset = hermon_bitmask_alloc ( hermon->qp_inuse,
833 844
 						    HERMON_MAX_QPS, 1 );
@@ -861,6 +872,64 @@ static void hermon_free_qpn ( struct ib_device *ibdev,
861 872
 		hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 );
862 873
 }
863 874
 
875
+/**
876
+ * Calculate transmission rate
877
+ *
878
+ * @v av		Address vector
879
+ * @ret hermon_rate	Hermon rate
880
+ */
881
+static unsigned int hermon_rate ( struct ib_address_vector *av ) {
882
+	return ( ( ( av->rate >= IB_RATE_2_5 ) && ( av->rate <= IB_RATE_120 ) )
883
+		 ? ( av->rate + 5 ) : 0 );
884
+}
885
+
886
+/**
887
+ * Calculate schedule queue
888
+ *
889
+ * @v ibdev		Infiniband device
890
+ * @v qp		Queue pair
891
+ * @ret sched_queue	Schedule queue
892
+ */
893
+static unsigned int hermon_sched_queue ( struct ib_device *ibdev,
894
+					 struct ib_queue_pair *qp ) {
895
+	return ( ( ( qp->type == IB_QPT_SMA ) ?
896
+		   HERMON_SCHED_QP0 : HERMON_SCHED_DEFAULT ) |
897
+		 ( ( ibdev->port - 1 ) << 6 ) );
898
+}
899
+
900
+/** Queue pair transport service type map */
901
+static uint8_t hermon_qp_st[] = {
902
+	[IB_QPT_SMA] = HERMON_ST_MLX,
903
+	[IB_QPT_GMA] = HERMON_ST_MLX,
904
+	[IB_QPT_UD] = HERMON_ST_UD,
905
+	[IB_QPT_RC] = HERMON_ST_RC,
906
+};
907
+
908
+/**
909
+ * Dump queue pair context (for debugging only)
910
+ *
911
+ * @v hermon		Hermon device
912
+ * @v qp		Queue pair
913
+ * @ret rc		Return status code
914
+ */
915
+static inline int hermon_dump_qpctx ( struct hermon *hermon,
916
+				      struct ib_queue_pair *qp ) {
917
+	struct hermonprm_qp_ee_state_transitions qpctx;
918
+	int rc;
919
+
920
+	memset ( &qpctx, 0, sizeof ( qpctx ) );
921
+	if ( ( rc = hermon_cmd_query_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ) {
922
+		DBGC ( hermon, "Hermon %p QUERY_QP failed: %s\n",
923
+		       hermon, strerror ( rc ) );
924
+		return rc;
925
+	}
926
+	DBGC ( hermon, "Hermon %p QPN %lx context:\n", hermon, qp->qpn );
927
+	DBGC_HDA ( hermon, 0, &qpctx.u.dwords[2],
928
+		   ( sizeof ( qpctx ) - 8 ) );
929
+
930
+	return 0;
931
+}
932
+
864 933
 /**
865 934
  * Create queue pair
866 935
  *
@@ -923,10 +992,8 @@ static int hermon_create_qp ( struct ib_device *ibdev,
923 992
 	/* Transition queue to INIT state */
924 993
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
925 994
 	MLX_FILL_2 ( &qpctx, 2,
926
-		     qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
927
-		     qpc_eec_data.st,
928
-		     ( ( qp->type == IB_QPT_UD ) ?
929
-		       HERMON_ST_UD : HERMON_ST_MLX ) );
995
+		     qpc_eec_data.pm_state, HERMON_PM_STATE_MIGRATED,
996
+		     qpc_eec_data.st, hermon_qp_st[qp->type] );
930 997
 	MLX_FILL_1 ( &qpctx, 3, qpc_eec_data.pd, HERMON_GLOBAL_PD );
931 998
 	MLX_FILL_4 ( &qpctx, 4,
932 999
 		     qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
@@ -939,7 +1006,11 @@ static int hermon_create_qp ( struct ib_device *ibdev,
939 1006
 	MLX_FILL_1 ( &qpctx, 5,
940 1007
 		     qpc_eec_data.usr_page, HERMON_UAR_NON_EQ_PAGE );
941 1008
 	MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
942
-	MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.page_offset,
1009
+	MLX_FILL_4 ( &qpctx, 38,
1010
+		     qpc_eec_data.rre, 1,
1011
+		     qpc_eec_data.rwe, 1,
1012
+		     qpc_eec_data.rae, 1,
1013
+		     qpc_eec_data.page_offset,
943 1014
 		     ( hermon_qp->mtt.page_offset >> 6 ) );
944 1015
 	MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
945 1016
 	MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.db_record_addr_l,
@@ -953,29 +1024,6 @@ static int hermon_create_qp ( struct ib_device *ibdev,
953 1024
 		goto err_rst2init_qp;
954 1025
 	}
955 1026
 
956
-	/* Transition queue to RTR state */
957
-	memset ( &qpctx, 0, sizeof ( qpctx ) );
958
-	MLX_FILL_2 ( &qpctx, 4,
959
-		     qpc_eec_data.mtu, HERMON_MTU_2048,
960
-		     qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
961
-	MLX_FILL_1 ( &qpctx, 16,
962
-		     qpc_eec_data.primary_address_path.sched_queue,
963
-		     ( ( ( qp->type == IB_QPT_SMA ) ?
964
-			 HERMON_SCHED_QP0 : HERMON_SCHED_DEFAULT ) |
965
-		       ( ( ibdev->port - 1 ) << 6 ) ) );
966
-	if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
967
-					     &qpctx ) ) != 0 ) {
968
-		DBGC ( hermon, "Hermon %p INIT2RTR_QP failed: %s\n",
969
-		       hermon, strerror ( rc ) );
970
-		goto err_init2rtr_qp;
971
-	}
972
-	memset ( &qpctx, 0, sizeof ( qpctx ) );
973
-	if ( ( rc = hermon_cmd_rtr2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){
974
-		DBGC ( hermon, "Hermon %p RTR2RTS_QP failed: %s\n",
975
-		       hermon, strerror ( rc ) );
976
-		goto err_rtr2rts_qp;
977
-	}
978
-
979 1027
 	DBGC ( hermon, "Hermon %p QPN %#lx send ring at [%p,%p)\n",
980 1028
 	       hermon, qp->qpn, hermon_qp->send.wqe,
981 1029
 	       ( ((void *)hermon_qp->send.wqe ) + hermon_qp->send.wqe_size ) );
@@ -985,8 +1033,6 @@ static int hermon_create_qp ( struct ib_device *ibdev,
985 1033
 	ib_qp_set_drvdata ( qp, hermon_qp );
986 1034
 	return 0;
987 1035
 
988
- err_rtr2rts_qp:
989
- err_init2rtr_qp:
990 1036
 	hermon_cmd_2rst_qp ( hermon, qp->qpn );
991 1037
  err_rst2init_qp:
992 1038
 	hermon_free_mtt ( hermon, &hermon_qp->mtt );
@@ -1013,12 +1059,41 @@ static int hermon_modify_qp ( struct ib_device *ibdev,
1013 1059
 	struct hermonprm_qp_ee_state_transitions qpctx;
1014 1060
 	int rc;
1015 1061
 
1016
-	/* Issue RTS2RTS_QP */
1062
+	/* Transition queue to RTR state */
1017 1063
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
1018 1064
 	MLX_FILL_1 ( &qpctx, 0, opt_param_mask, HERMON_QP_OPT_PARAM_QKEY );
1065
+	MLX_FILL_2 ( &qpctx, 4,
1066
+		     qpc_eec_data.mtu, HERMON_MTU_2048,
1067
+		     qpc_eec_data.msg_max, 31 );// 11 /* 2^11 = 2048 */ );
1068
+	MLX_FILL_1 ( &qpctx, 7, qpc_eec_data.remote_qpn_een, qp->av.qpn );
1069
+	MLX_FILL_1 ( &qpctx, 9,
1070
+		     qpc_eec_data.primary_address_path.rlid, qp->av.lid );
1071
+	MLX_FILL_1 ( &qpctx, 10,
1072
+		     qpc_eec_data.primary_address_path.max_stat_rate,
1073
+		     hermon_rate ( &qp->av ) );
1074
+	memcpy ( &qpctx.u.dwords[12], &qp->av.gid, sizeof ( qp->av.gid ) );
1075
+	MLX_FILL_1 ( &qpctx, 16,
1076
+		     qpc_eec_data.primary_address_path.sched_queue,
1077
+		     hermon_sched_queue ( ibdev, qp ) );
1078
+	MLX_FILL_1 ( &qpctx, 39, qpc_eec_data.next_rcv_psn, qp->recv.psn );
1019 1079
 	MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
1020
-	if ( ( rc = hermon_cmd_rts2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){
1021
-		DBGC ( hermon, "Hermon %p RTS2RTS_QP failed: %s\n",
1080
+	if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
1081
+					     &qpctx ) ) != 0 ) {
1082
+		DBGC ( hermon, "Hermon %p INIT2RTR_QP failed: %s\n",
1083
+		       hermon, strerror ( rc ) );
1084
+		return rc;
1085
+	}
1086
+
1087
+	/* Transition queue to RTS state */
1088
+	memset ( &qpctx, 0, sizeof ( qpctx ) );
1089
+	MLX_FILL_1 ( &qpctx, 10,
1090
+		     qpc_eec_data.primary_address_path.ack_timeout, 0x13 );
1091
+	MLX_FILL_2 ( &qpctx, 30,
1092
+		     qpc_eec_data.retry_count, HERMON_RETRY_MAX,
1093
+		     qpc_eec_data.rnr_retry, HERMON_RETRY_MAX );
1094
+	MLX_FILL_1 ( &qpctx, 32, qpc_eec_data.next_send_psn, qp->send.psn );
1095
+	if ( ( rc = hermon_cmd_rtr2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){
1096
+		DBGC ( hermon, "Hermon %p RTR2RTS_QP failed: %s\n",
1022 1097
 		       hermon, strerror ( rc ) );
1023 1098
 		return rc;
1024 1099
 	}
@@ -1094,15 +1169,13 @@ hermon_fill_ud_send_wqe ( struct ib_device *ibdev,
1094 1169
 		     ud_address_vector.rlid, av->lid,
1095 1170
 		     ud_address_vector.g, av->gid_present );
1096 1171
 	MLX_FILL_1 ( &wqe->ud.ud, 2,
1097
-		     ud_address_vector.max_stat_rate,
1098
-		     ( ( ( av->rate < 2 ) || ( av->rate > 10 ) ) ?
1099
-		       8 : ( av->rate + 5 ) ) );
1172
+		     ud_address_vector.max_stat_rate, hermon_rate ( av ) );
1100 1173
 	MLX_FILL_1 ( &wqe->ud.ud, 3, ud_address_vector.sl, av->sl );
1101 1174
 	memcpy ( &wqe->ud.ud.u.dwords[4], &av->gid, sizeof ( av->gid ) );
1102 1175
 	MLX_FILL_1 ( &wqe->ud.ud, 8, destination_qp, av->qpn );
1103 1176
 	MLX_FILL_1 ( &wqe->ud.ud, 9, q_key, av->qkey );
1104 1177
 	MLX_FILL_1 ( &wqe->ud.data[0], 0, byte_count, iob_len ( iobuf ) );
1105
-	MLX_FILL_1 ( &wqe->ud.data[0], 1, l_key, hermon->reserved_lkey );
1178
+	MLX_FILL_1 ( &wqe->ud.data[0], 1, l_key, hermon->lkey );
1106 1179
 	MLX_FILL_1 ( &wqe->ud.data[0], 3,
1107 1180
 		     local_address_l, virt_to_bus ( iobuf->data ) );
1108 1181
 	return HERMON_OPCODE_SEND;
@@ -1139,24 +1212,51 @@ hermon_fill_mlx_send_wqe ( struct ib_device *ibdev,
1139 1212
 	MLX_FILL_5 ( &wqe->mlx.ctrl, 2,
1140 1213
 		     c, 0x03 /* generate completion */,
1141 1214
 		     icrc, 0 /* generate ICRC */,
1142
-		     max_statrate, ( ( ( av->rate < 2 ) || ( av->rate > 10 ) )
1143
-				     ? 8 : ( av->rate + 5 ) ),
1215
+		     max_statrate, hermon_rate ( av ),
1144 1216
 		     slr, 0,
1145 1217
 		     v15, ( ( qp->ext_qpn == IB_QPN_SMA ) ? 1 : 0 ) );
1146 1218
 	MLX_FILL_1 ( &wqe->mlx.ctrl, 3, rlid, av->lid );
1147 1219
 	MLX_FILL_1 ( &wqe->mlx.data[0], 0,
1148 1220
 		     byte_count, iob_len ( &headers ) );
1149
-	MLX_FILL_1 ( &wqe->mlx.data[0], 1, l_key, hermon->reserved_lkey );
1221
+	MLX_FILL_1 ( &wqe->mlx.data[0], 1, l_key, hermon->lkey );
1150 1222
 	MLX_FILL_1 ( &wqe->mlx.data[0], 3,
1151 1223
 		     local_address_l, virt_to_bus ( headers.data ) );
1152 1224
 	MLX_FILL_1 ( &wqe->mlx.data[1], 0,
1153 1225
 		     byte_count, ( iob_len ( iobuf ) + 4 /* ICRC */ ) );
1154
-	MLX_FILL_1 ( &wqe->mlx.data[1], 1, l_key, hermon->reserved_lkey );
1226
+	MLX_FILL_1 ( &wqe->mlx.data[1], 1, l_key, hermon->lkey );
1155 1227
 	MLX_FILL_1 ( &wqe->mlx.data[1], 3,
1156 1228
 		     local_address_l, virt_to_bus ( iobuf->data ) );
1157 1229
 	return HERMON_OPCODE_SEND;
1158 1230
 }
1159 1231
 
1232
+/**
1233
+ * Construct RC send work queue entry
1234
+ *
1235
+ * @v ibdev		Infiniband device
1236
+ * @v qp		Queue pair
1237
+ * @v av		Address vector
1238
+ * @v iobuf		I/O buffer
1239
+ * @v wqe		Send work queue entry
1240
+ * @ret opcode		Control opcode
1241
+ */
1242
+static unsigned int
1243
+hermon_fill_rc_send_wqe ( struct ib_device *ibdev,
1244
+			  struct ib_queue_pair *qp __unused,
1245
+			  struct ib_address_vector *av __unused,
1246
+			  struct io_buffer *iobuf,
1247
+			  union hermon_send_wqe *wqe ) {
1248
+	struct hermon *hermon = ib_get_drvdata ( ibdev );
1249
+
1250
+	MLX_FILL_1 ( &wqe->rc.ctrl, 1, ds,
1251
+		     ( ( offsetof ( typeof ( wqe->rc ), data[1] ) / 16 ) ) );
1252
+	MLX_FILL_1 ( &wqe->rc.ctrl, 2, c, 0x03 /* generate completion */ );
1253
+	MLX_FILL_1 ( &wqe->rc.data[0], 0, byte_count, iob_len ( iobuf ) );
1254
+	MLX_FILL_1 ( &wqe->rc.data[0], 1, l_key, hermon->lkey );
1255
+	MLX_FILL_1 ( &wqe->rc.data[0], 3,
1256
+		     local_address_l, virt_to_bus ( iobuf->data ) );
1257
+	return HERMON_OPCODE_SEND;
1258
+}
1259
+
1160 1260
 /** Work queue entry constructors */
1161 1261
 static unsigned int
1162 1262
 ( * hermon_fill_send_wqe[] ) ( struct ib_device *ibdev,
@@ -1167,6 +1267,7 @@ static unsigned int
1167 1267
 	[IB_QPT_SMA] = hermon_fill_mlx_send_wqe,
1168 1268
 	[IB_QPT_GMA] = hermon_fill_mlx_send_wqe,
1169 1269
 	[IB_QPT_UD] = hermon_fill_ud_send_wqe,
1270
+	[IB_QPT_RC] = hermon_fill_rc_send_wqe,
1170 1271
 };
1171 1272
 
1172 1273
 /**
@@ -1258,7 +1359,7 @@ static int hermon_post_recv ( struct ib_device *ibdev,
1258 1359
 
1259 1360
 	/* Construct work queue entry */
1260 1361
 	MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
1261
-	MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->reserved_lkey );
1362
+	MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->lkey );
1262 1363
 	MLX_FILL_1 ( &wqe->data[0], 3,
1263 1364
 		     local_address_l, virt_to_bus ( iobuf->data ) );
1264 1365
 
@@ -1289,8 +1390,9 @@ static int hermon_complete ( struct ib_device *ibdev,
1289 1390
 	struct ib_queue_pair *qp;
1290 1391
 	struct hermon_queue_pair *hermon_qp;
1291 1392
 	struct io_buffer *iobuf;
1292
-	struct ib_address_vector av;
1393
+	struct ib_address_vector recv_av;
1293 1394
 	struct ib_global_route_header *grh;
1395
+	struct ib_address_vector *av;
1294 1396
 	unsigned int opcode;
1295 1397
 	unsigned long qpn;
1296 1398
 	int is_send;
@@ -1341,18 +1443,31 @@ static int hermon_complete ( struct ib_device *ibdev,
1341 1443
 		len = MLX_GET ( &cqe->normal, byte_cnt );
1342 1444
 		assert ( len <= iob_tailroom ( iobuf ) );
1343 1445
 		iob_put ( iobuf, len );
1344
-		assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
1345
-		grh = iobuf->data;
1346
-		iob_pull ( iobuf, sizeof ( *grh ) );
1347
-		/* Construct address vector */
1348
-		memset ( &av, 0, sizeof ( av ) );
1349
-		av.qpn = MLX_GET ( &cqe->normal, srq_rqpn );
1350
-		av.lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
1351
-		av.sl = MLX_GET ( &cqe->normal, sl );
1352
-		av.gid_present = MLX_GET ( &cqe->normal, g );
1353
-		memcpy ( &av.gid, &grh->sgid, sizeof ( av.gid ) );
1446
+		switch ( qp->type ) {
1447
+		case IB_QPT_SMA:
1448
+		case IB_QPT_GMA:
1449
+		case IB_QPT_UD:
1450
+			assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
1451
+			grh = iobuf->data;
1452
+			iob_pull ( iobuf, sizeof ( *grh ) );
1453
+			/* Construct address vector */
1454
+			av = &recv_av;
1455
+			memset ( av, 0, sizeof ( *av ) );
1456
+			av->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
1457
+			av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
1458
+			av->sl = MLX_GET ( &cqe->normal, sl );
1459
+			av->gid_present = MLX_GET ( &cqe->normal, g );
1460
+			memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) );
1461
+			break;
1462
+		case IB_QPT_RC:
1463
+			av = &qp->av;
1464
+			break;
1465
+		default:
1466
+			assert ( 0 );
1467
+			return -EINVAL;
1468
+		}
1354 1469
 		/* Hand off to completion handler */
1355
-		ib_complete_recv ( ibdev, qp, &av, iobuf, rc );
1470
+		ib_complete_recv ( ibdev, qp, av, iobuf, rc );
1356 1471
 	}
1357 1472
 
1358 1473
 	return rc;
@@ -1669,14 +1784,14 @@ static void hermon_close ( struct ib_device *ibdev ) {
1669 1784
 }
1670 1785
 
1671 1786
 /**
1672
- * Set port information
1787
+ * Inform embedded subnet management agent of a received MAD
1673 1788
  *
1674 1789
  * @v ibdev		Infiniband device
1675
- * @v mad		Set port information MAD
1790
+ * @v mad		MAD
1676 1791
  * @ret rc		Return status code
1677 1792
  */
1678
-static int hermon_set_port_info ( struct ib_device *ibdev,
1679
-				  union ib_mad *mad ) {
1793
+static int hermon_inform_sma ( struct ib_device *ibdev,
1794
+			       union ib_mad *mad ) {
1680 1795
 	int rc;
1681 1796
 
1682 1797
 	/* Send the MAD to the embedded SMA */
@@ -1799,7 +1914,8 @@ static struct ib_device_operations hermon_ib_operations = {
1799 1914
 	.close		= hermon_close,
1800 1915
 	.mcast_attach	= hermon_mcast_attach,
1801 1916
 	.mcast_detach	= hermon_mcast_detach,
1802
-	.set_port_info	= hermon_set_port_info,
1917
+	.set_port_info	= hermon_inform_sma,
1918
+	.set_pkey_table	= hermon_inform_sma,
1803 1919
 };
1804 1920
 
1805 1921
 /***************************************************************************
@@ -2293,17 +2409,21 @@ static int hermon_setup_mpt ( struct hermon *hermon ) {
2293 2409
 
2294 2410
 	/* Derive key */
2295 2411
 	key = ( hermon->cap.reserved_mrws | HERMON_MKEY_PREFIX );
2296
-	hermon->reserved_lkey = ( ( key << 8 ) | ( key >> 24 ) );
2412
+	hermon->lkey = ( ( key << 8 ) | ( key >> 24 ) );
2297 2413
 
2298 2414
 	/* Initialise memory protection table */
2299 2415
 	memset ( &mpt, 0, sizeof ( mpt ) );
2300
-	MLX_FILL_4 ( &mpt, 0,
2301
-		     r_w, 1,
2302
-		     pa, 1,
2416
+	MLX_FILL_7 ( &mpt, 0,
2417
+		     atomic, 1,
2418
+		     rw, 1,
2419
+		     rr, 1,
2420
+		     lw, 1,
2303 2421
 		     lr, 1,
2304
-		     lw, 1 );
2422
+		     pa, 1,
2423
+		     r_w, 1 );
2305 2424
 	MLX_FILL_1 ( &mpt, 2, mem_key, key );
2306
-	MLX_FILL_1 ( &mpt, 3, pd, HERMON_GLOBAL_PD );
2425
+	MLX_FILL_1 ( &mpt, 3,
2426
+		     pd, HERMON_GLOBAL_PD );
2307 2427
 	MLX_FILL_1 ( &mpt, 10, len64, 1 );
2308 2428
 	if ( ( rc = hermon_cmd_sw2hw_mpt ( hermon,
2309 2429
 					   hermon->cap.reserved_mrws,
@@ -2432,6 +2552,8 @@ static int hermon_probe ( struct pci_device *pci,
2432 2552
 	/* Set up memory protection */
2433 2553
 	if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
2434 2554
 		goto err_setup_mpt;
2555
+	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ )
2556
+		hermon->ibdev[i]->rdma_key = hermon->lkey;
2435 2557
 
2436 2558
 	/* Set up event queue */
2437 2559
 	if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )

+ 19
- 2
src/drivers/infiniband/hermon.h Zobrazit soubor

@@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
30 30
 #define HERMON_PCI_UAR_BAR		PCI_BASE_ADDRESS_2
31 31
 
32 32
 /* Work queue entry and completion queue entry opcodes */
33
+#define HERMON_OPCODE_NOP		0x00
33 34
 #define HERMON_OPCODE_SEND		0x0a
34 35
 #define HERMON_OPCODE_RECV_ERROR	0xfe
35 36
 #define HERMON_OPCODE_SEND_ERROR	0xff
@@ -54,6 +55,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
54 55
 #define HERMON_HCR_RTR2RTS_QP		0x001b
55 56
 #define HERMON_HCR_RTS2RTS_QP		0x001c
56 57
 #define HERMON_HCR_2RST_QP		0x0021
58
+#define HERMON_HCR_QUERY_QP		0x0022
57 59
 #define HERMON_HCR_CONF_SPECIAL_QP	0x0023
58 60
 #define HERMON_HCR_MAD_IFC		0x0024
59 61
 #define HERMON_HCR_READ_MCG		0x0025
@@ -71,6 +73,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
71 73
 #define HERMON_HCR_MAP_FA		0x0fff
72 74
 
73 75
 /* Service types */
76
+#define HERMON_ST_RC			0x00
74 77
 #define HERMON_ST_UD			0x03
75 78
 #define HERMON_ST_MLX			0x07
76 79
 
@@ -85,7 +88,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
85 88
 #define HERMON_DB_EQ_OFFSET(_eqn)	\
86 89
 	( 0x800 + HERMON_PAGE_SIZE * ( (_eqn) / 4 ) + 0x08 * ( (_eqn) % 4 ) )
87 90
 
91
+#define HERMON_QP_OPT_PARAM_PM_STATE	0x00000400UL
88 92
 #define HERMON_QP_OPT_PARAM_QKEY	0x00000020UL
93
+#define HERMON_QP_OPT_PARAM_ALT_PATH	0x00000001UL
89 94
 
90 95
 #define HERMON_MAP_EQ			( 0UL << 31 )
91 96
 #define HERMON_UNMAP_EQ			( 1UL << 31 )
@@ -95,6 +100,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
95 100
 #define HERMON_SCHED_QP0		0x3f
96 101
 #define HERMON_SCHED_DEFAULT		0x83
97 102
 
103
+#define HERMON_PM_STATE_ARMED		0x00
104
+#define HERMON_PM_STATE_REARM		0x01
105
+#define HERMON_PM_STATE_MIGRATED	0x03
106
+
107
+#define HERMON_RETRY_MAX		0x07
108
+
98 109
 /*
99 110
  * Datatypes that seem to be missing from the autogenerated documentation
100 111
  *
@@ -214,6 +225,11 @@ struct hermonprm_mlx_send_wqe {
214 225
 	uint8_t headers[IB_MAX_HEADER_SIZE];
215 226
 } __attribute__ (( packed ));
216 227
 
228
+struct hermonprm_rc_send_wqe {
229
+	struct hermonprm_wqe_segment_ctrl_send ctrl;
230
+	struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER];
231
+} __attribute__ (( packed ));
232
+
217 233
 #define HERMON_MAX_SCATTER 1
218 234
 
219 235
 struct hermonprm_recv_wqe {
@@ -336,6 +352,7 @@ union hermon_send_wqe {
336 352
 	struct hermonprm_wqe_segment_ctrl_send ctrl;
337 353
 	struct hermonprm_ud_send_wqe ud;
338 354
 	struct hermonprm_mlx_send_wqe mlx;
355
+	struct hermonprm_rc_send_wqe rc;
339 356
 	uint8_t force_align[HERMON_SEND_WQE_ALIGN];
340 357
 } __attribute__ (( packed ));
341 358
 
@@ -485,11 +502,11 @@ struct hermon {
485 502
 
486 503
 	/** Event queue */
487 504
 	struct hermon_event_queue eq;
488
-	/** Reserved LKey
505
+	/** Unrestricted LKey
489 506
 	 *
490 507
 	 * Used to get unrestricted memory access.
491 508
 	 */
492
-	unsigned long reserved_lkey;
509
+	unsigned long lkey;
493 510
 
494 511
 	/** Completion queue in-use bitmask */
495 512
 	hermon_bitmask_t cq_inuse[ HERMON_BITMASK_SIZE ( HERMON_MAX_CQS ) ];

+ 12
- 0
src/drivers/infiniband/mlx_bitops.h Zobrazit soubor

@@ -106,6 +106,10 @@ typedef unsigned char pseudo_bit_t;
106 106
 	( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |	     \
107 107
 	  MLX_ASSEMBLE_5 ( _structure_st, _index, __VA_ARGS__ ) )
108 108
 
109
+#define MLX_ASSEMBLE_7( _structure_st, _index, _field, _value, ... )	     \
110
+	( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |	     \
111
+	  MLX_ASSEMBLE_6 ( _structure_st, _index, __VA_ARGS__ ) )
112
+
109 113
 /*
110 114
  * Build native-endian (positive) dword bitmasks from named fields
111 115
  *
@@ -135,6 +139,10 @@ typedef unsigned char pseudo_bit_t;
135 139
 	( MLX_MASK_1 ( _structure_st, _index, _field ) |		     \
136 140
 	  MLX_MASK_5 ( _structure_st, _index, __VA_ARGS__ ) )
137 141
 
142
+#define MLX_MASK_7( _structure_st, _index, _field, ... )		     \
143
+	( MLX_MASK_1 ( _structure_st, _index, _field ) |		     \
144
+	  MLX_MASK_6 ( _structure_st, _index, __VA_ARGS__ ) )
145
+
138 146
 /*
139 147
  * Populate big-endian dwords from named fields and values
140 148
  *
@@ -171,6 +179,10 @@ typedef unsigned char pseudo_bit_t;
171 179
 	MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_6 ( MLX_PSEUDO_STRUCT ( _ptr ),\
172 180
 						  _index, __VA_ARGS__ ) )
173 181
 
182
+#define MLX_FILL_7( _ptr, _index, ... )					     \
183
+	MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_7 ( MLX_PSEUDO_STRUCT ( _ptr ),\
184
+						  _index, __VA_ARGS__ ) )
185
+
174 186
 /*
175 187
  * Modify big-endian dword using named field and value
176 188
  *

Načítá se…
Zrušit
Uložit