diff options
Diffstat (limited to 'target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch | 378 |
1 files changed, 0 insertions, 378 deletions
diff --git a/target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch b/target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch deleted file mode 100644 index e516e1d5b6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch +++ /dev/null @@ -1,378 +0,0 @@ -From 6ee2331a3a5627b062daf76aa5ed9f64fbbfa303 Mon Sep 17 00:00:00 2001 -From: Po Liu <po.liu@nxp.com> -Date: Fri, 15 Nov 2019 03:33:33 +0000 -Subject: [PATCH] enetc: Configure the Time-Aware Scheduler via tc-taprio - offload - -ENETC supports in hardware for time-based egress shaping according -to IEEE 802.1Qbv. This patch implement the Qbv enablement by the -hardware offload method qdisc tc-taprio method. -Also update cbdr writeback to up level since control bd ring may -writeback data to control bd ring. - -Signed-off-by: Po Liu <Po.Liu@nxp.com> -Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> -Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - drivers/net/ethernet/freescale/enetc/Kconfig | 10 ++ - drivers/net/ethernet/freescale/enetc/Makefile | 2 + - drivers/net/ethernet/freescale/enetc/enetc.c | 19 ++- - drivers/net/ethernet/freescale/enetc/enetc.h | 7 ++ - drivers/net/ethernet/freescale/enetc/enetc_cbdr.c | 5 +- - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 84 ++++++++++--- - drivers/net/ethernet/freescale/enetc/enetc_qos.c | 138 ++++++++++++++++++++++ - 7 files changed, 243 insertions(+), 22 deletions(-) - create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_qos.c - ---- a/drivers/net/ethernet/freescale/enetc/Kconfig -+++ b/drivers/net/ethernet/freescale/enetc/Kconfig -@@ -50,3 +50,13 @@ config FSL_ENETC_HW_TIMESTAMPING - allocation has not been supported and it is too expensive to use - extended RX BDs if timestamping is not used, this option enables - extended RX BDs in order to support hardware timestamping. -+ -+config FSL_ENETC_QOS -+ bool "ENETC hardware Time-sensitive Network support" -+ depends on (FSL_ENETC || FSL_ENETC_VF) && NET_SCH_TAPRIO -+ help -+ There are Time-Sensitive Network(TSN) capabilities(802.1Qbv/802.1Qci -+ /802.1Qbu etc.) supported by ENETC. These TSN capabilities can be set -+ enable/disable from user space via Qos commands(tc). In the kernel -+ side, it can be loaded by Qos driver. Currently, it is only support -+ taprio(802.1Qbv). ---- a/drivers/net/ethernet/freescale/enetc/Makefile -+++ b/drivers/net/ethernet/freescale/enetc/Makefile -@@ -5,9 +5,11 @@ common-objs := enetc.o enetc_cbdr.o enet - obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o - fsl-enetc-y := enetc_pf.o enetc_mdio.o $(common-objs) - fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o -+fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o - - obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o - fsl-enetc-vf-y := enetc_vf.o $(common-objs) -+fsl-enetc-vf-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o - - obj-$(CONFIG_FSL_ENETC_MDIO) += fsl-enetc-mdio.o - fsl-enetc-mdio-y := enetc_pci_mdio.o enetc_mdio.o ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -1419,8 +1419,7 @@ int enetc_close(struct net_device *ndev) - return 0; - } - --int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, -- void *type_data) -+int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data) - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct tc_mqprio_qopt *mqprio = type_data; -@@ -1428,9 +1427,6 @@ int enetc_setup_tc(struct net_device *nd - u8 num_tc; - int i; - -- if (type != TC_SETUP_QDISC_MQPRIO) -- return -EOPNOTSUPP; -- - mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; - num_tc = mqprio->num_tc; - -@@ -1475,6 +1471,19 @@ int enetc_setup_tc(struct net_device *nd - return 0; - } - -+int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, -+ void *type_data) -+{ -+ switch (type) { -+ case TC_SETUP_QDISC_MQPRIO: -+ return enetc_setup_tc_mqprio(ndev, type_data); -+ case TC_SETUP_QDISC_TAPRIO: -+ return enetc_setup_tc_taprio(ndev, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ - struct net_device_stats *enetc_get_stats(struct net_device *ndev) - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); ---- a/drivers/net/ethernet/freescale/enetc/enetc.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc.h -@@ -249,3 +249,10 @@ int enetc_set_fs_entry(struct enetc_si * - void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes); - int enetc_get_rss_table(struct enetc_si *si, u32 *table, int count); - int enetc_set_rss_table(struct enetc_si *si, const u32 *table, int count); -+int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd); -+ -+#ifdef CONFIG_FSL_ENETC_QOS -+int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data); -+#else -+#define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP -+#endif ---- a/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c -@@ -32,7 +32,7 @@ static int enetc_cbd_unused(struct enetc - r->bd_count; - } - --static int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd) -+int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd) - { - struct enetc_cbdr *ring = &si->cbd_ring; - int timeout = ENETC_CBDR_TIMEOUT; -@@ -66,6 +66,9 @@ static int enetc_send_cmd(struct enetc_s - if (!timeout) - return -EBUSY; - -+ /* CBD may writeback data, feedback up level */ -+ *cbd = *dest_cbd; -+ - enetc_clean_cbdr(si); - - return 0; ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -18,6 +18,7 @@ - #define ENETC_SICTR0 0x18 - #define ENETC_SICTR1 0x1c - #define ENETC_SIPCAPR0 0x20 -+#define ENETC_SIPCAPR0_QBV BIT(4) - #define ENETC_SIPCAPR0_RSS BIT(8) - #define ENETC_SIPCAPR1 0x24 - #define ENETC_SITGTGR 0x30 -@@ -446,22 +447,6 @@ union enetc_rx_bd { - #define EMETC_MAC_ADDR_FILT_RES 3 /* # of reserved entries at the beginning */ - #define ENETC_MAX_NUM_VFS 2 - --struct enetc_cbd { -- union { -- struct { -- __le32 addr[2]; -- __le32 opt[4]; -- }; -- __le32 data[6]; -- }; -- __le16 index; -- __le16 length; -- u8 cmd; -- u8 cls; -- u8 _res; -- u8 status_flags; --}; -- - #define ENETC_CBD_FLAGS_SF BIT(7) /* short format */ - #define ENETC_CBD_STATUS_MASK 0xf - -@@ -560,3 +545,70 @@ static inline void enetc_set_bdr_prio(st - val |= ENETC_TBMR_SET_PRIO(prio); - enetc_txbdr_wr(hw, bdr_idx, ENETC_TBMR, val); - } -+ -+enum bdcr_cmd_class { -+ BDCR_CMD_UNSPEC = 0, -+ BDCR_CMD_MAC_FILTER, -+ BDCR_CMD_VLAN_FILTER, -+ BDCR_CMD_RSS, -+ BDCR_CMD_RFS, -+ BDCR_CMD_PORT_GCL, -+ BDCR_CMD_RECV_CLASSIFIER, -+ __BDCR_CMD_MAX_LEN, -+ BDCR_CMD_MAX_LEN = __BDCR_CMD_MAX_LEN - 1, -+}; -+ -+/* class 5, command 0 */ -+struct tgs_gcl_conf { -+ u8 atc; /* init gate value */ -+ u8 res[7]; -+ struct { -+ u8 res1[4]; -+ __le16 acl_len; -+ u8 res2[2]; -+ }; -+}; -+ -+/* gate control list entry */ -+struct gce { -+ __le32 period; -+ u8 gate; -+ u8 res[3]; -+}; -+ -+/* tgs_gcl_conf address point to this data space */ -+struct tgs_gcl_data { -+ __le32 btl; -+ __le32 bth; -+ __le32 ct; -+ __le32 cte; -+ struct gce entry[0]; -+}; -+ -+struct enetc_cbd { -+ union{ -+ struct { -+ __le32 addr[2]; -+ union { -+ __le32 opt[4]; -+ struct tgs_gcl_conf gcl_conf; -+ }; -+ }; /* Long format */ -+ __le32 data[6]; -+ }; -+ __le16 index; -+ __le16 length; -+ u8 cmd; -+ u8 cls; -+ u8 _res; -+ u8 status_flags; -+}; -+ -+/* port time gating control register */ -+#define ENETC_QBV_PTGCR_OFFSET 0x11a00 -+#define ENETC_QBV_TGE BIT(31) -+#define ENETC_QBV_TGPE BIT(30) -+ -+/* Port time gating capability register */ -+#define ENETC_QBV_PTGCAPR_OFFSET 0x11a08 -+#define ENETC_QBV_MAX_GCL_LEN_MASK GENMASK(15, 0) ---- /dev/null -+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c -@@ -0,0 +1,138 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* Copyright 2019 NXP */ -+ -+#include "enetc.h" -+ -+#include <net/pkt_sched.h> -+ -+static u16 enetc_get_max_gcl_len(struct enetc_hw *hw) -+{ -+ return enetc_rd(hw, ENETC_QBV_PTGCAPR_OFFSET) -+ & ENETC_QBV_MAX_GCL_LEN_MASK; -+} -+ -+static int enetc_setup_taprio(struct net_device *ndev, -+ struct tc_taprio_qopt_offload *admin_conf) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ struct enetc_cbd cbd = {.cmd = 0}; -+ struct tgs_gcl_conf *gcl_config; -+ struct tgs_gcl_data *gcl_data; -+ struct gce *gce; -+ dma_addr_t dma; -+ u16 data_size; -+ u16 gcl_len; -+ u32 tge; -+ int err; -+ int i; -+ -+ if (admin_conf->num_entries > enetc_get_max_gcl_len(&priv->si->hw)) -+ return -EINVAL; -+ gcl_len = admin_conf->num_entries; -+ -+ tge = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET); -+ if (!admin_conf->enable) { -+ enetc_wr(&priv->si->hw, -+ ENETC_QBV_PTGCR_OFFSET, -+ tge & (~ENETC_QBV_TGE)); -+ return 0; -+ } -+ -+ if (admin_conf->cycle_time > U32_MAX || -+ admin_conf->cycle_time_extension > U32_MAX) -+ return -EINVAL; -+ -+ /* Configure the (administrative) gate control list using the -+ * control BD descriptor. -+ */ -+ gcl_config = &cbd.gcl_conf; -+ -+ data_size = struct_size(gcl_data, entry, gcl_len); -+ gcl_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!gcl_data) -+ return -ENOMEM; -+ -+ gce = (struct gce *)(gcl_data + 1); -+ -+ /* Set all gates open as default */ -+ gcl_config->atc = 0xff; -+ gcl_config->acl_len = cpu_to_le16(gcl_len); -+ -+ if (!admin_conf->base_time) { -+ gcl_data->btl = -+ cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR0)); -+ gcl_data->bth = -+ cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR1)); -+ } else { -+ gcl_data->btl = -+ cpu_to_le32(lower_32_bits(admin_conf->base_time)); -+ gcl_data->bth = -+ cpu_to_le32(upper_32_bits(admin_conf->base_time)); -+ } -+ -+ gcl_data->ct = cpu_to_le32(admin_conf->cycle_time); -+ gcl_data->cte = cpu_to_le32(admin_conf->cycle_time_extension); -+ -+ for (i = 0; i < gcl_len; i++) { -+ struct tc_taprio_sched_entry *temp_entry; -+ struct gce *temp_gce = gce + i; -+ -+ temp_entry = &admin_conf->entries[i]; -+ -+ temp_gce->gate = (u8)temp_entry->gate_mask; -+ temp_gce->period = cpu_to_le32(temp_entry->interval); -+ } -+ -+ cbd.length = cpu_to_le16(data_size); -+ cbd.status_flags = 0; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, gcl_data, -+ data_size, DMA_TO_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(gcl_data); -+ return -ENOMEM; -+ } -+ -+ cbd.addr[0] = lower_32_bits(dma); -+ cbd.addr[1] = upper_32_bits(dma); -+ cbd.cls = BDCR_CMD_PORT_GCL; -+ cbd.status_flags = 0; -+ -+ enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET, -+ tge | ENETC_QBV_TGE); -+ -+ err = enetc_send_cmd(priv->si, &cbd); -+ if (err) -+ enetc_wr(&priv->si->hw, -+ ENETC_QBV_PTGCR_OFFSET, -+ tge & (~ENETC_QBV_TGE)); -+ -+ dma_unmap_single(&priv->si->pdev->dev, dma, data_size, DMA_TO_DEVICE); -+ kfree(gcl_data); -+ -+ return err; -+} -+ -+int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data) -+{ -+ struct tc_taprio_qopt_offload *taprio = type_data; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ int err; -+ int i; -+ -+ for (i = 0; i < priv->num_tx_rings; i++) -+ enetc_set_bdr_prio(&priv->si->hw, -+ priv->tx_ring[i]->index, -+ taprio->enable ? i : 0); -+ -+ err = enetc_setup_taprio(ndev, taprio); -+ -+ if (err) -+ for (i = 0; i < priv->num_tx_rings; i++) -+ enetc_set_bdr_prio(&priv->si->hw, -+ priv->tx_ring[i]->index, -+ taprio->enable ? 0 : i); -+ -+ return err; -+} |