diff options
| -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 | ||||
| -rw-r--r-- | include/linux/mlx4/device.h | 1 |
7 files changed, 192 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; |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index e4853650679d..86e02e5c2c77 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #define MIN_MSIX_P_PORT 5 | 49 | #define MIN_MSIX_P_PORT 5 |
| 50 | 50 | ||
| 51 | #define MLX4_ROCE_MAX_GIDS 128 | 51 | #define MLX4_ROCE_MAX_GIDS 128 |
| 52 | #define MLX4_ROCE_PF_GIDS 16 | ||
| 52 | 53 | ||
| 53 | enum { | 54 | enum { |
| 54 | MLX4_FLAG_MSI_X = 1 << 0, | 55 | MLX4_FLAG_MSI_X = 1 << 0, |
