Commit 9cd59352 authored by Jack Morgenstein's avatar Jack Morgenstein Committed by David S. Miller

mlx4_core: For RoCE, allow slaves to set the GID entry at that slave's index

For IB transport, the host determines the slave GIDs. For ETH (RoCE),
however, the slave's GID is determined by the IP address that the slave
itself assigns to the ETH device used by RoCE.

In this case, the slave must be able to write its GIDs to the HCA gid table
(at the GID indices that slave "owns").

This commit adds processing for the SET_PORT_GID_TABLE opcode modifier
for the SET_PORT command wrapper (so that slaves may modify their GIDS
for RoCE).
Signed-off-by: default avatarJack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6ee51a4e
...@@ -505,6 +505,7 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) ...@@ -505,6 +505,7 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
mlx4_free_cmd_mailbox(dev, outmailbox); mlx4_free_cmd_mailbox(dev, outmailbox);
return err; return err;
} }
static struct mlx4_roce_gid_entry zgid_entry;
static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
u8 op_mod, struct mlx4_cmd_mailbox *inbox) u8 op_mod, struct mlx4_cmd_mailbox *inbox)
...@@ -515,6 +516,7 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, ...@@ -515,6 +516,7 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
struct mlx4_slave_state *slave_st = &master->slave_state[slave]; struct mlx4_slave_state *slave_st = &master->slave_state[slave];
struct mlx4_set_port_rqp_calc_context *qpn_context; struct mlx4_set_port_rqp_calc_context *qpn_context;
struct mlx4_set_port_general_context *gen_context; struct mlx4_set_port_general_context *gen_context;
struct mlx4_roce_gid_entry *gid_entry;
int reset_qkey_viols; int reset_qkey_viols;
int port; int port;
int is_eth; int is_eth;
...@@ -535,7 +537,8 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, ...@@ -535,7 +537,8 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
/* Slaves cannot perform SET_PORT operations except changing MTU */ /* Slaves cannot perform SET_PORT operations except changing MTU */
if (is_eth) { if (is_eth) {
if (slave != dev->caps.function && if (slave != dev->caps.function &&
in_modifier != MLX4_SET_PORT_GENERAL) { in_modifier != MLX4_SET_PORT_GENERAL &&
in_modifier != MLX4_SET_PORT_GID_TABLE) {
mlx4_warn(dev, "denying SET_PORT for slave:%d\n", mlx4_warn(dev, "denying SET_PORT for slave:%d\n",
slave); slave);
return -EINVAL; return -EINVAL;
...@@ -581,6 +584,28 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, ...@@ -581,6 +584,28 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
gen_context->mtu = cpu_to_be16(master->max_mtu[port]); gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
break; break;
case MLX4_SET_PORT_GID_TABLE:
gid_entry = (struct mlx4_roce_gid_entry *)(inbox->buf);
/* check that do not have duplicates */
if (memcmp(gid_entry->raw, zgid_entry.raw, 16)) {
for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) {
if (slave != i &&
!memcmp(gid_entry->raw, priv->roce_gids[port - 1][i].raw, 16)) {
mlx4_warn(dev, "requested gid entry for slave:%d "
"is a duplicate of slave %d\n",
slave, i);
return -EEXIST;
}
}
}
/* insert slave GID at proper index */
memcpy(priv->roce_gids[port - 1][slave].raw, gid_entry->raw, 16);
/* rewrite roce port gids table to FW */
for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) {
memcpy(gid_entry->raw, priv->roce_gids[port - 1][i].raw, 16);
gid_entry++;
}
break;
} }
return mlx4_cmd(dev, inbox->dma, in_mod, op_mod, return mlx4_cmd(dev, inbox->dma, in_mod, op_mod,
MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
...@@ -928,7 +953,8 @@ void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap) ...@@ -928,7 +953,8 @@ void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap)
} }
EXPORT_SYMBOL(mlx4_set_stats_bitmap); EXPORT_SYMBOL(mlx4_set_stats_bitmap);
int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, int *slave_id) int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
int *slave_id)
{ {
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
int i, found_ix = -1; int i, found_ix = -1;
...@@ -950,7 +976,8 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, int *s ...@@ -950,7 +976,8 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, int *s
} }
EXPORT_SYMBOL(mlx4_get_slave_from_roce_gid); EXPORT_SYMBOL(mlx4_get_slave_from_roce_gid);
int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id, u8 *gid) int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id,
u8 *gid)
{ {
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
......
...@@ -1184,8 +1184,11 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, u8 port, int ...@@ -1184,8 +1184,11 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, u8 port, int
void mlx4_put_slave_node_guid(struct mlx4_dev *dev, int slave, __be64 guid); void mlx4_put_slave_node_guid(struct mlx4_dev *dev, int slave, __be64 guid);
__be64 mlx4_get_slave_node_guid(struct mlx4_dev *dev, int slave); __be64 mlx4_get_slave_node_guid(struct mlx4_dev *dev, int slave);
int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, int *slave_id);
int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id, u8 *gid); int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
int *slave_id);
int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id,
u8 *gid);
int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn, int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
u32 max_range_qpn); u32 max_range_qpn);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment