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 | |
| 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>
| -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; | ||
