Skip to content

Commit

Permalink
mlxsw: spectrum: Allow setting maximum rate for a TC
Browse files Browse the repository at this point in the history
Allow a user to set maximum rate for a particular TC using DCB ops.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ido Schimmel authored and David S. Miller committed Apr 6, 2016
1 parent 8e8dfe9 commit cc7cf51
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
6 changes: 3 additions & 3 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -1513,9 +1513,9 @@ int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
}

static int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
enum mlxsw_reg_qeec_hr hr, u8 index,
u8 next_index, u32 maxrate)
int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
enum mlxsw_reg_qeec_hr hr, u8 index,
u8 next_index, u32 maxrate)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
char qeec_pl[MLXSW_REG_QEEC_LEN];
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ struct mlxsw_sp_port {
} vport;
struct {
struct ieee_ets *ets;
struct ieee_maxrate *maxrate;
} dcb;
/* 802.1Q bridge VLANs */
unsigned long *active_vlans;
Expand Down Expand Up @@ -280,6 +281,9 @@ int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port,
u8 switch_prio, u8 tclass);
int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
u8 *prio_tc);
int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
enum mlxsw_reg_qeec_hr hr, u8 index,
u8 next_index, u32 maxrate);

#ifdef CONFIG_MLXSW_SPECTRUM_DCB

Expand Down
70 changes: 70 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,51 @@ static int mlxsw_sp_dcbnl_ieee_setets(struct net_device *dev,
return 0;
}

static int mlxsw_sp_dcbnl_ieee_getmaxrate(struct net_device *dev,
struct ieee_maxrate *maxrate)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);

memcpy(maxrate, mlxsw_sp_port->dcb.maxrate, sizeof(*maxrate));

return 0;
}

static int mlxsw_sp_dcbnl_ieee_setmaxrate(struct net_device *dev,
struct ieee_maxrate *maxrate)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
struct ieee_maxrate *my_maxrate = mlxsw_sp_port->dcb.maxrate;
int err, i;

for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
MLXSW_REG_QEEC_HIERARCY_SUBGROUP,
i, 0,
maxrate->tc_maxrate[i]);
if (err) {
netdev_err(dev, "Failed to set maxrate for TC %d\n", i);
goto err_port_ets_maxrate_set;
}
}

memcpy(mlxsw_sp_port->dcb.maxrate, maxrate, sizeof(*maxrate));

return 0;

err_port_ets_maxrate_set:
for (i--; i >= 0; i--)
mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
MLXSW_REG_QEEC_HIERARCY_SUBGROUP,
i, 0, my_maxrate->tc_maxrate[i]);
return err;
}

static const struct dcbnl_rtnl_ops mlxsw_sp_dcbnl_ops = {
.ieee_getets = mlxsw_sp_dcbnl_ieee_getets,
.ieee_setets = mlxsw_sp_dcbnl_ieee_setets,
.ieee_getmaxrate = mlxsw_sp_dcbnl_ieee_getmaxrate,
.ieee_setmaxrate = mlxsw_sp_dcbnl_ieee_setmaxrate,

.getdcbx = mlxsw_sp_dcbnl_getdcbx,
.setdcbx = mlxsw_sp_dcbnl_setdcbx,
Expand All @@ -275,20 +317,48 @@ static void mlxsw_sp_port_ets_fini(struct mlxsw_sp_port *mlxsw_sp_port)
kfree(mlxsw_sp_port->dcb.ets);
}

static int mlxsw_sp_port_maxrate_init(struct mlxsw_sp_port *mlxsw_sp_port)
{
int i;

mlxsw_sp_port->dcb.maxrate = kmalloc(sizeof(*mlxsw_sp_port->dcb.maxrate),
GFP_KERNEL);
if (!mlxsw_sp_port->dcb.maxrate)
return -ENOMEM;

for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
mlxsw_sp_port->dcb.maxrate->tc_maxrate[i] = MLXSW_REG_QEEC_MAS_DIS;

return 0;
}

static void mlxsw_sp_port_maxrate_fini(struct mlxsw_sp_port *mlxsw_sp_port)
{
kfree(mlxsw_sp_port->dcb.maxrate);
}

int mlxsw_sp_port_dcb_init(struct mlxsw_sp_port *mlxsw_sp_port)
{
int err;

err = mlxsw_sp_port_ets_init(mlxsw_sp_port);
if (err)
return err;
err = mlxsw_sp_port_maxrate_init(mlxsw_sp_port);
if (err)
goto err_port_maxrate_init;

mlxsw_sp_port->dev->dcbnl_ops = &mlxsw_sp_dcbnl_ops;

return 0;

err_port_maxrate_init:
mlxsw_sp_port_ets_fini(mlxsw_sp_port);
return err;
}

void mlxsw_sp_port_dcb_fini(struct mlxsw_sp_port *mlxsw_sp_port)
{
mlxsw_sp_port_maxrate_fini(mlxsw_sp_port);
mlxsw_sp_port_ets_fini(mlxsw_sp_port);
}

0 comments on commit cc7cf51

Please sign in to comment.