aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch
diff options
context:
space:
mode:
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.patch378
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;
-+}