Bladeren bron

[hermon] Allow software GMA to receive packets destined for QP1

The Linux IB Communication Manager will always send MADs to QP1,
rather than back to the originating QP.  On Hermon, QP1 is by default
handled by the embedded firmware.  We can change this, but the cost is
that we have to handle both QP0 and QP1 (i.e. we have to provide SMA
as well as GMA service in software), and we have to use MLX queues
rather than standard UD queues (i.e. we have to construct the UD
datagrams by hand).

There doesn't seem to be any viable way around this situation, ugly
though it is.
tags/v0.9.8
Michael Brown 15 jaren geleden
bovenliggende
commit
cd5a21359c
2 gewijzigde bestanden met toevoegingen van 277 en 45 verwijderingen
  1. 247
    44
      src/drivers/infiniband/hermon.c
  2. 30
    1
      src/drivers/infiniband/hermon.h

+ 247
- 44
src/drivers/infiniband/hermon.c Bestand weergeven

@@ -417,6 +417,14 @@ hermon_cmd_2rst_qp ( struct hermon *hermon, unsigned long qpn ) {
417 417
 			    0x03, NULL, qpn, NULL );
418 418
 }
419 419
 
420
+static inline int
421
+hermon_cmd_conf_special_qp ( struct hermon *hermon, unsigned int internal_qps,
422
+			     unsigned long base_qpn ) {
423
+	return hermon_cmd ( hermon,
424
+			    HERMON_HCR_VOID_CMD ( HERMON_HCR_CONF_SPECIAL_QP ),
425
+			    internal_qps, NULL, base_qpn, NULL );
426
+}
427
+
420 428
 static inline int
