diff options
author | Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> | 2020-05-13 15:26:15 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-05-15 02:33:30 +0200 |
commit | 8127224c2708aa1558e2be7bbd1b7e9b07860de6 (patch) | |
tree | 58115fea5ce3d7953e0abaa19659355235b7d58d /drivers/net/ethernet/ti/am65-cpsw-nuss.c | |
parent | ethernet: ti: am65-cpts: add routines to support taprio offload (diff) | |
download | linux-8127224c2708aa1558e2be7bbd1b7e9b07860de6.tar.xz linux-8127224c2708aa1558e2be7bbd1b7e9b07860de6.zip |
ethernet: ti: am65-cpsw-qos: add TAPRIO offload support
AM65 CPSW h/w supports Enhanced Scheduled Traffic (EST – defined
in P802.1Qbv/D2.2 that later got included in IEEE 802.1Q-2018)
configuration. EST allows express queue traffic to be scheduled
(placed) on the wire at specific repeatable time intervals. In
Linux kernel, EST configuration is done through tc command and
the taprio scheduler in the net core implements a software only
scheduler (SCH_TAPRIO). If the NIC is capable of EST configuration,
user indicate "flag 2" in the command which is then parsed by
taprio scheduler in net core and indicate that the command is to
be offloaded to h/w. taprio then offloads the command to the
driver by calling ndo_setup_tc() ndo ops. This patch implements
ndo_setup_tc() to offload EST configuration to CPSW h/w.
Currently driver supports only SetGateStates operation. EST
operates on a repeating time interval generated by the CPTS EST
function generator. Each Ethernet port has a global EST fetch
RAM that can be configured as 2 buffers, each of 64 locations
or one large buffer of 128 locations. In 2 buffer configuration,
a ping pong mechanism is used to hold the active schedule (oper)
in one buffer and new (admin) command in the other. Each 22-bit
fetch command consists of a 14-bit fetch count (14 MSB’s) and an
8-bit priority fetch allow (8 LSB’s) that will be applied for the
fetch count time in wireside clocks. Driver process each of the
sched-entry in the offload command and update the fetch RAM.
Driver configures duration in sched-entry into the fetch count
and Gate mask into the priority fetch bits of the RAM. Then
configures the CPTS EST function generator to activate the
schedule. Currently driver supports only 2 buffer configuration
which means driver supports a max cycle time of ~8 msec.
CPSW supports a configurable number of priority queues (up to 8)
and needs to be switched to this mode from the default round
robin mode before EST can be offloaded. User configures
these through ethtool commands (-L for changing number of
queues and --set-priv-flags to disable round robin mode).
Driver doesn't enable EST if pf_p0_rx_ptype_rrobin privat flag
is set. The flag is common for all ports, and so can't be just
overridden by taprio configuration w/o user involvement.
Command fails if pf_p0_rx_ptype_rrobin is already set in the
driver.
Scheds (commands) configuration depends on interface speed so
driver translates the duration to the fetch count based on
link speed. Each schedule can be constructed with several
command entries in fetch RAM depending on interval. For example
if each sched has timer interval < ~130us on 1000 Mb link then
each sched consumes one command and have 1:1 mapping. When
Ethernet link goes down, driver purge the configuration if link
is down for more than 1 second.
The patch allows to update the timer and scheds memory only if it's
really needed, and skip cases required the user to stop timer by
configuring only shceds memory.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti/am65-cpsw-nuss.c')
-rw-r--r-- | drivers/net/ethernet/ti/am65-cpsw-nuss.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index 8cdbb2b9b13a..4a8229864ae4 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -37,12 +37,14 @@ #define AM65_CPSW_XGMII_BASE 0x2100 #define AM65_CPSW_CPSW_NU_BASE 0x20000 #define AM65_CPSW_NU_PORTS_BASE 0x1000 +#define AM65_CPSW_NU_FRAM_BASE 0x12000 #define AM65_CPSW_NU_STATS_BASE 0x1a000 #define AM65_CPSW_NU_ALE_BASE 0x1e000 #define AM65_CPSW_NU_CPTS_BASE 0x1d000 #define AM65_CPSW_NU_PORTS_OFFSET 0x1000 #define AM65_CPSW_NU_STATS_PORT_OFFSET 0x200 +#define AM65_CPSW_NU_FRAM_PORT_OFFSET 0x200 #define AM65_CPSW_MAX_PORTS 8 @@ -188,9 +190,11 @@ void am65_cpsw_nuss_adjust_link(struct net_device *ndev) cpsw_ale_control_set(common->ale, port->port_id, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); + am65_cpsw_qos_link_up(ndev, phy->speed); netif_tx_wake_all_queues(ndev); } else { int tmo; + /* disable forwarding */ cpsw_ale_control_set(common->ale, port->port_id, ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); @@ -204,6 +208,7 @@ void am65_cpsw_nuss_adjust_link(struct net_device *ndev) cpsw_sl_ctl_reset(port->slave.mac_sl); + am65_cpsw_qos_link_down(ndev); netif_tx_stop_all_queues(ndev); } @@ -1378,6 +1383,7 @@ static const struct net_device_ops am65_cpsw_nuss_netdev_ops_2g = { .ndo_vlan_rx_kill_vid = am65_cpsw_nuss_ndo_slave_kill_vid, .ndo_do_ioctl = am65_cpsw_nuss_ndo_slave_ioctl, .ndo_set_features = am65_cpsw_nuss_ndo_slave_set_features, + .ndo_setup_tc = am65_cpsw_qos_ndo_setup_tc, }; static void am65_cpsw_nuss_slave_disable_unused(struct am65_cpsw_port *port) @@ -1739,6 +1745,9 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) port->stat_base = common->cpsw_base + AM65_CPSW_NU_STATS_BASE + (AM65_CPSW_NU_STATS_PORT_OFFSET * port_id); port->name = of_get_property(port_np, "label", NULL); + port->fetch_ram_base = + common->cpsw_base + AM65_CPSW_NU_FRAM_BASE + + (AM65_CPSW_NU_FRAM_PORT_OFFSET * (port_id - 1)); port->disabled = !of_device_is_available(port_np); if (port->disabled) |