|
@@ -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:
|