Browse Source

[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 years ago
parent
commit
cd5a21359c
2 changed files with 277 additions and 45 deletions
  1. 247
    44
      src/drivers/infiniband/hermon.c
  2. 30
    1
      src/drivers/infiniband/hermon.h

+ 247
- 44
src/drivers/infiniband/hermon.c View File

417
 			    0x03, NULL, qpn, NULL );
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
 static inline int
428
 static inline int
421
 hermon_cmd_mad_ifc ( struct hermon *hermon, unsigned int port,
429
 hermon_cmd_mad_ifc ( struct hermon *hermon, unsigned int port,
422
 		     union hermonprm_mad *mad ) {
430
 		     union hermonprm_mad *mad ) {
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
  * Create queue pair
865
  * Create queue pair
801
  *
866
  *
808
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
873
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
809
 	struct hermon_queue_pair *hermon_qp;
874
 	struct hermon_queue_pair *hermon_qp;
810
 	struct hermonprm_qp_ee_state_transitions qpctx;
875
 	struct hermonprm_qp_ee_state_transitions qpctx;
811
-	int qpn_offset;
812
 	int rc;
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
 	/* Allocate control structures */
882
 	/* Allocate control structures */
826
 	hermon_qp = zalloc ( sizeof ( *hermon_qp ) );
883
 	hermon_qp = zalloc ( sizeof ( *hermon_qp ) );
867
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
924
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
868
 	MLX_FILL_2 ( &qpctx, 2,
925
 	MLX_FILL_2 ( &qpctx, 2,
869
 		     qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
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
 	MLX_FILL_1 ( &qpctx, 3, qpc_eec_data.pd, HERMON_GLOBAL_PD );
930
 	MLX_FILL_1 ( &qpctx, 3, qpc_eec_data.pd, HERMON_GLOBAL_PD );
872
 	MLX_FILL_4 ( &qpctx, 4,
931
 	MLX_FILL_4 ( &qpctx, 4,
873
 		     qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
932
 		     qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
901
 		     qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
960
 		     qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
902
 	MLX_FILL_1 ( &qpctx, 16,
961
 	MLX_FILL_1 ( &qpctx, 16,
903
 		     qpc_eec_data.primary_address_path.sched_queue,
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
 		       ( ( ibdev->port - 1 ) << 6 ) ) );
965
 		       ( ( ibdev->port - 1 ) << 6 ) ) );
906
 	if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
966
 	if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
907
 					     &qpctx ) ) != 0 ) {
967
 					     &qpctx ) ) != 0 ) {
935
  err_alloc_wqe:
995
  err_alloc_wqe:
936
 	free ( hermon_qp );
996
 	free ( hermon_qp );
937
  err_hermon_qp:
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
 	return rc;
1000
 	return rc;
941
 }
1001
 }
942
 
1002
 
976
 				struct ib_queue_pair *qp ) {
1036
 				struct ib_queue_pair *qp ) {
977
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
1037
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
978
 	struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
1038
 	struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
979
-	int qpn_offset;
980
 	int rc;
1039
 	int rc;
981
 
1040
 
982
 	/* Take ownership back from hardware */
1041
 	/* Take ownership back from hardware */
995
 	free ( hermon_qp );
1054
 	free ( hermon_qp );
996
 
1055
 
997
 	/* Mark queue number as free */
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
 	ib_qp_set_drvdata ( qp, NULL );
1059
 	ib_qp_set_drvdata ( qp, NULL );
1003
 }
1060
 }
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
  * Post send work queue entry
1173
  * Post send work queue entry
1014
  *
1174
  *
1026
 	struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
1186
 	struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
1027
 	struct ib_work_queue *wq = &qp->send;
1187
 	struct ib_work_queue *wq = &qp->send;
1028
 	struct hermon_send_work_queue *hermon_send_wq = &hermon_qp->send;
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
 	union hermonprm_doorbell_register db_reg;
1190
 	union hermonprm_doorbell_register db_reg;
1031
 	unsigned int wqe_idx_mask;
1191
 	unsigned int wqe_idx_mask;
1192
+	unsigned int opcode;
1032
 
1193
 
1033
 	/* Allocate work queue entry */
1194
 	/* Allocate work queue entry */
1034
 	wqe_idx_mask = ( wq->num_wqes - 1 );
1195
 	wqe_idx_mask = ( wq->num_wqes - 1 );
1038
 	}
1199
 	}
1039
 	wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
1200
 	wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
