diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 33 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 7 |
2 files changed, 35 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 9c063d6122b3..591740b06043 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c @@ -505,6 +505,7 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) mlx4_free_cmd_mailbox(dev, outmailbox); 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, 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, struct mlx4_slave_state *slave_st = &master->slave_state[slave]; struct mlx4_set_port_rqp_calc_context *qpn_context; struct mlx4_set_port_general_context *gen_context; + struct mlx4_roce_gid_entry *gid_entry; int reset_qkey_viols; int port; int is_eth; @@ -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 */ if (is_eth) { 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", slave); return -EINVAL; @@ -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]); 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, 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) } 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); 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 } 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); diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index fbe6cda00ba7..e4853650679d 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -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); __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, u32 max_range_qpn); |