Skip to content

Commit 90183b9

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum: Initialize egress scheduling
Before introducing support for DCB ops we should first make sure we initialize the relevant parts in the device correctly. Specifically, the egress scheduling. The device supports a superset of the 802.1Qaz standard with 4 hierarchy levels that can be linked to each other in multiple ways and with different transmission selection algorithms (TSA) employed between them. However, since we only intend to support the 802.1Qaz standard we flatten the hierarchies and let the user configure via DCB ops the TSA and max rate shaper at the subgroup hierarchy (see figure below) and the mapping between switch priority to traffic class. By default, all switch priorities are mapped to traffic class 0, strict priority is employed and max shaper is disabled. Default configuration: switch priority 0 ... switch priority 7 + + | | +----------------------------------+ | +--v--+ +-----+ Traffic Class | | | | Hierarchy | TC0 | ... | TC7 | | | | | +--+--+ +--+--+ | | +--v--+ +--v--+ Subgroup | SG0 | | SG7 | Hierarchy | | | | +-----+ +-----+ | TSA | | TSA | +-----+ ... +-----+ | MAX | | MAX | +--+--+ +--+--+ | | +---------------+----------------+ | +--v--+ Group | | Hierarchy | GR0 | | | +--+--+ | +--v--+ Port | | Hierarchy | PR0 | | | +-----+ 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>
1 parent 2c63a55 commit 90183b9

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <linux/jiffies.h>
5050
#include <linux/bitops.h>
5151
#include <linux/list.h>
52+
#include <linux/dcbnl.h>
5253
#include <net/devlink.h>
5354
#include <net/switchdev.h>
5455
#include <generated/utsrelease.h>
@@ -1464,6 +1465,108 @@ mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 width)
14641465
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
14651466
}
14661467

1468+
static int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
1469+
enum mlxsw_reg_qeec_hr hr, u8 index,
1470+
u8 next_index, bool dwrr, u8 dwrr_weight)
1471+
{
1472+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1473+
char qeec_pl[MLXSW_REG_QEEC_LEN];
1474+
1475+
mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
1476+
next_index);
1477+
mlxsw_reg_qeec_de_set(qeec_pl, true);
1478+
mlxsw_reg_qeec_dwrr_set(qeec_pl, dwrr);
1479+
mlxsw_reg_qeec_dwrr_weight_set(qeec_pl, dwrr_weight);
1480+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
1481+
}
1482+
1483+
static int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
1484+
enum mlxsw_reg_qeec_hr hr, u8 index,
1485+
u8 next_index, u32 maxrate)
1486+
{
1487+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1488+
char qeec_pl[MLXSW_REG_QEEC_LEN];
1489+
1490+
mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
1491+
next_index);
1492+
mlxsw_reg_qeec_mase_set(qeec_pl, true);
1493+
mlxsw_reg_qeec_max_shaper_rate_set(qeec_pl, maxrate);
1494+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
1495+
}
1496+
1497+
static int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port,
1498+
u8 switch_prio, u8 tclass)
1499+
{
1500+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1501+
char qtct_pl[MLXSW_REG_QTCT_LEN];
1502+
1503+
mlxsw_reg_qtct_pack(qtct_pl, mlxsw_sp_port->local_port, switch_prio,
1504+
tclass);
1505+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtct), qtct_pl);
1506+
}
1507+
1508+
static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
1509+
{
1510+
int err, i;
1511+
1512+
/* Setup the elements hierarcy, so that each TC is linked to
1513+
* one subgroup, which are all member in the same group.
1514+
*/
1515+
err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
1516+
MLXSW_REG_QEEC_HIERARCY_GROUP, 0, 0, false,
1517+
0);
1518+
if (err)
1519+
return err;
1520+
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1521+
err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
1522+
MLXSW_REG_QEEC_HIERARCY_SUBGROUP, i,
1523+
0, false, 0);
1524+
if (err)
1525+
return err;
1526+
}
1527+
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1528+
err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
1529+
MLXSW_REG_QEEC_HIERARCY_TC, i, i,
1530+
false, 0);
1531+
if (err)
1532+
return err;
1533+
}
1534+
1535+
/* Make sure the max shaper is disabled in all hierarcies that
1536+
* support it.
1537+
*/
1538+
err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
1539+
MLXSW_REG_QEEC_HIERARCY_PORT, 0, 0,
1540+
MLXSW_REG_QEEC_MAS_DIS);
1541+
if (err)
1542+
return err;
1543+
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1544+
err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
1545+
MLXSW_REG_QEEC_HIERARCY_SUBGROUP,
1546+
i, 0,
1547+
MLXSW_REG_QEEC_MAS_DIS);
1548+
if (err)
1549+
return err;
1550+
}
1551+
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1552+
err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
1553+
MLXSW_REG_QEEC_HIERARCY_TC,
1554+
i, i,
1555+
MLXSW_REG_QEEC_MAS_DIS);
1556+
if (err)
1557+
return err;
1558+
}
1559+
1560+
/* Map all priorities to traffic class 0. */
1561+
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1562+
err = mlxsw_sp_port_prio_tc_set(mlxsw_sp_port, i, 0);
1563+
if (err)
1564+
return err;
1565+
}
1566+
1567+
return 0;
1568+
}
1569+
14671570
static int __mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
14681571
bool split, u8 module, u8 width)
14691572
{
@@ -1571,6 +1674,13 @@ static int __mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
15711674
goto err_port_buffers_init;
15721675
}
15731676

1677+
err = mlxsw_sp_port_ets_init(mlxsw_sp_port);
1678+
if (err) {
1679+
dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize ETS\n",
1680+
mlxsw_sp_port->local_port);
1681+
goto err_port_ets_init;
1682+
}
1683+
15741684
mlxsw_sp_port_switchdev_init(mlxsw_sp_port);
15751685
err = register_netdev(dev);
15761686
if (err) {
@@ -1591,6 +1701,7 @@ static int __mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
15911701
err_port_vlan_init:
15921702
unregister_netdev(dev);
15931703
err_register_netdev:
1704+
err_port_ets_init:
15941705
err_port_buffers_init:
15951706
err_port_admin_status_set:
15961707
err_port_mtu_set:

0 commit comments

Comments
 (0)