Skip to content

Commit 8127224

Browse files
ikhorndavem330
authored andcommitted
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 <[email protected]> Signed-off-by: Murali Karicheri <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ec008fa commit 8127224

File tree

7 files changed

+689
-3
lines changed

7 files changed

+689
-3
lines changed

drivers/net/ethernet/ti/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@ config TI_K3_AM65_CPTS
123123
protocol, Ethernet Enhanced Scheduled Traffic Operations (CPTS_ESTFn)
124124
and PCIe Subsystem Precision Time Measurement (PTM).
125125

126+
config TI_AM65_CPSW_TAS
127+
bool "Enable TAS offload in AM65 CPSW"
128+
depends on TI_K3_AM65_CPSW_NUSS && NET_SCH_TAPRIO && TI_K3_AM65_CPTS
129+
help
130+
Say y here to support Time Aware Shaper(TAS) offload in AM65 CPSW.
131+
AM65 CPSW hardware supports Enhanced Scheduled Traffic (EST)
132+
defined in IEEE 802.1Q 2018. The EST scheduler runs on CPTS and the
133+
TAS/EST schedule is updated in the Fetch RAM memory of the CPSW.
134+
126135
config TI_KEYSTONE_NETCP
127136
tristate "TI Keystone NETCP Core Support"
128137
select TI_DAVINCI_MDIO

drivers/net/ethernet/ti/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ obj-$(CONFIG_TI_KEYSTONE_NETCP_ETHSS) += keystone_netcp_ethss.o
2525
keystone_netcp_ethss-y := netcp_ethss.o netcp_sgmii.o netcp_xgbepcsr.o cpsw_ale.o
2626

2727
obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o
28-
ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o
28+
ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o am65-cpsw-qos.o
2929
obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o

drivers/net/ethernet/ti/am65-cpsw-ethtool.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,9 +730,17 @@ static u32 am65_cpsw_get_ethtool_priv_flags(struct net_device *ndev)
730730
static int am65_cpsw_set_ethtool_priv_flags(struct net_device *ndev, u32 flags)
731731
{
732732
struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
733+
int rrobin;
733734

734-
common->pf_p0_rx_ptype_rrobin =
735-
!!(flags & AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN);
735+
rrobin = !!(flags & AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN);
736+
737+
if (common->est_enabled && rrobin) {
738+
netdev_err(ndev,
739+
"p0-rx-ptype-rrobin flag conflicts with QOS\n");
740+
return -EINVAL;
741+
}
742+
743+
common->pf_p0_rx_ptype_rrobin = rrobin;
736744
am65_cpsw_nuss_set_p0_ptype(common);
737745

738746
return 0;

drivers/net/ethernet/ti/am65-cpsw-nuss.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@
3737
#define AM65_CPSW_XGMII_BASE 0x2100
3838
#define AM65_CPSW_CPSW_NU_BASE 0x20000
3939
#define AM65_CPSW_NU_PORTS_BASE 0x1000
40+
#define AM65_CPSW_NU_FRAM_BASE 0x12000
4041
#define AM65_CPSW_NU_STATS_BASE 0x1a000
4142
#define AM65_CPSW_NU_ALE_BASE 0x1e000
4243
#define AM65_CPSW_NU_CPTS_BASE 0x1d000
4344

4445
#define AM65_CPSW_NU_PORTS_OFFSET 0x1000
4546
#define AM65_CPSW_NU_STATS_PORT_OFFSET 0x200
47+
#define AM65_CPSW_NU_FRAM_PORT_OFFSET 0x200
4648

4749
#define AM65_CPSW_MAX_PORTS 8
4850

@@ -188,9 +190,11 @@ void am65_cpsw_nuss_adjust_link(struct net_device *ndev)
188190
cpsw_ale_control_set(common->ale, port->port_id,
189191
ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
190192

193+
am65_cpsw_qos_link_up(ndev, phy->speed);
191194
netif_tx_wake_all_queues(ndev);
192195
} else {
193196
int tmo;
197+
194198
/* disable forwarding */
195199
cpsw_ale_control_set(common->ale, port->port_id,
196200
ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
@@ -204,6 +208,7 @@ void am65_cpsw_nuss_adjust_link(struct net_device *ndev)
204208

205209
cpsw_sl_ctl_reset(port->slave.mac_sl);
206210

211+
am65_cpsw_qos_link_down(ndev);
207212
netif_tx_stop_all_queues(ndev);
208213
}
209214

@@ -1378,6 +1383,7 @@ static const struct net_device_ops am65_cpsw_nuss_netdev_ops_2g = {
13781383
.ndo_vlan_rx_kill_vid = am65_cpsw_nuss_ndo_slave_kill_vid,
13791384
.ndo_do_ioctl = am65_cpsw_nuss_ndo_slave_ioctl,
13801385
.ndo_set_features = am65_cpsw_nuss_ndo_slave_set_features,
1386+
.ndo_setup_tc = am65_cpsw_qos_ndo_setup_tc,
13811387
};
13821388

13831389
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)
17391745
port->stat_base = common->cpsw_base + AM65_CPSW_NU_STATS_BASE +
17401746
(AM65_CPSW_NU_STATS_PORT_OFFSET * port_id);
17411747
port->name = of_get_property(port_np, "label", NULL);
1748+
port->fetch_ram_base =
1749+
common->cpsw_base + AM65_CPSW_NU_FRAM_BASE +
1750+
(AM65_CPSW_NU_FRAM_PORT_OFFSET * (port_id - 1));
17421751

17431752
port->disabled = !of_device_is_available(port_np);
17441753
if (port->disabled)

drivers/net/ethernet/ti/am65-cpsw-nuss.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#include <linux/kernel.h>
1010
#include <linux/module.h>
1111
#include <linux/netdevice.h>
12+
#include <linux/phy.h>
1213
#include <linux/platform_device.h>
14+
#include "am65-cpsw-qos.h"
1315

1416
struct am65_cpts;
1517

@@ -38,10 +40,12 @@ struct am65_cpsw_port {
3840
u32 port_id;
3941
void __iomem *port_base;
4042
void __iomem *stat_base;
43+
void __iomem *fetch_ram_base;
4144
bool disabled;
4245
struct am65_cpsw_slave_data slave;
4346
bool tx_ts_enabled;
4447
bool rx_ts_enabled;
48+
struct am65_cpsw_qos qos;
4549
};
4650

4751
struct am65_cpsw_host {
@@ -104,6 +108,7 @@ struct am65_cpsw_common {
104108
u32 cpsw_ver;
105109
bool pf_p0_rx_ptype_rrobin;
106110
struct am65_cpts *cpts;
111+
int est_enabled;
107112
};
108113

109114
struct am65_cpsw_ndev_stats {

0 commit comments

Comments
 (0)