1040
 	wqe = &hermon_send_wq->wqe[ wq->next_idx &
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
 	/* Construct work queue entry */
1204
 	/* Construct work queue entry */
1044
 	memset ( ( ( ( void * ) wqe ) + 4 /* avoid ctrl.owner */ ), 0,
1205
 	memset ( ( ( ( void * ) wqe ) + 4 /* avoid ctrl.owner */ ), 0,
1045
 		   ( sizeof ( *wqe ) - 4 ) );
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
 	barrier();
1211
 	barrier();
1067
 	MLX_FILL_2 ( &wqe->ctrl, 0,
1212
 	MLX_FILL_2 ( &wqe->ctrl, 0,
1068
-		     opcode, HERMON_OPCODE_SEND,
1213
+		     opcode, opcode,
1069
 		     owner,
1214
 		     owner,
1070
 		     ( ( wq->next_idx & hermon_send_wq->num_wqes ) ? 1 : 0 ) );
1215
 		     ( ( wq->next_idx & hermon_send_wq->num_wqes ) ? 1 : 0 ) );
1071
 	DBGCP ( hermon, "Hermon %p posting send WQE:\n", hermon );
1216
 	DBGCP ( hermon, "Hermon %p posting send WQE:\n", hermon );
1183
 	iobuf = wq->iobufs[wqe_idx];
1328
 	iobuf = wq->iobufs[wqe_idx];
1184
 	if ( ! iobuf ) {
1329
 	if ( ! iobuf ) {
1185
 		DBGC ( hermon, "Hermon %p CQN %lx QPN %lx empty WQE %x\n",
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
 		return -EIO;
1332
 		return -EIO;
1188
 	}
1333
 	}
1189
 	wq->iobufs[wqe_idx] = NULL;
1334
 	wq->iobufs[wqe_idx] = NULL;
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
  * Multicast group operations
1694
  * Multicast group operations
1633
 	.close		= hermon_close,
1799
 	.close		= hermon_close,
1634
 	.mcast_attach	= hermon_mcast_attach,
1800
 	.mcast_attach	= hermon_mcast_attach,
1635
 	.mcast_detach	= hermon_mcast_detach,
1801
 	.mcast_detach	= hermon_mcast_detach,
1802
+	.set_port_info	= hermon_set_port_info,
1636
 };
1803
 };
1637
 
1804
 
1638
 /***************************************************************************
1805
 /***************************************************************************
1863
 	 */
2030
 	 */
1864
 
2031
 
1865
 	/* Calculate number of each object type within ICM */
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
 	log_num_srqs = fls ( hermon->cap.reserved_srqs - 1 );
2035
 	log_num_srqs = fls ( hermon->cap.reserved_srqs - 1 );
1868
 	log_num_cqs = fls ( hermon->cap.reserved_cqs + HERMON_MAX_CQS - 1 );
2036
 	log_num_cqs = fls ( hermon->cap.reserved_cqs + HERMON_MAX_CQS - 1 );
1869
 	log_num_eqs = fls ( hermon->cap.reserved_eqs + HERMON_MAX_EQS - 1 );
2037
 	log_num_eqs = fls ( hermon->cap.reserved_eqs + HERMON_MAX_EQS - 1 );
2148
 	return 0;
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
  * Probe PCI device
2350
  * Probe PCI device
2153
  *
2351
  *
2239
 	if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
2437
 	if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
2240
 		goto err_create_eq;
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
 	/* Update MAD parameters */
2444
 	/* Update MAD parameters */
2243
 	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ )
2445
 	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ )
2244
 		ib_smc_update ( hermon->ibdev[i], hermon_mad );
2446
 		ib_smc_update ( hermon->ibdev[i], hermon_mad );
2258
  err_register_ibdev:
2460
  err_register_ibdev:
2259
 	for ( i-- ; i >= 0 ; i-- )
2461
 	for ( i-- ; i >= 0 ; i-- )
2260
 		unregister_ibdev ( hermon->ibdev[i] );
2462
 		unregister_ibdev ( hermon->ibdev[i] );
2463
+ err_conf_special_qps:
2261
 	hermon_destroy_eq ( hermon );
2464
 	hermon_destroy_eq ( hermon );
2262
  err_create_eq:
2465
  err_create_eq:
2263
  err_setup_mpt:
2466
  err_setup_mpt:

+ 30
- 1
src/drivers/infiniband/hermon.h View File

11
 
11
 
12
 #include <stdint.h>
12
 #include <stdint.h>
13
 #include <gpxe/uaccess.h>
13
 #include <gpxe/uaccess.h>
14
+#include <gpxe/ib_packet.h>
14
 #include "mlx_bitops.h"
15
 #include "mlx_bitops.h"
15
 #include "MT25408_PRM.h"
16
 #include "MT25408_PRM.h"
16
 
17
 
53
 #define HERMON_HCR_RTR2RTS_QP		0x001b