421 429
 hermon_cmd_mad_ifc ( struct hermon *hermon, unsigned int port,
422 430
 		     union hermonprm_mad *mad ) {
@@ -796,6 +804,63 @@ static void hermon_destroy_cq ( struct ib_device *ibdev,
796 804
  ***************************************************************************
797 805
  */
798 806
 
807
+/**
808
+ * Assign queue pair number
809
+ *
810
+ * @v ibdev		Infiniband device
811
+ * @v qp		Queue pair
812
+ * @ret rc		Return status code
813
+ */
814
+static int hermon_alloc_qpn ( struct ib_device *ibdev,
815
+			      struct ib_queue_pair *qp ) {
816
+	struct hermon *hermon = ib_get_drvdata ( ibdev );
817
+	unsigned int port_offset;
818
+	int qpn_offset;
819
+
820
+	/* Calculate queue pair number */
821
+	port_offset = ( ibdev->port - HERMON_PORT_BASE );
822
+
823
+	switch ( qp->type ) {
824
+	case IB_QPT_SMA:
825
+		qp->qpn = ( hermon->special_qpn_base + port_offset );
826
+		return 0;
827
+	case IB_QPT_GMA:
828
+		qp->qpn = ( hermon->special_qpn_base + 2 + port_offset );
829
+		return 0;
830
+	case IB_QPT_UD:
831
+		/* Find a free queue pair number */
832
+		qpn_offset = hermon_bitmask_alloc ( hermon->qp_inuse,
833
+						    HERMON_MAX_QPS, 1 );
834
+		if ( qpn_offset < 0 ) {
835
+			DBGC ( hermon, "Hermon %p out of queue pairs\n",
836
+			       hermon );
837
+			return qpn_offset;
838
+		}
839
+		qp->qpn = ( hermon->qpn_base + qpn_offset );
840
+		return 0;
841
+	default:
842
+		DBGC ( hermon, "Hermon %p unsupported QP type %d\n",
843
+		       hermon, qp->type );
844
+		return -ENOTSUP;
845
+	}
846
+}
847
+
848
+/**
849
+ * Free queue pair number
850
+ *
851
+ * @v ibdev		Infiniband device
852
+ * @v qp		Queue pair
853
+ */
854
+static void hermon_free_qpn ( struct ib_device *ibdev,
855
+			      struct ib_queue_pair *qp ) {
856
+	struct hermon *hermon = ib_get_drvdata ( ibdev );
857
+	int qpn_offset;
858
+
859
+	qpn_offset = ( qp->qpn - hermon->qpn_base );
860
+	if ( qpn_offset >= 0 )
861
+		hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 );
862
+}
863
+
799 864
 /**
800 865
  * Create queue pair
801 866
  *
@@ -808,19 +873,11 @@ static int hermon_create_qp ( struct ib_device *ibdev,
808 873
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
809 874
 	struct hermon_queue_pair *hermon_qp;
810 875
 	struct hermonprm_qp_ee_state_transitions qpctx;
811
-	int qpn_offset;
812 876
 	int rc;
813 877
 
814
-	/* Find a free queue pair number */
815
-	qpn_offset = hermon_bitmask_alloc ( hermon->qp_inuse,
816
-					    HERMON_MAX_QPS, 1 );
817
-	if ( qpn_offset < 0 ) {
818
-		DBGC ( hermon, "Hermon %p out of queue pairs\n", hermon );
819
-		rc = qpn_offset;
820
-		goto err_qpn_offset;
821
-	}
822
-	qp->qpn = ( HERMON_QPN_BASE + hermon->cap.reserved_qps +
823
-		    qpn_offset );
878
+	/* Calculate queue pair number */
879
+	if ( ( rc = hermon_alloc_qpn ( ibdev, qp ) ) != 0 )
880
+		goto err_alloc_qpn;
824 881
 
825 882
 	/* Allocate control structures */
826 883
 	hermon_qp = zalloc ( sizeof ( *hermon_qp ) );
@@ -867,7 +924,9 @@ static int hermon_create_qp ( struct ib_device *ibdev,
867 924
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
868 925
 	MLX_FILL_2 ( &qpctx, 2,
869 926
 		     qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
870
-		     qpc_eec_data.st, HERMON_ST_UD );
927
+		     qpc_eec_data.st,
928
+		     ( ( qp->type == IB_QPT_UD ) ?
929
+		       HERMON_ST_UD : HERMON_ST_MLX ) );
871 930
 	MLX_FILL_1 ( &qpctx, 3, qpc_eec_data.pd, HERMON_GLOBAL_PD );
872 931
 	MLX_FILL_4 ( &qpctx, 4,
873 932
 		     qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
@@ -901,7 +960,8 @@ static int hermon_create_qp ( struct ib_device *ibdev,
901 960
 		     qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
902 961
 	MLX_FILL_1 ( &qpctx, 16,
903 962
 		     qpc_eec_data.primary_address_path.sched_queue,
904
-		     ( 0x83 /* default policy */ |
963
+		     ( ( ( qp->type == IB_QPT_SMA ) ?
964
+			 HERMON_SCHED_QP0 : HERMON_SCHED_DEFAULT ) |
905 965
 		       ( ( ibdev->port - 1 ) << 6 ) ) );
906 966
 	if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
907 967
 					     &qpctx ) ) != 0 ) {
@@ -935,8 +995,8 @@ static int hermon_create_qp ( struct ib_device *ibdev,
935 995
  err_alloc_wqe:
936 996
 	free ( hermon_qp );
937 997
  err_hermon_qp:
938
-	hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 );
939
- err_qpn_offset:
998
+	hermon_free_qpn ( ibdev, qp );
999
+ err_alloc_qpn:
940 1000
 	return rc;
941 1001
 }
942 1002
 
@@ -976,7 +1036,6 @@ static void hermon_destroy_qp ( struct ib_device *ibdev,
976 1036
 				struct ib_queue_pair *qp ) {
977 1037
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
978 1038
 	struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
979
-	int qpn_offset;
980 1039
 	int rc;
981 1040
 
982 1041
 	/* Take ownership back from hardware */
@@ -995,9 +1054,7 @@ static void hermon_destroy_qp ( struct ib_device *ibdev,
995 1054
 	free ( hermon_qp );
996 1055
 
997 1056
 	/* Mark queue number as free */
998
-	qpn_offset = ( qp->qpn - HERMON_QPN_BASE -
999
-		       hermon->cap.reserved_qps );
1000
-	hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 );
1057
+	hermon_free_qpn ( ibdev, qp );
1001 1058
 
1002 1059
 	ib_qp_set_drvdata ( qp, NULL );
1003 1060
 }
@@ -1009,6 +1066,109 @@ static void hermon_destroy_qp ( struct ib_device *ibdev,
1009 1066
  ***************************************************************************
1010 1067
  */
1011 1068
 
1069
+/**
1070
+ * Construct UD send work queue entry
1071
+ *
1072
+ * @v ibdev		Infiniband device
1073
+ * @v qp		Queue pair
1074
+ * @v av		Address vector
1075
+ * @v iobuf		I/O buffer
1076
+ * @v wqe		Send work queue entry
1077
+ * @ret opcode		Control opcode
1078
+ */
1079
+static unsigned int
1080
+hermon_fill_ud_send_wqe ( struct ib_device *ibdev,
1081
+			  struct ib_queue_pair *qp __unused,
1082
+			  struct ib_address_vector *av,
1083
+			  struct io_buffer *iobuf,
1084
+			  union hermon_send_wqe *wqe ) {
1085
+	struct hermon *hermon = ib_get_drvdata ( ibdev );
1086
+
1087
+	MLX_FILL_1 ( &wqe->ud.ctrl, 1, ds,
1088
+		     ( ( offsetof ( typeof ( wqe->ud ), data[1] ) / 16 ) ) );
1089
+	MLX_FILL_1 ( &wqe->ud.ctrl, 2, c, 0x03 /* generate completion */ );
1090
+	MLX_FILL_2 ( &wqe->ud.ud, 0,
1091
+		     ud_address_vector.pd, HERMON_GLOBAL_PD,
1092
+		     ud_address_vector.port_number, ibdev->port );
1093
+	MLX_FILL_2 ( &wqe->ud.ud, 1,
1094
+		     ud_address_vector.rlid, av->lid,
1095
+		     ud_address_vector.g, av->gid_present );
1096
+	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 ) ) );
1100
+	MLX_FILL_1 ( &wqe->ud.ud, 3, ud_address_vector.sl, av->sl );
1101
+	memcpy ( &wqe->ud.ud.u.dwords[4], &av->gid, sizeof ( av->gid ) );
1102
+	MLX_FILL_1 ( &wqe->ud.ud, 8, destination_qp, av->qpn );
1103
+	MLX_FILL_1 ( &wqe->ud.ud, 9, q_key, av->qkey );
1104
+	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 );
1106
+	MLX_FILL_1 ( &wqe->ud.data[0], 3,
1107
+		     local_address_l, virt_to_bus ( iobuf->data ) );
1108
+	return HERMON_OPCODE_SEND;
1109
+}
1110
+
1111
+/**
1112
+ * Construct MLX send work queue entry
1113
+ *
1114
+ * @v ibdev		Infiniband device
1115
+ * @v qp		Queue pair
1116
+ * @v av		Address vector
1117
+ * @v iobuf		I/O buffer
1118
+ * @v wqe		Send work queue entry
1119
+ * @ret opcode		Control opcode
1120
+ */
1121
+static unsigned int
1122
+hermon_fill_mlx_send_wqe ( struct ib_device *ibdev,
1123
+			   struct ib_queue_pair *qp,
1124
+			   struct ib_address_vector *av,
1125
+			   struct io_buffer *iobuf,
1126
+			   union hermon_send_wqe *wqe ) {
1127
+	struct hermon *hermon = ib_get_drvdata ( ibdev );
1128
+	struct io_buffer headers;
1129
+
1130
+	/* Construct IB headers */
1131
+	iob_populate ( &headers, &wqe->mlx.headers, 0,
1132
+		       sizeof ( wqe->mlx.headers ) );
1133
+	iob_reserve ( &headers, sizeof ( wqe->mlx.headers ) );
1134
+	ib_push ( ibdev, &headers, qp, iob_len ( iobuf ), av );
1135
+
1136
+	/* Fill work queue entry */
1137
+	MLX_FILL_1 ( &wqe->mlx.ctrl, 1, ds,
1138
+		     ( ( offsetof ( typeof ( wqe->mlx ), data[2] ) / 16 ) ) );
1139
+	MLX_FILL_5 ( &wqe->mlx.ctrl, 2,
1140
+		     c, 0x03 /* generate completion */,
1141
+		     icrc, 0 /* generate ICRC */,
1142
+		     max_statrate, ( ( ( av->rate < 2 ) || ( av->rate > 10 ) )
1143
+				     ? 8 : ( av->rate + 5 ) ),
1144
+		     slr, 0,
1145
+		     v15, ( ( qp->ext_qpn == IB_QPN_SMA ) ? 1 : 0 ) );
1146
+	MLX_FILL_1 ( &wqe->mlx.ctrl, 3, rlid, av->lid );
1147
+	MLX_FILL_1 ( &wqe->mlx.data[0], 0,
1148
+		     byte_count, iob_len ( &headers ) );
1149
+	MLX_FILL_1 ( &wqe->mlx.data[0], 1, l_key, hermon->reserved_lkey );
1150
+	MLX_FILL_1 ( &wqe->mlx.data[0], 3,
1151
+		     local_address_l, virt_to_bus ( headers.data ) );
1152
+	MLX_FILL_1 ( &wqe->mlx.data[1], 0,
1153
+		     byte_count, ( iob_len ( iobuf ) + 4 /* ICRC */ ) );
1154
+	MLX_FILL_1 ( &wqe->mlx.data[1], 1, l_key, hermon->reserved_lkey );
1155
+	MLX_FILL_1 ( &wqe->mlx.data[1], 3,
1156
+		     local_address_l, virt_to_bus ( iobuf->data ) );
1157
+	return HERMON_OPCODE_SEND;
1158
+}
1159
+
1160
+/** Work queue entry constructors */
1161
+static unsigned int
1162
+( * hermon_fill_send_wqe[] ) ( struct ib_device *ibdev,
1163
+			       struct ib_queue_pair *qp,
1164
+			       struct ib_address_vector *av,
1165
+			       struct io_buffer *iobuf,
1166
+			       union hermon_send_wqe *wqe ) = {
1167
+	[IB_QPT_SMA] = hermon_fill_mlx_send_wqe,
1168
+	[IB_QPT_GMA] = hermon_fill_mlx_send_wqe,
1169
+	[IB_QPT_UD] = hermon_fill_ud_send_wqe,
1170
+};
1171
+
1012 1172
 /**
1013 1173
  * Post send work queue entry
1014 1174
  *
@@ -1026,9 +1186,10 @@ static int hermon_post_send ( struct ib_device *ibdev,
1026 1186
 	struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
1027 1187
 	struct ib_work_queue *wq = &qp->send;
1028 1188
 	struct hermon_send_work_queue *hermon_send_wq = &hermon_qp->send;
1029
-	struct hermonprm_ud_send_wqe *wqe;
1189
+	union hermon_send_wqe *wqe;
1030 1190
 	union hermonprm_doorbell_register db_reg;
1031 1191
 	unsigned int wqe_idx_mask;
1192
+	unsigned int opcode;
1032 1193
 
1033 1194
 	/* Allocate work queue entry */
