aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch231
1 files changed, 0 insertions, 231 deletions
diff --git a/target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch b/target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch
deleted file mode 100644
index 8b59f994b2..0000000000
--- a/target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch
+++ /dev/null
@@ -1,231 +0,0 @@
-From 3426e5e4339f124f00eef8815b56a80481364550 Mon Sep 17 00:00:00 2001
-From: Po Liu <po.liu@nxp.com>
-Date: Mon, 25 Nov 2019 05:56:56 +0000
-Subject: [PATCH] enetc: add support Credit Based Shaper(CBS) for hardware
- offload
-
-The ENETC hardware support the Credit Based Shaper(CBS) which part
-of the IEEE-802.1Qav. The CBS driver was loaded by the sch_cbs
-interface when set in the QOS in the kernel.
-
-Here is an example command to set 20Mbits bandwidth in 1Gbits port
-for taffic class 7:
-
-tc qdisc add dev eth0 root handle 1: mqprio \
- num_tc 8 map 0 1 2 3 4 5 6 7 hw 1
-
-tc qdisc replace dev eth0 parent 1:8 cbs \
- locredit -1470 hicredit 30 \
- sendslope -980000 idleslope 20000 offload 1
-
-Signed-off-by: Po Liu <Po.Liu@nxp.com>
-Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
-Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/freescale/enetc/Kconfig | 4 +-
- drivers/net/ethernet/freescale/enetc/enetc.c | 2 +
- drivers/net/ethernet/freescale/enetc/enetc.h | 2 +
- drivers/net/ethernet/freescale/enetc/enetc_hw.h | 4 +
- drivers/net/ethernet/freescale/enetc/enetc_qos.c | 128 +++++++++++++++++++++++
- 5 files changed, 138 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/freescale/enetc/Kconfig
-+++ b/drivers/net/ethernet/freescale/enetc/Kconfig
-@@ -53,10 +53,10 @@ config FSL_ENETC_HW_TIMESTAMPING
-
- config FSL_ENETC_QOS
- bool "ENETC hardware Time-sensitive Network support"
-- depends on (FSL_ENETC || FSL_ENETC_VF) && NET_SCH_TAPRIO
-+ depends on (FSL_ENETC || FSL_ENETC_VF) && (NET_SCH_TAPRIO || NET_SCH_CBS)
- 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).
-+ taprio(802.1Qbv) and Credit Based Shaper(802.1Qbu).
---- a/drivers/net/ethernet/freescale/enetc/enetc.c
-+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
-@@ -1516,6 +1516,8 @@ int enetc_setup_tc(struct net_device *nd
- return enetc_setup_tc_mqprio(ndev, type_data);
- case TC_SETUP_QDISC_TAPRIO:
- return enetc_setup_tc_taprio(ndev, type_data);
-+ case TC_SETUP_QDISC_CBS:
-+ return enetc_setup_tc_cbs(ndev, type_data);
- default:
- return -EOPNOTSUPP;
- }
---- a/drivers/net/ethernet/freescale/enetc/enetc.h
-+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
-@@ -260,7 +260,9 @@ int enetc_send_cmd(struct enetc_si *si,
- #ifdef CONFIG_FSL_ENETC_QOS
- int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data);
- void enetc_sched_speed_set(struct net_device *ndev);
-+int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data);
- #else
- #define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP
- #define enetc_sched_speed_set(ndev) (void)0
-+#define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP
- #endif
---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
-+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
-@@ -185,6 +185,8 @@ enum enetc_bdr_type {TX, RX};
- #define ENETC_PSICFGR0_SIVC(bmp) (((bmp) & 0xff) << 24) /* VLAN_TYPE */
-
- #define ENETC_PTCCBSR0(n) (0x1110 + (n) * 8) /* n = 0 to 7*/
-+#define ENETC_CBSE BIT(31)
-+#define ENETC_CBS_BW_MASK GENMASK(6, 0)
- #define ENETC_PTCCBSR1(n) (0x1114 + (n) * 8) /* n = 0 to 7*/
- #define ENETC_RSSHASH_KEY_SIZE 40
- #define ENETC_PRSSCAPR 0x1404
-@@ -679,6 +681,8 @@ struct enetc_cbd {
- u8 status_flags;
- };
-
-+#define ENETC_CLK 400000000ULL
-+
- /* port time gating control register */
- #define ENETC_QBV_PTGCR_OFFSET 0x11a00
- #define ENETC_QBV_TGE BIT(31)
---- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
-+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
-@@ -4,6 +4,7 @@
- #include "enetc.h"
-
- #include <net/pkt_sched.h>
-+#include <linux/math64.h>
-
- static u16 enetc_get_max_gcl_len(struct enetc_hw *hw)
- {
-@@ -170,3 +171,130 @@ int enetc_setup_tc_taprio(struct net_dev
-
- return err;
- }
-+
-+static u32 enetc_get_cbs_enable(struct enetc_hw *hw, u8 tc)
-+{
-+ return enetc_port_rd(hw, ENETC_PTCCBSR0(tc)) & ENETC_CBSE;
-+}
-+
-+static u8 enetc_get_cbs_bw(struct enetc_hw *hw, u8 tc)
-+{
-+ return enetc_port_rd(hw, ENETC_PTCCBSR0(tc)) & ENETC_CBS_BW_MASK;
-+}
-+
-+int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
-+{
-+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
-+ struct tc_cbs_qopt_offload *cbs = type_data;
-+ u32 port_transmit_rate = priv->speed;
-+ u8 tc_nums = netdev_get_num_tc(ndev);
-+ struct enetc_si *si = priv->si;
-+ u32 hi_credit_bit, hi_credit_reg;
-+ u32 max_interference_size;
-+ u32 port_frame_max_size;
-+ u32 tc_max_sized_frame;
-+ u8 tc = cbs->queue;
-+ u8 prio_top, prio_next;
-+ int bw_sum = 0;
-+ u8 bw;
-+
-+ prio_top = netdev_get_prio_tc_map(ndev, tc_nums - 1);
-+ prio_next = netdev_get_prio_tc_map(ndev, tc_nums - 2);
-+
-+ /* Support highest prio and second prio tc in cbs mode */
-+ if (tc != prio_top && tc != prio_next)
-+ return -EOPNOTSUPP;
-+
-+ if (!cbs->enable) {
-+ /* Make sure the other TC that are numerically
-+ * lower than this TC have been disabled.
-+ */
-+ if (tc == prio_top &&
-+ enetc_get_cbs_enable(&si->hw, prio_next)) {
-+ dev_err(&ndev->dev,
-+ "Disable TC%d before disable TC%d\n",
-+ prio_next, tc);
-+ return -EINVAL;
-+ }
-+
-+ enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0);
-+ enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0);
-+
-+ return 0;
-+ }
-+
-+ if (cbs->idleslope - cbs->sendslope != port_transmit_rate * 1000L ||
-+ cbs->idleslope < 0 || cbs->sendslope > 0)
-+ return -EOPNOTSUPP;
-+
-+ port_frame_max_size = ndev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
-+
-+ bw = cbs->idleslope / (port_transmit_rate * 10UL);
-+
-+ /* Make sure the other TC that are numerically
-+ * higher than this TC have been enabled.
-+ */
-+ if (tc == prio_next) {
-+ if (!enetc_get_cbs_enable(&si->hw, prio_top)) {
-+ dev_err(&ndev->dev,
-+ "Enable TC%d first before enable TC%d\n",
-+ prio_top, prio_next);
-+ return -EINVAL;
-+ }
-+ bw_sum += enetc_get_cbs_bw(&si->hw, prio_top);
-+ }
-+
-+ if (bw_sum + bw >= 100) {
-+ dev_err(&ndev->dev,
-+ "The sum of all CBS Bandwidth can't exceed 100\n");
-+ return -EINVAL;
-+ }
-+
-+ tc_max_sized_frame = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc));
-+
-+ /* For top prio TC, the max_interfrence_size is maxSizedFrame.
-+ *
-+ * For next prio TC, the max_interfrence_size is calculated as below:
-+ *
-+ * max_interference_size = M0 + Ma + Ra * M0 / (R0 - Ra)
-+ *
-+ * - RA: idleSlope for AVB Class A
-+ * - R0: port transmit rate
-+ * - M0: maximum sized frame for the port
-+ * - MA: maximum sized frame for AVB Class A
-+ */
-+
-+ if (tc == prio_top) {
-+ max_interference_size = port_frame_max_size * 8;
-+ } else {
-+ u32 m0, ma, r0, ra;
-+
-+ m0 = port_frame_max_size * 8;
-+ ma = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(prio_top)) * 8;
-+ ra = enetc_get_cbs_bw(&si->hw, prio_top) *
-+ port_transmit_rate * 10000ULL;
-+ r0 = port_transmit_rate * 1000000ULL;
-+ max_interference_size = m0 + ma +
-+ (u32)div_u64((u64)ra * m0, r0 - ra);
-+ }
-+
-+ /* hiCredit bits calculate by:
-+ *
-+ * maxSizedFrame * (idleSlope/portTxRate)
-+ */
-+ hi_credit_bit = max_interference_size * bw / 100;
-+
-+ /* hiCredit bits to hiCredit register need to calculated as:
-+ *
-+ * (enetClockFrequency / portTransmitRate) * 100
-+ */
-+ hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit,
-+ port_transmit_rate * 1000000ULL);
-+
-+ enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
-+
-+ /* Set bw register and enable this traffic class */
-+ enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
-+
-+ return 0;
-+}