54
 #define HERMON_HCR_RTR2RTS_QP		0x001b
54
 #define HERMON_HCR_RTS2RTS_QP		0x001c
55
 #define HERMON_HCR_RTS2RTS_QP		0x001c
55
 #define HERMON_HCR_2RST_QP		0x0021
56
 #define HERMON_HCR_2RST_QP		0x0021
57
+#define HERMON_HCR_CONF_SPECIAL_QP	0x0023
56
 #define HERMON_HCR_MAD_IFC		0x0024
58
 #define HERMON_HCR_MAD_IFC		0x0024
57
 #define HERMON_HCR_READ_MCG		0x0025
59
 #define HERMON_HCR_READ_MCG		0x0025
58
 #define HERMON_HCR_WRITE_MCG		0x0026
60
 #define HERMON_HCR_WRITE_MCG		0x0026
70
 
72
 
71
 /* Service types */
73
 /* Service types */
72
 #define HERMON_ST_UD			0x03
74
 #define HERMON_ST_UD			0x03
75
+#define HERMON_ST_MLX			0x07
73
 
76
 
74
 /* MTUs */
77
 /* MTUs */
75
 #define HERMON_MTU_2048			0x04
78
 #define HERMON_MTU_2048			0x04
89
 
92
 
90
 #define HERMON_EV_PORT_STATE_CHANGE	0x09
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
  * Datatypes that seem to be missing from the autogenerated documentation
99
  * Datatypes that seem to be missing from the autogenerated documentation
94
  *
100
  *
178
 struct MLX_DECLARE_STRUCT ( hermonprm_send_db_register );
184
 struct MLX_DECLARE_STRUCT ( hermonprm_send_db_register );
179
 struct MLX_DECLARE_STRUCT ( hermonprm_ud_address_vector );
185
 struct MLX_DECLARE_STRUCT ( hermonprm_ud_address_vector );
180
 struct MLX_DECLARE_STRUCT ( hermonprm_virtual_physical_mapping );
186
 struct MLX_DECLARE_STRUCT ( hermonprm_virtual_physical_mapping );
187
+struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ctrl_mlx );
181
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ctrl_send );
188
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ctrl_send );
182
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_data_ptr );
189
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_data_ptr );
183
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ud );
190
 struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ud );
193
 	struct hermonprm_mtt mtt;
200
 	struct hermonprm_mtt mtt;
194
 } __attribute__ (( packed ));
201
 } __attribute__ (( packed ));
195
 
202
 
196
-#define HERMON_MAX_GATHER 1
203
+#define HERMON_MAX_GATHER 2
197
 
204
 
198
 struct hermonprm_ud_send_wqe {
205
 struct hermonprm_ud_send_wqe {
199
 	struct hermonprm_wqe_segment_ctrl_send ctrl;
206
 	struct hermonprm_wqe_segment_ctrl_send ctrl;
201
 	struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER];
208
 	struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER];
202
 } __attribute__ (( packed ));
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
 #define HERMON_MAX_SCATTER 1
217
 #define HERMON_MAX_SCATTER 1
205
 
218
 
206
 struct hermonprm_recv_wqe {
219
 struct hermonprm_recv_wqe {
320
 
333
 
321
 /** A Hermon send work queue entry */
334
 /** A Hermon send work queue entry */
322
 union hermon_send_wqe {
335
 union hermon_send_wqe {
336
+	struct hermonprm_wqe_segment_ctrl_send ctrl;
323
 	struct hermonprm_ud_send_wqe ud;
337
 	struct hermonprm_ud_send_wqe ud;
338
+	struct hermonprm_mlx_send_wqe mlx;
324
 	uint8_t force_align[HERMON_SEND_WQE_ALIGN];
339
 	uint8_t force_align[HERMON_SEND_WQE_ALIGN];
325
 } __attribute__ (( packed ));
340
 } __attribute__ (( packed ));
326
 
341
 
360
 	struct hermonprm_qp_db_record doorbell __attribute__ (( aligned (4) ));
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
 /** Maximum number of allocatable queue pairs
388
 /** Maximum number of allocatable queue pairs
364
  *
389
  *
365
  * This is a policy decision, not a device limit.
390
  * This is a policy decision, not a device limit.
475
 
500
 
476
 	/** Device capabilities */
501
 	/** Device capabilities */
477
 	struct hermon_dev_cap cap;
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
 	/** Infiniband devices */
508
 	/** Infiniband devices */
480
 	struct ib_device *ibdev[HERMON_NUM_PORTS];
509
 	struct ib_device *ibdev[HERMON_NUM_PORTS];

Loading…
Cancel
Save