1034 1195
 	wqe_idx_mask = ( wq->num_wqes - 1 );
@@ -1038,34 +1199,18 @@ static int hermon_post_send ( struct ib_device *ibdev,
1038 1199
 	}
1039 1200
 	wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
1040 1201
 	wqe = &hermon_send_wq->wqe[ wq->next_idx &
1041
-				    ( hermon_send_wq->num_wqes - 1 ) ].ud;
1202
+				    ( hermon_send_wq->num_wqes - 1 ) ];
1042 1203
 
1043 1204
 	/* Construct work queue entry */
1044 1205
 	memset ( ( ( ( void * ) wqe ) + 4 /* avoid ctrl.owner */ ), 0,
1045 1206
 		   ( sizeof ( *wqe ) - 4 ) );
1046
-	MLX_FILL_1 ( &wqe->ctrl, 1, ds, ( sizeof ( *wqe ) / 16 ) );
1047
-	MLX_FILL_1 ( &wqe->ctrl, 2, c, 0x03 /* generate completion */ );
1048
-	MLX_FILL_2 ( &wqe->ud, 0,
1049
-		     ud_address_vector.pd, HERMON_GLOBAL_PD,
1050
-		     ud_address_vector.port_number, ibdev->port );
1051
-	MLX_FILL_2 ( &wqe->ud, 1,
1052
-		     ud_address_vector.rlid, av->lid,
1053
-		     ud_address_vector.g, av->gid_present );
1054
-	MLX_FILL_1 ( &wqe->ud, 2,
1055
-		     ud_address_vector.max_stat_rate,
1056
-		     ( ( ( av->rate < 2 ) || ( av->rate > 10 ) ) ?
1057
-		       8 : ( av->rate + 5 ) ) );
1058
-	MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1059
-	memcpy ( &wqe->ud.u.dwords[4], &av->gid, sizeof ( av->gid ) );
1060
-	MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->qpn );
1061
-	MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1062
-	MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1063
-	MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->reserved_lkey );
1064
-	MLX_FILL_1 ( &wqe->data[0], 3,
1065
-		     local_address_l, virt_to_bus ( iobuf->data ) );
1207
+	assert ( qp->type < ( sizeof ( hermon_fill_send_wqe ) /
1208
+			      sizeof ( hermon_fill_send_wqe[0] ) ) );
1209
+	assert ( hermon_fill_send_wqe[qp->type] != NULL );
1210
+	opcode = hermon_fill_send_wqe[qp->type] ( ibdev, qp, av, iobuf, wqe );
1066 1211
 	barrier();
