aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2012-08-03 04:40:43 -0400
committerRoland Dreier <roland@purestorage.com>2012-09-30 23:33:33 -0400
commit54679e148287f0ca1bdd09264c908bacb9f19b3f (patch)
tree8ef261b3d7a51f8c29c2f625273ae9b399cb0402 /drivers
parentfc06573dfaf8a33bc0533bb70c49de13fa5232a4 (diff)
mlx4: Implement QP paravirtualization and maintain phys_pkey_cache for smp_snoop
This requires: 1. Replacing the paravirtualized P_Key index (inserted by the guest) with the real P_Key index. 2. For UD QPs, placing the guest's true source GID index in the address path structure mgid field, and setting the ud_force_mgid bit so that the mgid is taken from the QP context and not from the WQE when posting sends. 3. For UC and RC QPs, placing the guest's true source GID index in the address path structure mgid field. 4. For tunnel and proxy QPs, setting the Q_Key value reserved for that proxy/tunnel pair. Since not all the above adjustments occur in all the QP transitions, the QP transitions require separate wrapper functions. Secondly, initialize the P_Key virtualization table to its default values: Master virtualized table is 1-1 with the real P_Key table, guest virtualized table has P_Key index 0 mapped to the real P_Key index 0, and all the other P_Key indices mapped to the reserved (invalid) P_Key at index 127. Finally, add logic in smp_snoop for maintaining the phys_P_Key_cache. and generating events on the master only if a P_Key actually changed. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c33
-rw-r--r--drivers/infiniband/hw/mlx4/main.c35
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h47
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c217
6 files changed, 341 insertions, 14 deletions
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index e98849338a94..318d5bcf821b 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -185,6 +185,10 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad,
185{ 185{
186 struct ib_port_info *pinfo; 186 struct ib_port_info *pinfo;
187 u16 lid; 187 u16 lid;
188 __be16 *base;
189 u32 bn, pkey_change_bitmap;
190 int i;
191
188 192
189 struct mlx4_ib_dev *dev = to_mdev(ibdev); 193 struct mlx4_ib_dev *dev = to_mdev(ibdev);
190 if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || 194 if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
@@ -209,8 +213,33 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad,
209 break; 213 break;
210 214
211 case IB_SMP_ATTR_PKEY_TABLE: 215 case IB_SMP_ATTR_PKEY_TABLE:
212 mlx4_ib_dispatch_event(dev, port_num, 216 if (!mlx4_is_mfunc(dev->dev)) {
213 IB_EVENT_PKEY_CHANGE); 217 mlx4_ib_dispatch_event(dev, port_num,
218 IB_EVENT_PKEY_CHANGE);
219 break;
220 }
221
222 bn = be32_to_cpu(((struct ib_smp *)mad)->attr_mod) & 0xFFFF;
223 base = (__be16 *) &(((struct ib_smp *)mad)->data[0]);
224 pkey_change_bitmap = 0;
225 for (i = 0; i < 32; i++) {
226 pr_debug("PKEY[%d] = x%x\n",
227 i + bn*32, be16_to_cpu(base[i]));
228 if (be16_to_cpu(base[i]) !=
229 dev->pkeys.phys_pkey_cache[port_num - 1][i + bn*32]) {
230 pkey_change_bitmap |= (1 << i);
231 dev->pkeys.phys_pkey_cache[port_num - 1][i + bn*32] =
232 be16_to_cpu(base[i]);
233 }
234 }
235 pr_debug("PKEY Change event: port=%d, "
236 "block=0x%x, change_bitmap=0x%x\n",
237 port_num, bn, pkey_change_bitmap);
238
239 if (pkey_change_bitmap)
240 mlx4_ib_dispatch_event(dev, port_num,
241 IB_EVENT_PKEY_CHANGE);
242
214 break; 243 break;
215 244
216 case IB_SMP_ATTR_GUID_INFO: 245 case IB_SMP_ATTR_GUID_INFO:
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 3f7f77f93a1c..8e10ec2af7b6 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1121,6 +1121,38 @@ static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event
1121 return NOTIFY_DONE; 1121 return NOTIFY_DONE;
1122} 1122}
1123 1123
1124static void init_pkeys(struct mlx4_ib_dev *ibdev)
1125{
1126 int port;
1127 int slave;
1128 int i;
1129
1130 if (mlx4_is_master(ibdev->dev)) {
1131 for (slave = 0; slave <= ibdev->dev->num_vfs; ++slave) {
1132 for (port = 1; port <= ibdev->dev->caps.num_ports; ++port) {
1133 for (i = 0;
1134 i < ibdev->dev->phys_caps.pkey_phys_table_len[port];
1135 ++i) {
1136 ibdev->pkeys.virt2phys_pkey[slave][port - 1][i] =
1137 /* master has the identity virt2phys pkey mapping */
1138 (slave == mlx4_master_func_num(ibdev->dev) || !i) ? i :
1139 ibdev->dev->phys_caps.pkey_phys_table_len[port] - 1;
1140 mlx4_sync_pkey_table(ibdev->dev, slave, port, i,
1141 ibdev->pkeys.virt2phys_pkey[slave][port - 1][i]);
1142 }
1143 }
1144 }
1145 /* initialize pkey cache */
1146 for (port = 1; port <= ibdev->dev->caps.num_ports; ++port) {
1147 for (i = 0;
1148 i < ibdev->dev->phys_caps.pkey_phys_table_len[port];
1149 ++i)
1150 ibdev->pkeys.phys_pkey_cache[port-1][i] =
1151 (i) ? 0 : 0xFFFF;
1152 }
1153 }
1154}
1155
1124static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) 1156static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev)
1125{ 1157{
1126 char name[32]; 1158 char name[32];
@@ -1375,6 +1407,9 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
1375 1407
1376 ibdev->ib_active = true; 1408 ibdev->ib_active = true;
1377 1409
1410 if (mlx4_is_mfunc(ibdev->dev))
1411 init_pkeys(ibdev);
1412
1378 return ibdev; 1413 return ibdev;
1379 1414
1380err_notif: 1415err_notif:
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index cb9bebe28276..662a3c5da739 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -950,7 +950,7 @@ static struct mlx4_cmd_info cmd_info[] = {
950 .out_is_imm = false, 950 .out_is_imm = false,
951 .encode_slave_id = false, 951 .encode_slave_id = false,
952 .verify = NULL, 952 .verify = NULL,
953 .wrapper = mlx4_GEN_QP_wrapper 953 .wrapper = mlx4_INIT2INIT_QP_wrapper
954 }, 954 },
955 { 955 {
956 .opcode = MLX4_CMD_INIT2RTR_QP, 956 .opcode = MLX4_CMD_INIT2RTR_QP,
@@ -968,7 +968,7 @@ static struct mlx4_cmd_info cmd_info[] = {
968 .out_is_imm = false, 968 .out_is_imm = false,
969 .encode_slave_id = false, 969 .encode_slave_id = false,
970 .verify = NULL, 970 .verify = NULL,
971 .wrapper = mlx4_GEN_QP_wrapper 971 .wrapper = mlx4_RTR2RTS_QP_wrapper
972 }, 972 },
973 { 973 {
974 .opcode = MLX4_CMD_RTS2RTS_QP, 974 .opcode = MLX4_CMD_RTS2RTS_QP,
@@ -977,7 +977,7 @@ static struct mlx4_cmd_info cmd_info[] = {
977 .out_is_imm = false, 977 .out_is_imm = false,
978 .encode_slave_id = false, 978 .encode_slave_id = false,
979 .verify = NULL, 979 .verify = NULL,
980 .wrapper = mlx4_GEN_QP_wrapper 980 .wrapper = mlx4_RTS2RTS_QP_wrapper
981 }, 981 },
982 { 982 {
983 .opcode = MLX4_CMD_SQERR2RTS_QP, 983 .opcode = MLX4_CMD_SQERR2RTS_QP,
@@ -986,7 +986,7 @@ static struct mlx4_cmd_info cmd_info[] = {
986 .out_is_imm = false, 986 .out_is_imm = false,
987 .encode_slave_id = false, 987 .encode_slave_id = false,
988 .verify = NULL, 988 .verify = NULL,
989 .wrapper = mlx4_GEN_QP_wrapper 989 .wrapper = mlx4_SQERR2RTS_QP_wrapper
990 }, 990 },
991 { 991 {
992 .opcode = MLX4_CMD_2ERR_QP, 992 .opcode = MLX4_CMD_2ERR_QP,
@@ -1013,7 +1013,7 @@ static struct mlx4_cmd_info cmd_info[] = {
1013 .out_is_imm = false, 1013 .out_is_imm = false,
1014 .encode_slave_id = false, 1014 .encode_slave_id = false,
1015 .verify = NULL, 1015 .verify = NULL,
1016 .wrapper = mlx4_GEN_QP_wrapper 1016 .wrapper = mlx4_SQD2SQD_QP_wrapper
1017 }, 1017 },
1018 { 1018 {
1019 .opcode = MLX4_CMD_SQD2RTS_QP, 1019 .opcode = MLX4_CMD_SQD2RTS_QP,
@@ -1022,7 +1022,7 @@ static struct mlx4_cmd_info cmd_info[] = {
1022 .out_is_imm = false, 1022 .out_is_imm = false,
1023 .encode_slave_id = false, 1023 .encode_slave_id = false,
1024 .verify = NULL, 1024 .verify = NULL,
1025 .wrapper = mlx4_GEN_QP_wrapper 1025 .wrapper = mlx4_SQD2RTS_QP_wrapper
1026 }, 1026 },
1027 { 1027 {
1028 .opcode = MLX4_CMD_2RST_QP, 1028 .opcode = MLX4_CMD_2RST_QP,
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 06ef3afbc49a..2294b7173180 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -424,6 +424,17 @@ int mlx4_get_parav_qkey(struct mlx4_dev *dev, u32 qpn, u32 *qkey)
424} 424}
425EXPORT_SYMBOL(mlx4_get_parav_qkey); 425EXPORT_SYMBOL(mlx4_get_parav_qkey);
426 426
427void mlx4_sync_pkey_table(struct mlx4_dev *dev, int slave, int port, int i, int val)
428{
429 struct mlx4_priv *priv = container_of(dev, struct mlx4_priv, dev);
430
431 if (!mlx4_is_master(dev))
432 return;
433
434 priv->virt2phys_pkey[slave][port - 1][i] = val;
435}
436EXPORT_SYMBOL(mlx4_sync_pkey_table);
437
427int mlx4_is_slave_active(struct mlx4_dev *dev, int slave) 438int mlx4_is_slave_active(struct mlx4_dev *dev, int slave)
428{ 439{
429 struct mlx4_priv *priv = mlx4_priv(dev); 440 struct mlx4_priv *priv = mlx4_priv(dev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index dba69d98734a..7d27c3158d0c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -807,6 +807,8 @@ struct mlx4_priv {
807 struct io_mapping *bf_mapping; 807 struct io_mapping *bf_mapping;
808 int reserved_mtts; 808 int reserved_mtts;
809 int fs_hash_mode; 809 int fs_hash_mode;
810 u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS];
811
810}; 812};
811 813
812static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev) 814static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
@@ -1011,16 +1013,61 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
1011 struct mlx4_cmd_mailbox *inbox, 1013 struct mlx4_cmd_mailbox *inbox,
1012 struct mlx4_cmd_mailbox *outbox, 1014 struct mlx4_cmd_mailbox *outbox,
1013 struct mlx4_cmd_info *cmd); 1015 struct mlx4_cmd_info *cmd);
1016int mlx4_INIT2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
1017 struct mlx4_vhcr *vhcr,
1018 struct mlx4_cmd_mailbox *inbox,
1019 struct mlx4_cmd_mailbox *outbox,
1020 struct mlx4_cmd_info *cmd);
1014int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave, 1021int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
1015 struct mlx4_vhcr *vhcr, 1022 struct mlx4_vhcr *vhcr,
1016 struct mlx4_cmd_mailbox *inbox, 1023 struct mlx4_cmd_mailbox *inbox,
1017 struct mlx4_cmd_mailbox *outbox, 1024 struct mlx4_cmd_mailbox *outbox,
1018 struct mlx4_cmd_info *cmd); 1025 struct mlx4_cmd_info *cmd);
1026int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
1027 struct mlx4_vhcr *vhcr,
1028 struct mlx4_cmd_mailbox *inbox,
1029 struct mlx4_cmd_mailbox *outbox,
1030 struct mlx4_cmd_info *cmd);
1031int mlx4_RTS2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
1032 struct mlx4_vhcr *vhcr,
1033 struct mlx4_cmd_mailbox *inbox,
1034 struct mlx4_cmd_mailbox *outbox,
1035 struct mlx4_cmd_info *cmd);
1036int mlx4_SQERR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
1037 struct mlx4_vhcr *vhcr,
1038 struct mlx4_cmd_mailbox *inbox,
1039 struct mlx4_cmd_mailbox *outbox,
1040 struct mlx4_cmd_info *cmd);
1041int mlx4_2ERR_QP_wrapper(struct mlx4_dev *dev, int slave,
1042 struct mlx4_vhcr *vhcr,
1043 struct mlx4_cmd_mailbox *inbox,
1044 struct mlx4_cmd_mailbox *outbox,
1045 struct mlx4_cmd_info *cmd);
1046int mlx4_RTS2SQD_QP_wrapper(struct mlx4_dev *dev, int slave,
1047 struct mlx4_vhcr *vhcr,
1048 struct mlx4_cmd_mailbox *inbox,
1049 struct mlx4_cmd_mailbox *outbox,
1050 struct mlx4_cmd_info *cmd);
1051int mlx4_SQD2SQD_QP_wrapper(struct mlx4_dev *dev, int slave,
1052 struct mlx4_vhcr *vhcr,
1053 struct mlx4_cmd_mailbox *inbox,
1054 struct mlx4_cmd_mailbox *outbox,
1055 struct mlx4_cmd_info *cmd);
1056int mlx4_SQD2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
1057 struct mlx4_vhcr *vhcr,
1058 struct mlx4_cmd_mailbox *inbox,
1059 struct mlx4_cmd_mailbox *outbox,
1060 struct mlx4_cmd_info *cmd);
1019int mlx4_2RST_QP_wrapper(struct mlx4_dev *dev, int slave, 1061int mlx4_2RST_QP_wrapper(struct mlx4_dev *dev, int slave,
1020 struct mlx4_vhcr *vhcr, 1062 struct mlx4_vhcr *vhcr,
1021 struct mlx4_cmd_mailbox *inbox, 1063 struct mlx4_cmd_mailbox *inbox,
1022 struct mlx4_cmd_mailbox *outbox, 1064 struct mlx4_cmd_mailbox *outbox,
1023 struct mlx4_cmd_info *cmd); 1065 struct mlx4_cmd_info *cmd);
1066int mlx4_QUERY_QP_wrapper(struct mlx4_dev *dev, int slave,
1067 struct mlx4_vhcr *vhcr,
1068 struct mlx4_cmd_mailbox *inbox,
1069 struct mlx4_cmd_mailbox *outbox,
1070 struct mlx4_cmd_info *cmd);
1024 1071
1025int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe); 1072int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe);
1026 1073
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 3c57a83e6287..49e9de725d0a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -242,6 +242,15 @@ static int res_tracker_insert(struct rb_root *root, struct res_common *res)
242 return 0; 242 return 0;
243} 243}
244 244
245enum qp_transition {
246 QP_TRANS_INIT2RTR,
247 QP_TRANS_RTR2RTS,
248 QP_TRANS_RTS2RTS,
249 QP_TRANS_SQERR2RTS,
250 QP_TRANS_SQD2SQD,
251 QP_TRANS_SQD2RTS
252};
253
245/* For Debug uses */ 254/* For Debug uses */
246static const char *ResourceType(enum mlx4_resource rt) 255static const char *ResourceType(enum mlx4_resource rt)
247{ 256{
@@ -308,14 +317,41 @@ void mlx4_free_resource_tracker(struct mlx4_dev *dev,
308 } 317 }
309} 318}
310 319
311static void update_ud_gid(struct mlx4_dev *dev, 320static void update_pkey_index(struct mlx4_dev *dev, int slave,
312 struct mlx4_qp_context *qp_ctx, u8 slave) 321 struct mlx4_cmd_mailbox *inbox)
313{ 322{
314 u32 ts = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff; 323 u8 sched = *(u8 *)(inbox->buf + 64);
324 u8 orig_index = *(u8 *)(inbox->buf + 35);
325 u8 new_index;
326 struct mlx4_priv *priv = mlx4_priv(dev);
327 int port;
328
329 port = (sched >> 6 & 1) + 1;
330
331 new_index = priv->virt2phys_pkey[slave][port - 1][orig_index];
332 *(u8 *)(inbox->buf + 35) = new_index;
333
334 mlx4_dbg(dev, "port = %d, orig pkey index = %d, "
335 "new pkey index = %d\n", port, orig_index, new_index);
336}
337
338static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox,
339 u8 slave)
340{
341 struct mlx4_qp_context *qp_ctx = inbox->buf + 8;
342 enum mlx4_qp_optpar optpar = be32_to_cpu(*(__be32 *) inbox->buf);
343 u32 ts = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
315 344
316 if (MLX4_QP_ST_UD == ts) 345 if (MLX4_QP_ST_UD == ts)
317 qp_ctx->pri_path.mgid_index = 0x80 | slave; 346 qp_ctx->pri_path.mgid_index = 0x80 | slave;
318 347
348 if (MLX4_QP_ST_RC == ts || MLX4_QP_ST_UC == ts) {
349 if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH)
350 qp_ctx->pri_path.mgid_index = slave & 0x7F;
351 if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH)
352 qp_ctx->alt_path.mgid_index = slave & 0x7F;
353 }
354
319 mlx4_dbg(dev, "slave %d, new gid index: 0x%x ", 355 mlx4_dbg(dev, "slave %d, new gid index: 0x%x ",
320 slave, qp_ctx->pri_path.mgid_index); 356 slave, qp_ctx->pri_path.mgid_index);
321} 357}
@@ -1109,6 +1145,11 @@ static int valid_reserved(struct mlx4_dev *dev, int slave, int qpn)
1109 (mlx4_is_master(dev) || mlx4_is_guest_proxy(dev, slave, qpn)); 1145 (mlx4_is_master(dev) || mlx4_is_guest_proxy(dev, slave, qpn));
1110} 1146}
1111 1147
1148static int fw_reserved(struct mlx4_dev *dev, int qpn)
1149{
1150 return qpn < dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW];
1151}
1152
1112static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, 1153static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1113 u64 in_param, u64 *out_param) 1154 u64 in_param, u64 *out_param)
1114{ 1155{
@@ -1146,7 +1187,7 @@ static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1146 if (err) 1187 if (err)
1147 return err; 1188 return err;
1148 1189
1149 if (!valid_reserved(dev, slave, qpn)) { 1190 if (!fw_reserved(dev, qpn)) {
1150 err = __mlx4_qp_alloc_icm(dev, qpn); 1191 err = __mlx4_qp_alloc_icm(dev, qpn);
1151 if (err) { 1192 if (err) {
1152 res_abort_move(dev, slave, RES_QP, qpn); 1193 res_abort_move(dev, slave, RES_QP, qpn);
@@ -1499,7 +1540,7 @@ static int qp_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1499 if (err) 1540 if (err)
1500 return err; 1541 return err;
1501 1542
1502 if (!valid_reserved(dev, slave, qpn)) 1543 if (!fw_reserved(dev, qpn))
1503 __mlx4_qp_free_icm(dev, qpn); 1544 __mlx4_qp_free_icm(dev, qpn);
1504 1545
1505 res_end_move(dev, slave, RES_QP, qpn); 1546 res_end_move(dev, slave, RES_QP, qpn);
@@ -1939,6 +1980,19 @@ static u32 qp_get_srqn(struct mlx4_qp_context *qpc)
1939 return be32_to_cpu(qpc->srqn) & 0x1ffffff; 1980 return be32_to_cpu(qpc->srqn) & 0x1ffffff;
1940} 1981}
1941 1982
1983static void adjust_proxy_tun_qkey(struct mlx4_dev *dev, struct mlx4_vhcr *vhcr,
1984 struct mlx4_qp_context *context)
1985{
1986 u32 qpn = vhcr->in_modifier & 0xffffff;
1987 u32 qkey = 0;
1988
1989 if (mlx4_get_parav_qkey(dev, qpn, &qkey))
1990 return;
1991
1992 /* adjust qkey in qp context */
1993 context->qkey = cpu_to_be32(qkey);
1994}
1995
1942int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave, 1996int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
1943 struct mlx4_vhcr *vhcr, 1997 struct mlx4_vhcr *vhcr,
1944 struct mlx4_cmd_mailbox *inbox, 1998 struct mlx4_cmd_mailbox *inbox,
@@ -1991,6 +2045,8 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
1991 goto ex_put_scq; 2045 goto ex_put_scq;
1992 } 2046 }
1993 2047
2048 adjust_proxy_tun_qkey(dev, vhcr, qpc);
2049 update_pkey_index(dev, slave, inbox);
1994 err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); 2050 err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
1995 if (err) 2051 if (err)
1996 goto ex_put_srq; 2052 goto ex_put_srq;
@@ -2136,6 +2192,48 @@ static int get_containing_mtt(struct mlx4_dev *dev, int slave, int start,
2136 return err; 2192 return err;
2137} 2193}
2138 2194
2195static int verify_qp_parameters(struct mlx4_dev *dev,
2196 struct mlx4_cmd_mailbox *inbox,
2197 enum qp_transition transition, u8 slave)
2198{
2199 u32 qp_type;
2200 struct mlx4_qp_context *qp_ctx;
2201 enum mlx4_qp_optpar optpar;
2202
2203 qp_ctx = inbox->buf + 8;
2204 qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
2205 optpar = be32_to_cpu(*(__be32 *) inbox->buf);
2206
2207 switch (qp_type) {
2208 case MLX4_QP_ST_RC:
2209 case MLX4_QP_ST_UC:
2210 switch (transition) {
2211 case QP_TRANS_INIT2RTR:
2212 case QP_TRANS_RTR2RTS:
2213 case QP_TRANS_RTS2RTS:
2214 case QP_TRANS_SQD2SQD:
2215 case QP_TRANS_SQD2RTS:
2216 if (slave != mlx4_master_func_num(dev))
2217 /* slaves have only gid index 0 */
2218 if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH)
2219 if (qp_ctx->pri_path.mgid_index)
2220 return -EINVAL;
2221 if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH)
2222 if (qp_ctx->alt_path.mgid_index)
2223 return -EINVAL;
2224 break;
2225 default:
2226 break;
2227 }
2228
2229 break;
2230 default:
2231 break;
2232 }
2233
2234 return 0;
2235}
2236
2139int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave, 2237int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave,
2140 struct mlx4_vhcr *vhcr, 2238 struct mlx4_vhcr *vhcr,
2141 struct mlx4_cmd_mailbox *inbox, 2239 struct mlx4_cmd_mailbox *inbox,
@@ -2623,16 +2721,123 @@ out:
2623 return err; 2721 return err;
2624} 2722}
2625 2723
2724int mlx4_INIT2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
2725 struct mlx4_vhcr *vhcr,
2726 struct mlx4_cmd_mailbox *inbox,
2727 struct mlx4_cmd_mailbox *outbox,
2728 struct mlx4_cmd_info *cmd)
2729{
2730 struct mlx4_qp_context *context = inbox->buf + 8;
2731 adjust_proxy_tun_qkey(dev, vhcr, context);
2732 update_pkey_index(dev, slave, inbox);
2733 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2734}
2735
2626int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave, 2736int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
2627 struct mlx4_vhcr *vhcr, 2737 struct mlx4_vhcr *vhcr,
2628 struct mlx4_cmd_mailbox *inbox, 2738 struct mlx4_cmd_mailbox *inbox,
2629 struct mlx4_cmd_mailbox *outbox, 2739 struct mlx4_cmd_mailbox *outbox,
2630 struct mlx4_cmd_info *cmd) 2740 struct mlx4_cmd_info *cmd)
2631{ 2741{
2742 int err;
2632 struct mlx4_qp_context *qpc = inbox->buf + 8; 2743 struct mlx4_qp_context *qpc = inbox->buf + 8;
2633 2744
2634 update_ud_gid(dev, qpc, (u8)slave); 2745 err = verify_qp_parameters(dev, inbox, QP_TRANS_INIT2RTR, slave);
2746 if (err)
2747 return err;
2748
2749 update_pkey_index(dev, slave, inbox);
2750 update_gid(dev, inbox, (u8)slave);
2751 adjust_proxy_tun_qkey(dev, vhcr, qpc);
2752
2753 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2754}
2755
2756int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
2757 struct mlx4_vhcr *vhcr,
2758 struct mlx4_cmd_mailbox *inbox,
2759 struct mlx4_cmd_mailbox *outbox,
2760 struct mlx4_cmd_info *cmd)
2761{
2762 int err;
2763 struct mlx4_qp_context *context = inbox->buf + 8;
2764
2765 err = verify_qp_parameters(dev, inbox, QP_TRANS_RTR2RTS, slave);
2766 if (err)
2767 return err;
2768
2769 update_pkey_index(dev, slave, inbox);
2770 update_gid(dev, inbox, (u8)slave);
2771 adjust_proxy_tun_qkey(dev, vhcr, context);
2772 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2773}
2774
2775int mlx4_RTS2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
2776 struct mlx4_vhcr *vhcr,
2777 struct mlx4_cmd_mailbox *inbox,
2778 struct mlx4_cmd_mailbox *outbox,
2779 struct mlx4_cmd_info *cmd)
2780{
2781 int err;
2782 struct mlx4_qp_context *context = inbox->buf + 8;
2783
2784 err = verify_qp_parameters(dev, inbox, QP_TRANS_RTS2RTS, slave);
2785 if (err)
2786 return err;
2787
2788 update_pkey_index(dev, slave, inbox);
2789 update_gid(dev, inbox, (u8)slave);
2790 adjust_proxy_tun_qkey(dev, vhcr, context);
2791 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2792}
2793
2794
2795int mlx4_SQERR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
2796 struct mlx4_vhcr *vhcr,
2797 struct mlx4_cmd_mailbox *inbox,
2798 struct mlx4_cmd_mailbox *outbox,
2799 struct mlx4_cmd_info *cmd)
2800{
2801 struct mlx4_qp_context *context = inbox->buf + 8;
2802 adjust_proxy_tun_qkey(dev, vhcr, context);
2803 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2804}
2805
2806int mlx4_SQD2SQD_QP_wrapper(struct mlx4_dev *dev, int slave,
2807 struct mlx4_vhcr *vhcr,
2808 struct mlx4_cmd_mailbox *inbox,
2809 struct mlx4_cmd_mailbox *outbox,
2810 struct mlx4_cmd_info *cmd)
2811{
2812 int err;
2813 struct mlx4_qp_context *context = inbox->buf + 8;
2814
2815 err = verify_qp_parameters(dev, inbox, QP_TRANS_SQD2SQD, slave);
2816 if (err)
2817 return err;
2818
2819 adjust_proxy_tun_qkey(dev, vhcr, context);
2820 update_gid(dev, inbox, (u8)slave);
2821 update_pkey_index(dev, slave, inbox);
2822 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2823}
2824
2825int mlx4_SQD2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
2826 struct mlx4_vhcr *vhcr,
2827 struct mlx4_cmd_mailbox *inbox,
2828 struct mlx4_cmd_mailbox *outbox,
2829 struct mlx4_cmd_info *cmd)
2830{
2831 int err;
2832 struct mlx4_qp_context *context = inbox->buf + 8;
2833
2834 err = verify_qp_parameters(dev, inbox, QP_TRANS_SQD2RTS, slave);
2835 if (err)
2836 return err;
2635 2837
2838 adjust_proxy_tun_qkey(dev, vhcr, context);
2839 update_gid(dev, inbox, (u8)slave);
2840 update_pkey_index(dev, slave, inbox);
2636 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd); 2841 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2637} 2842}
2638 2843