Commit 34c6adf1 authored by Po Liu's avatar Po Liu Committed by David S. Miller
Browse files

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: default avatarPo Liu <Po.Liu@nxp.com>
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarClaudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c3f812ce
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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).
+2 −0
Original line number Diff line number Diff line
@@ -5,9 +5,11 @@ common-objs := enetc.o enetc_cbdr.o enetc_ethtool.o
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
+14 −5
Original line number Diff line number Diff line
@@ -1427,8 +1427,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;
@@ -1436,9 +1435,6 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
	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;

@@ -1483,6 +1479,19 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
	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);
+7 −0
Original line number Diff line number Diff line
@@ -244,3 +244,10 @@ int enetc_set_fs_entry(struct enetc_si *si, struct enetc_cmd_rfse *rfse,
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
+4 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ static int enetc_cbd_unused(struct enetc_cbdr *r)
		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_si *si, struct enetc_cbd *cbd)
	if (!timeout)
		return -EBUSY;

	/* CBD may writeback data, feedback up level */
	*cbd = *dest_cbd;

	enetc_clean_cbdr(si);

	return 0;
Loading