1067 1212
 	MLX_FILL_2 ( &wqe->ctrl, 0,
1068
-		     opcode, HERMON_OPCODE_SEND,
1213
+		     opcode, opcode,
1069 1214
 		     owner,
1070 1215
 		     ( ( wq->next_idx & hermon_send_wq->num_wqes ) ? 1 : 0 ) );
1071 1216
 	DBGCP ( hermon, "Hermon %p posting send WQE:\n", hermon );
@@ -1183,7 +1328,7 @@ static int hermon_complete ( struct ib_device *ibdev,
1183 1328
 	iobuf = wq->iobufs[wqe_idx];
1184 1329
 	if ( ! iobuf ) {
1185 1330
 		DBGC ( hermon, "Hermon %p CQN %lx QPN %lx empty WQE %x\n",
1186
-		       hermon, cq->cqn, qpn, wqe_idx );
1331
+		       hermon, cq->cqn, qp->qpn, wqe_idx );
1187 1332
 		return -EIO;
1188 1333
 	}
1189 1334
 	wq->iobufs[wqe_idx] = NULL;
@@ -1523,6 +1668,27 @@ static void hermon_close ( struct ib_device *ibdev ) {
1523 1668
 	}
1524 1669
 }
1525 1670
 
1671
+/**
1672
+ * Set port information
1673
+ *
1674
+ * @v ibdev		Infiniband device
1675
+ * @v mad		Set port information MAD
1676
+ * @ret rc		Return status code
1677
+ */
1678
+static int hermon_set_port_info ( struct ib_device *ibdev,
1679
+				  union ib_mad *mad ) {
1680
+	int rc;
1681
+
1682
+	/* Send the MAD to the embedded SMA */
1683
+	if ( ( rc = hermon_mad ( ibdev, mad ) ) != 0 )
1684
+		return rc;
1685
+
1686
+	/* Update parameters held in software */
1687
+	ib_smc_update ( ibdev, hermon_mad );
1688
+
1689
+	return 0;
1690
+}
1691
+
1526 1692
 /***************************************************************************
1527 1693
  *
1528 1694
  * Multicast group operations
@@ -1633,6 +1799,7 @@ static struct ib_device_operations hermon_ib_operations = {
1633 1799
 	.close		= hermon_close,
1634 1800
 	.mcast_attach	= hermon_mcast_attach,
1635 1801
 	.mcast_detach	= hermon_mcast_detach,
1802
+	.set_port_info	= hermon_set_port_info,
1636 1803
 };
1637 1804
 
1638 1805
 /***************************************************************************
@@ -1863,7 +2030,8 @@ static int hermon_alloc_icm ( struct hermon *hermon,
1863 2030
 	 */
