diff options
author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2014-03-12 06:00:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-12 15:57:14 -0400 |
commit | b6ffaeffaea4d92f05f5ba1ef54df407cb7c8517 (patch) | |
tree | 36ce4558756c07bdcc47a8ad6a6a3208f4e1fe05 /drivers | |
parent | 9cd593529c8652785bc9962acc79b6b176741f99 (diff) |
mlx4: In RoCE allow guests to have multiple GIDS
The GIDs are statically distributed, as follows:
PF: gets 16 GIDs
VFs: Remaining GIDS are divided evenly between VFs activated by the driver.
If the division is not even, lower-numbered VFs get an extra GID.
For an IB interface, the number of gids per guest remains as before: one gid per guest.
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 34 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 117 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 64 |
6 files changed, 191 insertions, 38 deletions
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index c2e9879a5a34..c5bca0f0da4a 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -511,9 +511,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
511 | memset(&attr, 0, sizeof attr); | 511 | memset(&attr, 0, sizeof attr); |
512 | attr.port_num = port; | 512 | attr.port_num = port; |
513 | if (is_eth) { | 513 | if (is_eth) { |
514 | ret = mlx4_get_roce_gid_from_slave(dev->dev, port, slave, attr.grh.dgid.raw); | 514 | memcpy(&attr.grh.dgid.raw[0], &grh->dgid.raw[0], 16); |
515 | if (ret) | ||
516 | return ret; | ||
517 | attr.ah_flags = IB_AH_GRH; | 515 | attr.ah_flags = IB_AH_GRH; |
518 | } | 516 | } |
519 | ah = ib_create_ah(tun_ctx->pd, &attr); | 517 | ah = ib_create_ah(tun_ctx->pd, &attr); |
@@ -1216,6 +1214,34 @@ out: | |||
1216 | return ret; | 1214 | return ret; |
1217 | } | 1215 | } |
1218 | 1216 | ||
1217 | static int get_slave_base_gid_ix(struct mlx4_ib_dev *dev, int slave, int port) | ||
1218 | { | ||
1219 | int gids; | ||
1220 | int vfs; | ||
1221 | |||
1222 | if (rdma_port_get_link_layer(&dev->ib_dev, port) == IB_LINK_LAYER_INFINIBAND) | ||
1223 | return slave; | ||
1224 | |||
1225 | gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; | ||
1226 | vfs = dev->dev->num_vfs; | ||
1227 | |||
1228 | if (slave == 0) | ||
1229 | return 0; | ||
1230 | if (slave <= gids % vfs) | ||
1231 | return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave - 1); | ||
1232 | |||
1233 | return MLX4_ROCE_PF_GIDS + (gids % vfs) + ((gids / vfs) * (slave - 1)); | ||
1234 | } | ||
1235 | |||
1236 | static void fill_in_real_sgid_index(struct mlx4_ib_dev *dev, int slave, int port, | ||
1237 | struct ib_ah_attr *ah_attr) | ||
1238 | { | ||
1239 | if (rdma_port_get_link_layer(&dev->ib_dev, port) == IB_LINK_LAYER_INFINIBAND) | ||
1240 | ah_attr->grh.sgid_index = slave; | ||
1241 | else | ||
1242 | ah_attr->grh.sgid_index += get_slave_base_gid_ix(dev, slave, port); | ||
1243 | } | ||
1244 | |||
1219 | static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc *wc) | 1245 | static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc *wc) |
1220 | { | 1246 | { |
1221 | struct mlx4_ib_dev *dev = to_mdev(ctx->ib_dev); | 1247 | struct mlx4_ib_dev *dev = to_mdev(ctx->ib_dev); |
@@ -1303,7 +1329,7 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc | |||
1303 | ah.ibah.device = ctx->ib_dev; | 1329 | ah.ibah.device = ctx->ib_dev; |
1304 | mlx4_ib_query_ah(&ah.ibah, &ah_attr); | 1330 | mlx4_ib_query_ah(&ah.ibah, &ah_attr); |
1305 | if (ah_attr.ah_flags & IB_AH_GRH) | 1331 | if (ah_attr.ah_flags & IB_AH_GRH) |
1306 | ah_attr.grh.sgid_index = slave; | 1332 | fill_in_real_sgid_index(dev, slave, ctx->port, &ah_attr); |
1307 | 1333 | ||
1308 | mlx4_ib_send_to_wire(dev, slave, ctx->port, | 1334 | mlx4_ib_send_to_wire(dev, slave, ctx->port, |
1309 | is_proxy_qp0(dev, wc->src_qp, slave) ? | 1335 | is_proxy_qp0(dev, wc->src_qp, slave) ? |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 9cdf452140da..6e1ee2170a39 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -934,7 +934,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
934 | MLX4_PUT(outbox->buf, port_type, | 934 | MLX4_PUT(outbox->buf, port_type, |
935 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); | 935 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); |
936 | 936 | ||
937 | short_field = 1; /* slave max gids */ | 937 | if (dev->caps.port_type[vhcr->in_modifier] == MLX4_PORT_TYPE_ETH) |
938 | short_field = mlx4_get_slave_num_gids(dev, slave); | ||
939 | else | ||
940 | short_field = 1; /* slave max gids */ | ||
938 | MLX4_PUT(outbox->buf, short_field, | 941 | MLX4_PUT(outbox->buf, short_field, |
939 | QUERY_PORT_CUR_MAX_GID_OFFSET); | 942 | QUERY_PORT_CUR_MAX_GID_OFFSET); |
940 | 943 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 979ea4364efb..4c441aa83016 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -1462,7 +1462,11 @@ static void mlx4_parav_master_pf_caps(struct mlx4_dev *dev) | |||
1462 | int i; | 1462 | int i; |
1463 | 1463 | ||
1464 | for (i = 1; i <= dev->caps.num_ports; i++) { | 1464 | for (i = 1; i <= dev->caps.num_ports; i++) { |
1465 | dev->caps.gid_table_len[i] = 1; | 1465 | if (dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH) |
1466 | dev->caps.gid_table_len[i] = | ||
1467 | mlx4_get_slave_num_gids(dev, 0); | ||
1468 | else | ||
1469 | dev->caps.gid_table_len[i] = 1; | ||
1466 | dev->caps.pkey_table_len[i] = | 1470 | dev->caps.pkey_table_len[i] = |
1467 | dev->phys_caps.pkey_phys_table_len[i] - 1; | 1471 | dev->phys_caps.pkey_phys_table_len[i] - 1; |
1468 | } | 1472 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index da829f4ef938..6ba38c98c492 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -1287,4 +1287,7 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work); | |||
1287 | 1287 | ||
1288 | void mlx4_init_quotas(struct mlx4_dev *dev); | 1288 | void mlx4_init_quotas(struct mlx4_dev *dev); |
1289 | 1289 | ||
1290 | int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave); | ||
1291 | int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave); | ||
1292 | |||
1290 | #endif /* MLX4_H */ | 1293 | #endif /* MLX4_H */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 591740b06043..ece328166e94 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
@@ -507,6 +507,31 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) | |||
507 | } | 507 | } |
508 | static struct mlx4_roce_gid_entry zgid_entry; | 508 | static struct mlx4_roce_gid_entry zgid_entry; |
509 | 509 | ||
510 | int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave) | ||
511 | { | ||
512 | if (slave == 0) | ||
513 | return MLX4_ROCE_PF_GIDS; | ||
514 | if (slave <= ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) % dev->num_vfs)) | ||
515 | return ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / dev->num_vfs) + 1; | ||
516 | return (MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / dev->num_vfs; | ||
517 | } | ||
518 | |||
519 | int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave) | ||
520 | { | ||
521 | int gids; | ||
522 | int vfs; | ||
523 | |||
524 | gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; | ||
525 | vfs = dev->num_vfs; | ||
526 | |||
527 | if (slave == 0) | ||
528 | return 0; | ||
529 | if (slave <= gids % vfs) | ||
530 | return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave - 1); | ||
531 | |||
532 | return MLX4_ROCE_PF_GIDS + (gids % vfs) + ((gids / vfs) * (slave - 1)); | ||
533 | } | ||
534 | |||
510 | static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | 535 | static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, |
511 | u8 op_mod, struct mlx4_cmd_mailbox *inbox) | 536 | u8 op_mod, struct mlx4_cmd_mailbox *inbox) |
512 | { | 537 | { |
@@ -516,15 +541,18 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
516 | struct mlx4_slave_state *slave_st = &master->slave_state[slave]; | 541 | struct mlx4_slave_state *slave_st = &master->slave_state[slave]; |
517 | struct mlx4_set_port_rqp_calc_context *qpn_context; | 542 | struct mlx4_set_port_rqp_calc_context *qpn_context; |
518 | struct mlx4_set_port_general_context *gen_context; | 543 | struct mlx4_set_port_general_context *gen_context; |
519 | struct mlx4_roce_gid_entry *gid_entry; | 544 | struct mlx4_roce_gid_entry *gid_entry_tbl, *gid_entry_mbox, *gid_entry_mb1; |
520 | int reset_qkey_viols; | 545 | int reset_qkey_viols; |
521 | int port; | 546 | int port; |
522 | int is_eth; | 547 | int is_eth; |
548 | int num_gids; | ||
549 | int base; | ||
523 | u32 in_modifier; | 550 | u32 in_modifier; |
524 | u32 promisc; | 551 | u32 promisc; |
525 | u16 mtu, prev_mtu; | 552 | u16 mtu, prev_mtu; |
526 | int err; | 553 | int err; |
527 | int i; | 554 | int i, j; |
555 | int offset; | ||
528 | __be32 agg_cap_mask; | 556 | __be32 agg_cap_mask; |
529 | __be32 slave_cap_mask; | 557 | __be32 slave_cap_mask; |
530 | __be32 new_cap_mask; | 558 | __be32 new_cap_mask; |
@@ -585,26 +613,65 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
585 | gen_context->mtu = cpu_to_be16(master->max_mtu[port]); | 613 | gen_context->mtu = cpu_to_be16(master->max_mtu[port]); |
586 | break; | 614 | break; |
587 | case MLX4_SET_PORT_GID_TABLE: | 615 | case MLX4_SET_PORT_GID_TABLE: |
588 | gid_entry = (struct mlx4_roce_gid_entry *)(inbox->buf); | 616 | /* change to MULTIPLE entries: number of guest's gids |
589 | /* check that do not have duplicates */ | 617 | * need a FOR-loop here over number of gids the guest has. |
590 | if (memcmp(gid_entry->raw, zgid_entry.raw, 16)) { | 618 | * 1. Check no duplicates in gids passed by slave |
591 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { | 619 | */ |
592 | if (slave != i && | 620 | num_gids = mlx4_get_slave_num_gids(dev, slave); |
593 | !memcmp(gid_entry->raw, priv->roce_gids[port - 1][i].raw, 16)) { | 621 | base = mlx4_get_base_gid_ix(dev, slave); |
594 | mlx4_warn(dev, "requested gid entry for slave:%d " | 622 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); |
595 | "is a duplicate of slave %d\n", | 623 | for (i = 0; i < num_gids; gid_entry_mbox++, i++) { |
596 | slave, i); | 624 | if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw, |
597 | return -EEXIST; | 625 | sizeof(zgid_entry))) |
626 | continue; | ||
627 | gid_entry_mb1 = gid_entry_mbox + 1; | ||
628 | for (j = i + 1; j < num_gids; gid_entry_mb1++, j++) { | ||
629 | if (!memcmp(gid_entry_mb1->raw, | ||
630 | zgid_entry.raw, sizeof(zgid_entry))) | ||
631 | continue; | ||
632 | if (!memcmp(gid_entry_mb1->raw, gid_entry_mbox->raw, | ||
633 | sizeof(gid_entry_mbox->raw))) { | ||
634 | /* found duplicate */ | ||
635 | return -EINVAL; | ||
598 | } | 636 | } |
599 | } | 637 | } |
600 | } | 638 | } |
601 | /* insert slave GID at proper index */ | 639 | |
602 | memcpy(priv->roce_gids[port - 1][slave].raw, gid_entry->raw, 16); | 640 | /* 2. Check that do not have duplicates in OTHER |
603 | /* rewrite roce port gids table to FW */ | 641 | * entries in the port GID table |
642 | */ | ||
604 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { | 643 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { |
605 | memcpy(gid_entry->raw, priv->roce_gids[port - 1][i].raw, 16); | 644 | if (i >= base && i < base + num_gids) |
606 | gid_entry++; | 645 | continue; /* don't compare to slave's current gids */ |
646 | gid_entry_tbl = &priv->roce_gids[port - 1][i]; | ||
647 | if (!memcmp(gid_entry_tbl->raw, zgid_entry.raw, sizeof(zgid_entry))) | ||
648 | continue; | ||
649 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | ||
650 | for (j = 0; j < num_gids; gid_entry_mbox++, j++) { | ||
651 | if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw, | ||
652 | sizeof(zgid_entry))) | ||
653 | continue; | ||
654 | if (!memcmp(gid_entry_mbox->raw, gid_entry_tbl->raw, | ||
655 | sizeof(gid_entry_tbl->raw))) { | ||
656 | /* found duplicate */ | ||
657 | mlx4_warn(dev, "requested gid entry for slave:%d " | ||
658 | "is a duplicate of gid at index %d\n", | ||
659 | slave, i); | ||
660 | return -EINVAL; | ||
661 | } | ||
662 | } | ||
607 | } | 663 | } |
664 | |||
665 | /* insert slave GIDs with memcpy, starting at slave's base index */ | ||
666 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | ||
667 | for (i = 0, offset = base; i < num_gids; gid_entry_mbox++, offset++, i++) | ||
668 | memcpy(priv->roce_gids[port - 1][offset].raw, gid_entry_mbox->raw, 16); | ||
669 | |||
670 | /* Now, copy roce port gids table to current mailbox for passing to FW */ | ||
671 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | ||
672 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++) | ||
673 | memcpy(gid_entry_mbox->raw, priv->roce_gids[port - 1][i].raw, 16); | ||
674 | |||
608 | break; | 675 | break; |
609 | } | 676 | } |
610 | return mlx4_cmd(dev, inbox->dma, in_mod, op_mod, | 677 | return mlx4_cmd(dev, inbox->dma, in_mod, op_mod, |
@@ -958,6 +1025,7 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, | |||
958 | { | 1025 | { |
959 | struct mlx4_priv *priv = mlx4_priv(dev); | 1026 | struct mlx4_priv *priv = mlx4_priv(dev); |
960 | int i, found_ix = -1; | 1027 | int i, found_ix = -1; |
1028 | int vf_gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; | ||
961 | 1029 | ||
962 | if (!mlx4_is_mfunc(dev)) | 1030 | if (!mlx4_is_mfunc(dev)) |
963 | return -EINVAL; | 1031 | return -EINVAL; |
@@ -969,8 +1037,19 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, | |||
969 | } | 1037 | } |
970 | } | 1038 | } |
971 | 1039 | ||
972 | if (found_ix >= 0) | 1040 | if (found_ix >= 0) { |
973 | *slave_id = found_ix; | 1041 | if (found_ix < MLX4_ROCE_PF_GIDS) |
1042 | *slave_id = 0; | ||
1043 | else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % dev->num_vfs) * | ||
1044 | (vf_gids / dev->num_vfs + 1)) | ||
1045 | *slave_id = ((found_ix - MLX4_ROCE_PF_GIDS) / | ||
1046 | (vf_gids / dev->num_vfs + 1)) + 1; | ||
1047 | else | ||
1048 | *slave_id = | ||
1049 | ((found_ix - MLX4_ROCE_PF_GIDS - | ||
1050 | ((vf_gids % dev->num_vfs) * ((vf_gids / dev->num_vfs + 1)))) / | ||
1051 | (vf_gids / dev->num_vfs)) + vf_gids % dev->num_vfs + 1; | ||
1052 | } | ||
974 | 1053 | ||
975 | return (found_ix >= 0) ? 0 : -EINVAL; | 1054 | return (found_ix >= 0) ? 0 : -EINVAL; |
976 | } | 1055 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 57428a0cb9dd..1c3634eab5e1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -219,6 +219,11 @@ struct res_fs_rule { | |||
219 | int qpn; | 219 | int qpn; |
220 | }; | 220 | }; |
221 | 221 | ||
222 | static int mlx4_is_eth(struct mlx4_dev *dev, int port) | ||
223 | { | ||
224 | return dev->caps.port_mask[port] == MLX4_PORT_TYPE_IB ? 0 : 1; | ||
225 | } | ||
226 | |||
222 | static void *res_tracker_lookup(struct rb_root *root, u64 res_id) | 227 | static void *res_tracker_lookup(struct rb_root *root, u64 res_id) |
223 | { | 228 | { |
224 | struct rb_node *node = root->rb_node; | 229 | struct rb_node *node = root->rb_node; |
@@ -600,15 +605,34 @@ static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox, | |||
600 | struct mlx4_qp_context *qp_ctx = inbox->buf + 8; | 605 | struct mlx4_qp_context *qp_ctx = inbox->buf + 8; |
601 | enum mlx4_qp_optpar optpar = be32_to_cpu(*(__be32 *) inbox->buf); | 606 | enum mlx4_qp_optpar optpar = be32_to_cpu(*(__be32 *) inbox->buf); |
602 | u32 ts = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff; | 607 | u32 ts = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff; |
608 | int port; | ||
603 | 609 | ||
604 | if (MLX4_QP_ST_UD == ts) | 610 | if (MLX4_QP_ST_UD == ts) { |
605 | qp_ctx->pri_path.mgid_index = 0x80 | slave; | 611 | port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1; |
606 | 612 | if (mlx4_is_eth(dev, port)) | |
607 | if (MLX4_QP_ST_RC == ts || MLX4_QP_ST_UC == ts) { | 613 | qp_ctx->pri_path.mgid_index = mlx4_get_base_gid_ix(dev, slave) | 0x80; |
608 | if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) | 614 | else |
609 | qp_ctx->pri_path.mgid_index = slave & 0x7F; | 615 | qp_ctx->pri_path.mgid_index = slave | 0x80; |
610 | if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) | 616 | |
611 | qp_ctx->alt_path.mgid_index = slave & 0x7F; | 617 | } else if (MLX4_QP_ST_RC == ts || MLX4_QP_ST_XRC == ts || MLX4_QP_ST_UC == ts) { |
618 | if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) { | ||
619 | port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1; | ||
620 | if (mlx4_is_eth(dev, port)) { | ||
621 | qp_ctx->pri_path.mgid_index += mlx4_get_base_gid_ix(dev, slave); | ||
622 | qp_ctx->pri_path.mgid_index &= 0x7f; | ||
623 | } else { | ||
624 | qp_ctx->pri_path.mgid_index = slave & 0x7F; | ||
625 | } | ||
626 | } | ||
627 | if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) { | ||
628 | port = (qp_ctx->alt_path.sched_queue >> 6 & 1) + 1; | ||
629 | if (mlx4_is_eth(dev, port)) { | ||
630 | qp_ctx->alt_path.mgid_index += mlx4_get_base_gid_ix(dev, slave); | ||
631 | qp_ctx->alt_path.mgid_index &= 0x7f; | ||
632 | } else { | ||
633 | qp_ctx->alt_path.mgid_index = slave & 0x7F; | ||
634 | } | ||
635 | } | ||
612 | } | 636 | } |
613 | } | 637 | } |
614 | 638 | ||
@@ -2734,6 +2758,8 @@ static int verify_qp_parameters(struct mlx4_dev *dev, | |||
2734 | u32 qp_type; | 2758 | u32 qp_type; |
2735 | struct mlx4_qp_context *qp_ctx; | 2759 | struct mlx4_qp_context *qp_ctx; |
2736 | enum mlx4_qp_optpar optpar; | 2760 | enum mlx4_qp_optpar optpar; |
2761 | int port; | ||
2762 | int num_gids; | ||
2737 | 2763 | ||
2738 | qp_ctx = inbox->buf + 8; | 2764 | qp_ctx = inbox->buf + 8; |
2739 | qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff; | 2765 | qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff; |
@@ -2741,6 +2767,7 @@ static int verify_qp_parameters(struct mlx4_dev *dev, | |||
2741 | 2767 | ||
2742 | switch (qp_type) { | 2768 | switch (qp_type) { |
2743 | case MLX4_QP_ST_RC: | 2769 | case MLX4_QP_ST_RC: |
2770 | case MLX4_QP_ST_XRC: | ||
2744 | case MLX4_QP_ST_UC: | 2771 | case MLX4_QP_ST_UC: |
2745 | switch (transition) { | 2772 | switch (transition) { |
2746 | case QP_TRANS_INIT2RTR: | 2773 | case QP_TRANS_INIT2RTR: |
@@ -2749,13 +2776,24 @@ static int verify_qp_parameters(struct mlx4_dev *dev, | |||
2749 | case QP_TRANS_SQD2SQD: | 2776 | case QP_TRANS_SQD2SQD: |
2750 | case QP_TRANS_SQD2RTS: | 2777 | case QP_TRANS_SQD2RTS: |
2751 | if (slave != mlx4_master_func_num(dev)) | 2778 | if (slave != mlx4_master_func_num(dev)) |
2752 | /* slaves have only gid index 0 */ | 2779 | if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) { |
2753 | if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) | 2780 | port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1; |
2754 | if (qp_ctx->pri_path.mgid_index) | 2781 | if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB) |
2782 | num_gids = mlx4_get_slave_num_gids(dev, slave); | ||
2783 | else | ||
2784 | num_gids = 1; | ||
2785 | if (qp_ctx->pri_path.mgid_index >= num_gids) | ||
2755 | return -EINVAL; | 2786 | return -EINVAL; |
2756 | if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) | 2787 | } |
2757 | if (qp_ctx->alt_path.mgid_index) | 2788 | if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) { |
2789 | port = (qp_ctx->alt_path.sched_queue >> 6 & 1) + 1; | ||
2790 | if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB) | ||
2791 | num_gids = mlx4_get_slave_num_gids(dev, slave); | ||
2792 | else | ||
2793 | num_gids = 1; | ||
2794 | if (qp_ctx->alt_path.mgid_index >= num_gids) | ||
2758 | return -EINVAL; | 2795 | return -EINVAL; |
2796 | } | ||
2759 | break; | 2797 | break; |
2760 | default: | 2798 | default: |
2761 | break; | 2799 | break; |