1864 2031
 
1865 2032
 	/* Calculate number of each object type within ICM */
1866
-	log_num_qps = fls ( hermon->cap.reserved_qps + HERMON_MAX_QPS - 1 );
2033
+	log_num_qps = fls ( hermon->cap.reserved_qps +
2034
+			    HERMON_RSVD_SPECIAL_QPS + HERMON_MAX_QPS - 1 );
1867 2035
 	log_num_srqs = fls ( hermon->cap.reserved_srqs - 1 );
1868 2036
 	log_num_cqs = fls ( hermon->cap.reserved_cqs + HERMON_MAX_CQS - 1 );
1869 2037
 	log_num_eqs = fls ( hermon->cap.reserved_eqs + HERMON_MAX_EQS - 1 );
@@ -2148,6 +2316,36 @@ static int hermon_setup_mpt ( struct hermon *hermon ) {
2148 2316
 	return 0;
2149 2317
 }
2150 2318
 
2319
+/**
2320
+ * Configure special queue pairs
2321
+ *
2322
+ * @v hermon		Hermon device
2323
+ * @ret rc		Return status code
2324
+ */
2325
+static int hermon_configure_special_qps ( struct hermon *hermon ) {
2326
+	int rc;
2327
+
2328
+	/* Special QP block must be aligned on its own size */
2329
+	hermon->special_qpn_base = ( ( HERMON_QPN_BASE +
2330
+				       hermon->cap.reserved_qps +
2331
+				       HERMON_NUM_SPECIAL_QPS - 1 )
2332
+				     & ~( HERMON_NUM_SPECIAL_QPS - 1 ) );
2333
+	hermon->qpn_base = ( hermon->special_qpn_base +
2334
+			     HERMON_NUM_SPECIAL_QPS );
2335
+	DBGC ( hermon, "Hermon %p special QPs at [%lx,%lx]\n", hermon,
2336
+	       hermon->special_qpn_base, ( hermon->qpn_base - 1 ) );
2337
+
2338
+	/* Issue command to configure special QPs */
2339
+	if ( ( rc = hermon_cmd_conf_special_qp ( hermon, 0x00,
2340
+					  hermon->special_qpn_base ) ) != 0 ) {
2341
+		DBGC ( hermon, "Hermon %p could not configure special QPs: "
2342
+		       "%s\n", hermon, strerror ( rc ) );
2343
+		return rc;
2344
+	}
2345
+
2346
+	return 0;
2347
+}
2348
+
2151 2349
 /**
2152 2350
  * Probe PCI device
2153 2351
  *
@@ -2239,6 +2437,10 @@ static int hermon_probe ( struct pci_device *pci,
2239 2437
 	if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
2240 2438
 		goto err_create_eq;
2241 2439
 
2440
+	/* Configure special QPs */
2441
+	if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
2442
+		goto err_conf_special_qps;
2443
+
2242 2444
 	/* Update MAD parameters */
2243 2445
 	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ )
2244 2446
 		ib_smc_update ( hermon->ibdev[i], hermon_mad );
@@ -2258,6 +2460,7 @@ static int hermon_probe ( struct pci_device *pci,
2258 2460
  err_register_ibdev:
2259 2461
 	for ( i-- ; i >= 0 ; i-- )
2260 2462
 		unregister_ibdev ( hermon->ibdev[i] );
2463
+ err_conf_special_qps:
2261 2464
 	hermon_destroy_eq ( hermon );
2262 2465
  err_create_eq:
2263 2466
  err_setup_mpt:

+ 30
- 1
src/drivers/infiniband/hermon.h Bestand weergeven

@@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12 12
 #include <stdint.h>
13 13
 #include <gpxe/uaccess.h>
14
+#include <gpxe/ib_packet.h>
14 15
 #include "mlx_bitops.h"
15 16
 #include "MT25408_PRM.h"
16 17
 
@@ -53,6 +54,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
53 54
 #define HERMON_HCR_RTR2RTS_QP		0x001b
54 55
 #define HERMON_HCR_RTS2RTS_QP		0x001c
55 56
 #define HERMON_HCR_2RST_QP		0x0021
57
+#define HERMON_HCR_CONF_SPECIAL_QP	0x0023
56 58
 #define HERMON_HCR_MAD_IFC		0x0024
57 59
 #define HERMON_HCR_READ_MCG		0x0025
58 60
 #define HERMON_HCR_WRITE_MCG		0x0026
@@ -70,6 +72,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
70 72
 
71 73
 /* Service types */
72 74
 #define HERMON_ST_UD			0x03
75
+#define HERMON_ST_MLX			0x07
73 76
 
74 77
 /* MTUs */
75 78
 #define HERMON_MTU_2048			0x04
@@ -89,6 +92,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
89 92
 
90 93
 #define HERMON_EV_PORT_STATE_CHANGE	0x09
91 94
 
95
+#define HERMON_SCHED_QP0		0x3f
96
+#define HERMON_SCHED_DEFAULT		0x83
97
+
92 98
 /*
93 99
  * Datatypes that seem to be missing from the autogenerated documentation
94 100
  *
@@ -178,6 +184,7 @@ struct MLX_DECLARE_STRUCT ( hermonprm_scalar_parameter );
178 184
 struct MLX_DECLARE_STRUCT ( hermonprm_send_db_register );
179 185
 struct MLX_DECLARE_STRUCT ( hermonprm_ud_address_vector );
180 186
 struct MLX_DECLARE_STRUCT ( hermonprm_virtual_physical_mapping );
187
+struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ctrl_mlx );
181 188
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ctrl_send );
182 189
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_data_ptr );
183 190
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ud );
@@ -193,7 +200,7 @@ struct hermonprm_write_mtt {
193 200
 	struct hermonprm_mtt mtt;
194 201
 } __attribute__ (( packed ));
195 202
 
196
-#define HERMON_MAX_GATHER 1
203
+#define HERMON_MAX_GATHER 2
197 204
 
198 205
 struct hermonprm_ud_send_wqe {
199 206
 	struct hermonprm_wqe_segment_ctrl_send ctrl;
@@ -201,6 +208,12 @@ struct hermonprm_ud_send_wqe {
201 208
 	struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER];
202 209
 } __attribute__ (( packed ));
203 210
 
211
+struct hermonprm_mlx_send_wqe {
212
+	struct hermonprm_wqe_segment_ctrl_mlx ctrl;
213
+	struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER];
214
+	uint8_t headers[IB_MAX_HEADER_SIZE];
215
+} __attribute__ (( packed ));
216
+
204 217
 #define HERMON_MAX_SCATTER 1
205 218
 
206 219
 struct hermonprm_recv_wqe {
@@ -320,7 +333,9 @@ struct hermon_mtt {
320 333
 
321 334
 /** A Hermon send work queue entry */
322 335
 union hermon_send_wqe {
336
+	struct hermonprm_wqe_segment_ctrl_send ctrl;
323 337
 	struct hermonprm_ud_send_wqe ud;
338
+	struct hermonprm_mlx_send_wqe mlx;
324 339
 	uint8_t force_align[HERMON_SEND_WQE_ALIGN];
325 340
 } __attribute__ (( packed ));
326 341
 
@@ -360,6 +375,16 @@ struct hermon_recv_work_queue {
360 375
 	struct hermonprm_qp_db_record doorbell __attribute__ (( aligned (4) ));
361 376
 };
362 377
 
378
+/** Number of special queue pairs */
379
+#define HERMON_NUM_SPECIAL_QPS 8
380
+
381
+/** Number of queue pairs reserved for the "special QP" block
382
+ *
383
+ * The special QPs must be within a contiguous block aligned on its
384
+ * own size.
385
+ */
386
+#define HERMON_RSVD_SPECIAL_QPS	( ( HERMON_NUM_SPECIAL_QPS << 1 ) - 1 )
387
+
363 388
 /** Maximum number of allocatable queue pairs
364 389
  *
365 390
  * This is a policy decision, not a device limit.
@@ -475,6 +500,10 @@ struct hermon {
475 500
 
476 501
 	/** Device capabilities */
477 502
 	struct hermon_dev_cap cap;
503
+	/** Special QPN base */
504
+	unsigned long special_qpn_base;
505
+	/** QPN base */
506
+	unsigned long qpn_base;
478 507
 
479 508
 	/** Infiniband devices */
480 509
 	struct ib_device *ibdev[HERMON_NUM_PORTS];

Laden…
Annuleren
Opslaan