diff mbox series

[v6,RESEND,net-next,2/5] net: enetc: add Tx checksum offload for i.MX95 ENETC

Message ID 20241204052932.112446-3-wei.fang@nxp.com (mailing list archive)
State Superseded
Headers show
Series Add more feautues for ENETC v4 - round 1 | expand

Commit Message

Wei Fang Dec. 4, 2024, 5:29 a.m. UTC
In addition to supporting Rx checksum offload, i.MX95 ENETC also supports
Tx checksum offload. The transmit checksum offload is implemented through
the Tx BD. To support Tx checksum offload, software needs to fill some
auxiliary information in Tx BD, such as IP version, IP header offset and
size, whether L4 is UDP or TCP, etc.

Same as Rx checksum offload, Tx checksum offload capability isn't defined
in register, so tx_csum bit is added to struct enetc_drvdata to indicate
whether the device supports Tx checksum offload.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
---
v2: refine enetc_tx_csum_offload_check().
v3:
1. refine enetc_tx_csum_offload_check() and enetc_skb_is_tcp() through
skb->csum_offset instead of touching skb->data.
2. add enetc_skb_is_ipv6() helper function
v4: no changes
v5:
1. remove 'inline' from enetc_skb_is_ipv6() and enetc_skb_is_tcp().
2. temp_bd.ipcs is no need to be set due to Linux always aclculates
the IPv4 checksum, so remove it.
3. simplify the setting of temp_bd.l3t.
4. remove the error log from the datapath
v6: no changes
---
 drivers/net/ethernet/freescale/enetc/enetc.c  | 47 ++++++++++++++++---
 drivers/net/ethernet/freescale/enetc/enetc.h  |  2 +
 .../net/ethernet/freescale/enetc/enetc_hw.h   | 14 ++++--
 .../freescale/enetc/enetc_pf_common.c         |  3 ++
 4 files changed, 56 insertions(+), 10 deletions(-)

Comments

Simon Horman Dec. 6, 2024, 9:37 a.m. UTC | #1
On Wed, Dec 04, 2024 at 01:29:29PM +0800, Wei Fang wrote:
> In addition to supporting Rx checksum offload, i.MX95 ENETC also supports
> Tx checksum offload. The transmit checksum offload is implemented through
> the Tx BD. To support Tx checksum offload, software needs to fill some
> auxiliary information in Tx BD, such as IP version, IP header offset and
> size, whether L4 is UDP or TCP, etc.
> 
> Same as Rx checksum offload, Tx checksum offload capability isn't defined
> in register, so tx_csum bit is added to struct enetc_drvdata to indicate
> whether the device supports Tx checksum offload.
> 
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>

...

> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> index 4b8fd1879005..590b1412fadf 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> @@ -558,7 +558,12 @@ union enetc_tx_bd {
>  		__le16 frm_len;
>  		union {
>  			struct {
> -				u8 reserved[3];
> +				u8 l3_start:7;
> +				u8 ipcs:1;
> +				u8 l3_hdr_size:7;
> +				u8 l3t:1;
> +				u8 resv:5;
> +				u8 l4t:3;
>  				u8 flags;
>  			}; /* default layout */

Hi Wei,

Given that little-endian types are used elsewhere in this structure
I am guessing that the layout above works for little-endian hosts
but will not work on big-endian hosts.

If so, I would suggest an alternate approach of using a single 32-bit
word and accessing it using a combination of FIELD_PREP() and FIELD_GET()
using masks created using GENMASK() and BIT().

Or, less desirably IMHO, by providing an alternate layout for
the embedded struct for big endian systems.

...
Wei Fang Dec. 6, 2024, 10:46 a.m. UTC | #2
> -----Original Message-----
> From: Simon Horman <horms@kernel.org>
> Sent: 2024年12月6日 17:37
> To: Wei Fang <wei.fang@nxp.com>
> Cc: Claudiu Manoil <claudiu.manoil@nxp.com>; Vladimir Oltean
> <vladimir.oltean@nxp.com>; Clark Wang <xiaoning.wang@nxp.com>;
> andrew+netdev@lunn.ch; davem@davemloft.net; edumazet@google.com;
> kuba@kernel.org; pabeni@redhat.com; Frank Li <frank.li@nxp.com>;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org; imx@lists.linux.dev
> Subject: Re: [PATCH v6 RESEND net-next 2/5] net: enetc: add Tx checksum
> offload for i.MX95 ENETC
> 
> On Wed, Dec 04, 2024 at 01:29:29PM +0800, Wei Fang wrote:
> > In addition to supporting Rx checksum offload, i.MX95 ENETC also supports
> > Tx checksum offload. The transmit checksum offload is implemented through
> > the Tx BD. To support Tx checksum offload, software needs to fill some
> > auxiliary information in Tx BD, such as IP version, IP header offset and
> > size, whether L4 is UDP or TCP, etc.
> >
> > Same as Rx checksum offload, Tx checksum offload capability isn't defined
> > in register, so tx_csum bit is added to struct enetc_drvdata to indicate
> > whether the device supports Tx checksum offload.
> >
> > Signed-off-by: Wei Fang <wei.fang@nxp.com>
> > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
> 
> ...
> 
> > diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > index 4b8fd1879005..590b1412fadf 100644
> > --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > @@ -558,7 +558,12 @@ union enetc_tx_bd {
> >  		__le16 frm_len;
> >  		union {
> >  			struct {
> > -				u8 reserved[3];
> > +				u8 l3_start:7;
> > +				u8 ipcs:1;
> > +				u8 l3_hdr_size:7;
> > +				u8 l3t:1;
> > +				u8 resv:5;
> > +				u8 l4t:3;
> >  				u8 flags;
> >  			}; /* default layout */
> 
> Hi Wei,
> 
> Given that little-endian types are used elsewhere in this structure
> I am guessing that the layout above works for little-endian hosts
> but will not work on big-endian hosts.
> 
> If so, I would suggest an alternate approach of using a single 32-bit
> word and accessing it using a combination of FIELD_PREP() and FIELD_GET()
> using masks created using GENMASK() and BIT().

Good suggestion, I will refine it, thanks.

> 
> Or, less desirably IMHO, by providing an alternate layout for
> the embedded struct for big endian systems.
> 
> ...
Simon Horman Dec. 6, 2024, 12:32 p.m. UTC | #3
On Fri, Dec 06, 2024 at 10:46:49AM +0000, Wei Fang wrote:
> > -----Original Message-----
> > From: Simon Horman <horms@kernel.org>
> > Sent: 2024年12月6日 17:37
> > To: Wei Fang <wei.fang@nxp.com>
> > Cc: Claudiu Manoil <claudiu.manoil@nxp.com>; Vladimir Oltean
> > <vladimir.oltean@nxp.com>; Clark Wang <xiaoning.wang@nxp.com>;
> > andrew+netdev@lunn.ch; davem@davemloft.net; edumazet@google.com;
> > kuba@kernel.org; pabeni@redhat.com; Frank Li <frank.li@nxp.com>;
> > netdev@vger.kernel.org; linux-kernel@vger.kernel.org; imx@lists.linux.dev
> > Subject: Re: [PATCH v6 RESEND net-next 2/5] net: enetc: add Tx checksum
> > offload for i.MX95 ENETC
> > 
> > On Wed, Dec 04, 2024 at 01:29:29PM +0800, Wei Fang wrote:
> > > In addition to supporting Rx checksum offload, i.MX95 ENETC also supports
> > > Tx checksum offload. The transmit checksum offload is implemented through
> > > the Tx BD. To support Tx checksum offload, software needs to fill some
> > > auxiliary information in Tx BD, such as IP version, IP header offset and
> > > size, whether L4 is UDP or TCP, etc.
> > >
> > > Same as Rx checksum offload, Tx checksum offload capability isn't defined
> > > in register, so tx_csum bit is added to struct enetc_drvdata to indicate
> > > whether the device supports Tx checksum offload.
> > >
> > > Signed-off-by: Wei Fang <wei.fang@nxp.com>
> > > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > > Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
> > 
> > ...
> > 
> > > diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > index 4b8fd1879005..590b1412fadf 100644
> > > --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > @@ -558,7 +558,12 @@ union enetc_tx_bd {
> > >  		__le16 frm_len;
> > >  		union {
> > >  			struct {
> > > -				u8 reserved[3];
> > > +				u8 l3_start:7;
> > > +				u8 ipcs:1;
> > > +				u8 l3_hdr_size:7;
> > > +				u8 l3t:1;
> > > +				u8 resv:5;
> > > +				u8 l4t:3;
> > >  				u8 flags;
> > >  			}; /* default layout */
> > 
> > Hi Wei,
> > 
> > Given that little-endian types are used elsewhere in this structure
> > I am guessing that the layout above works for little-endian hosts
> > but will not work on big-endian hosts.
> > 
> > If so, I would suggest an alternate approach of using a single 32-bit
> > word and accessing it using a combination of FIELD_PREP() and FIELD_GET()
> > using masks created using GENMASK() and BIT().
> 
> Good suggestion, I will refine it, thanks.

Thanks. I forgot to mention that you will likely also need to add
cpu_to_le32 and le32_to_cpu to the mix.

> > Or, less desirably IMHO, by providing an alternate layout for
> > the embedded struct for big endian systems.
> > 
> > ...
>
Wei Fang Dec. 6, 2024, 12:38 p.m. UTC | #4
> -----Original Message-----
> From: Simon Horman <horms@kernel.org>
> Sent: 2024年12月6日 20:32
> To: Wei Fang <wei.fang@nxp.com>
> Cc: Claudiu Manoil <claudiu.manoil@nxp.com>; Vladimir Oltean
> <vladimir.oltean@nxp.com>; Clark Wang <xiaoning.wang@nxp.com>;
> andrew+netdev@lunn.ch; davem@davemloft.net; edumazet@google.com;
> kuba@kernel.org; pabeni@redhat.com; Frank Li <frank.li@nxp.com>;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org; imx@lists.linux.dev
> Subject: Re: [PATCH v6 RESEND net-next 2/5] net: enetc: add Tx checksum
> offload for i.MX95 ENETC
> 
> On Fri, Dec 06, 2024 at 10:46:49AM +0000, Wei Fang wrote:
> > > -----Original Message-----
> > > From: Simon Horman <horms@kernel.org>
> > > Sent: 2024年12月6日 17:37
> > > To: Wei Fang <wei.fang@nxp.com>
> > > Cc: Claudiu Manoil <claudiu.manoil@nxp.com>; Vladimir Oltean
> > > <vladimir.oltean@nxp.com>; Clark Wang <xiaoning.wang@nxp.com>;
> > > andrew+netdev@lunn.ch; davem@davemloft.net; edumazet@google.com;
> > > kuba@kernel.org; pabeni@redhat.com; Frank Li <frank.li@nxp.com>;
> > > netdev@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > imx@lists.linux.dev
> > > Subject: Re: [PATCH v6 RESEND net-next 2/5] net: enetc: add Tx
> > > checksum offload for i.MX95 ENETC
> > >
> > > On Wed, Dec 04, 2024 at 01:29:29PM +0800, Wei Fang wrote:
> > > > In addition to supporting Rx checksum offload, i.MX95 ENETC also
> > > > supports Tx checksum offload. The transmit checksum offload is
> > > > implemented through the Tx BD. To support Tx checksum offload,
> > > > software needs to fill some auxiliary information in Tx BD, such
> > > > as IP version, IP header offset and size, whether L4 is UDP or TCP, etc.
> > > >
> > > > Same as Rx checksum offload, Tx checksum offload capability isn't
> > > > defined in register, so tx_csum bit is added to struct
> > > > enetc_drvdata to indicate whether the device supports Tx checksum
> offload.
> > > >
> > > > Signed-off-by: Wei Fang <wei.fang@nxp.com>
> > > > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > > > Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
> > >
> > > ...
> > >
> > > > diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > > index 4b8fd1879005..590b1412fadf 100644
> > > > --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > > +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > > @@ -558,7 +558,12 @@ union enetc_tx_bd {
> > > >  		__le16 frm_len;
> > > >  		union {
> > > >  			struct {
> > > > -				u8 reserved[3];
> > > > +				u8 l3_start:7;
> > > > +				u8 ipcs:1;
> > > > +				u8 l3_hdr_size:7;
> > > > +				u8 l3t:1;
> > > > +				u8 resv:5;
> > > > +				u8 l4t:3;
> > > >  				u8 flags;
> > > >  			}; /* default layout */
> > >
> > > Hi Wei,
> > >
> > > Given that little-endian types are used elsewhere in this structure
> > > I am guessing that the layout above works for little-endian hosts
> > > but will not work on big-endian hosts.
> > >
> > > If so, I would suggest an alternate approach of using a single
> > > 32-bit word and accessing it using a combination of FIELD_PREP() and
> > > FIELD_GET() using masks created using GENMASK() and BIT().
> >
> > Good suggestion, I will refine it, thanks.
> 
> Thanks. I forgot to mention that you will likely also need to add
> cpu_to_le32 and le32_to_cpu to the mix.
> 

I think I will use u8 instead of 32-bit, because I don't want to affect
the existing 'u8 flag'. And u8 is good enough.

> > > Or, less desirably IMHO, by providing an alternate layout for the
> > > embedded struct for big endian systems.
> > >
> > > ...
> >
Simon Horman Dec. 6, 2024, 1:31 p.m. UTC | #5
On Fri, Dec 06, 2024 at 12:38:49PM +0000, Wei Fang wrote:
> > -----Original Message-----
> > From: Simon Horman <horms@kernel.org>
> > Sent: 2024年12月6日 20:32
> > To: Wei Fang <wei.fang@nxp.com>
> > Cc: Claudiu Manoil <claudiu.manoil@nxp.com>; Vladimir Oltean
> > <vladimir.oltean@nxp.com>; Clark Wang <xiaoning.wang@nxp.com>;
> > andrew+netdev@lunn.ch; davem@davemloft.net; edumazet@google.com;
> > kuba@kernel.org; pabeni@redhat.com; Frank Li <frank.li@nxp.com>;
> > netdev@vger.kernel.org; linux-kernel@vger.kernel.org; imx@lists.linux.dev
> > Subject: Re: [PATCH v6 RESEND net-next 2/5] net: enetc: add Tx checksum
> > offload for i.MX95 ENETC
> > 
> > On Fri, Dec 06, 2024 at 10:46:49AM +0000, Wei Fang wrote:
> > > > -----Original Message-----
> > > > From: Simon Horman <horms@kernel.org>
> > > > Sent: 2024年12月6日 17:37
> > > > To: Wei Fang <wei.fang@nxp.com>
> > > > Cc: Claudiu Manoil <claudiu.manoil@nxp.com>; Vladimir Oltean
> > > > <vladimir.oltean@nxp.com>; Clark Wang <xiaoning.wang@nxp.com>;
> > > > andrew+netdev@lunn.ch; davem@davemloft.net; edumazet@google.com;
> > > > kuba@kernel.org; pabeni@redhat.com; Frank Li <frank.li@nxp.com>;
> > > > netdev@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > > imx@lists.linux.dev
> > > > Subject: Re: [PATCH v6 RESEND net-next 2/5] net: enetc: add Tx
> > > > checksum offload for i.MX95 ENETC
> > > >
> > > > On Wed, Dec 04, 2024 at 01:29:29PM +0800, Wei Fang wrote:
> > > > > In addition to supporting Rx checksum offload, i.MX95 ENETC also
> > > > > supports Tx checksum offload. The transmit checksum offload is
> > > > > implemented through the Tx BD. To support Tx checksum offload,
> > > > > software needs to fill some auxiliary information in Tx BD, such
> > > > > as IP version, IP header offset and size, whether L4 is UDP or TCP, etc.
> > > > >
> > > > > Same as Rx checksum offload, Tx checksum offload capability isn't
> > > > > defined in register, so tx_csum bit is added to struct
> > > > > enetc_drvdata to indicate whether the device supports Tx checksum
> > offload.
> > > > >
> > > > > Signed-off-by: Wei Fang <wei.fang@nxp.com>
> > > > > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > > > > Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
> > > >
> > > > ...
> > > >
> > > > > diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > > b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > > > index 4b8fd1879005..590b1412fadf 100644
> > > > > --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > > > +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> > > > > @@ -558,7 +558,12 @@ union enetc_tx_bd {
> > > > >  		__le16 frm_len;
> > > > >  		union {
> > > > >  			struct {
> > > > > -				u8 reserved[3];
> > > > > +				u8 l3_start:7;
> > > > > +				u8 ipcs:1;
> > > > > +				u8 l3_hdr_size:7;
> > > > > +				u8 l3t:1;
> > > > > +				u8 resv:5;
> > > > > +				u8 l4t:3;
> > > > >  				u8 flags;
> > > > >  			}; /* default layout */
> > > >
> > > > Hi Wei,
> > > >
> > > > Given that little-endian types are used elsewhere in this structure
> > > > I am guessing that the layout above works for little-endian hosts
> > > > but will not work on big-endian hosts.
> > > >
> > > > If so, I would suggest an alternate approach of using a single
> > > > 32-bit word and accessing it using a combination of FIELD_PREP() and
> > > > FIELD_GET() using masks created using GENMASK() and BIT().
> > >
> > > Good suggestion, I will refine it, thanks.
> > 
> > Thanks. I forgot to mention that you will likely also need to add
> > cpu_to_le32 and le32_to_cpu to the mix.
> > 
> 
> I think I will use u8 instead of 32-bit, because I don't want to affect
> the existing 'u8 flag'. And u8 is good enough.

Sure, I agree that looks like it should work.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 3137b6ee62d3..94a78dca86e1 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -143,6 +143,27 @@  static int enetc_ptp_parse(struct sk_buff *skb, u8 *udp,
 	return 0;
 }
 
+static bool enetc_tx_csum_offload_check(struct sk_buff *skb)
+{
+	switch (skb->csum_offset) {
+	case offsetof(struct tcphdr, check):
+	case offsetof(struct udphdr, check):
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool enetc_skb_is_ipv6(struct sk_buff *skb)
+{
+	return vlan_get_protocol(skb) == htons(ETH_P_IPV6);
+}
+
+static bool enetc_skb_is_tcp(struct sk_buff *skb)
+{
+	return skb->csum_offset == offsetof(struct tcphdr, check);
+}
+
 static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 {
 	bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false;
@@ -160,6 +181,23 @@  static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 	dma_addr_t dma;
 	u8 flags = 0;
 
+	enetc_clear_tx_bd(&temp_bd);
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		/* Can not support TSD and checksum offload at the same time */
+		if (priv->active_offloads & ENETC_F_TXCSUM &&
+		    enetc_tx_csum_offload_check(skb) && !tx_ring->tsd_enable) {
+			temp_bd.l3_start = skb_network_offset(skb);
+			temp_bd.l3_hdr_size = skb_network_header_len(skb) / 4;
+			temp_bd.l3t = enetc_skb_is_ipv6(skb);
+			temp_bd.l4t = enetc_skb_is_tcp(skb) ? ENETC_TXBD_L4T_TCP :
+							      ENETC_TXBD_L4T_UDP;
+			flags |= ENETC_TXBD_FLAGS_CSUM_LSO | ENETC_TXBD_FLAGS_L4CS;
+		} else {
+			if (skb_checksum_help(skb))
+				return 0;
+		}
+	}
+
 	i = tx_ring->next_to_use;
 	txbd = ENETC_TXBD(*tx_ring, i);
 	prefetchw(txbd);
@@ -170,7 +208,6 @@  static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 
 	temp_bd.addr = cpu_to_le64(dma);
 	temp_bd.buf_len = cpu_to_le16(len);
-	temp_bd.lstatus = 0;
 
 	tx_swbd = &tx_ring->tx_swbd[i];
 	tx_swbd->dma = dma;
@@ -591,7 +628,7 @@  static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
 {
 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
 	struct enetc_bdr *tx_ring;
-	int count, err;
+	int count;
 
 	/* Queue one-step Sync packet if already locked */
 	if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
@@ -624,11 +661,6 @@  static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
 			return NETDEV_TX_BUSY;
 		}
 
-		if (skb->ip_summed == CHECKSUM_PARTIAL) {
-			err = skb_checksum_help(skb);
-			if (err)
-				goto drop_packet_err;
-		}
 		enetc_lock_mdio();
 		count = enetc_map_tx_buffs(tx_ring, skb);
 		enetc_unlock_mdio();
@@ -3287,6 +3319,7 @@  static const struct enetc_drvdata enetc4_pf_data = {
 	.sysclk_freq = ENETC_CLK_333M,
 	.pmac_offset = ENETC4_PMAC_OFFSET,
 	.rx_csum = 1,
+	.tx_csum = 1,
 	.eth_ops = &enetc4_pf_ethtool_ops,
 };
 
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index 5b65f79e05be..ee11ff97e9ed 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -235,6 +235,7 @@  enum enetc_errata {
 struct enetc_drvdata {
 	u32 pmac_offset; /* Only valid for PSI which supports 802.1Qbu */
 	u8 rx_csum:1;
+	u8 tx_csum:1;
 	u64 sysclk_freq;
 	const struct ethtool_ops *eth_ops;
 };
@@ -343,6 +344,7 @@  enum enetc_active_offloads {
 	ENETC_F_QCI			= BIT(10),
 	ENETC_F_QBU			= BIT(11),
 	ENETC_F_RXCSUM			= BIT(12),
+	ENETC_F_TXCSUM			= BIT(13),
 };
 
 enum enetc_flags_bit {
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index 4b8fd1879005..590b1412fadf 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -558,7 +558,12 @@  union enetc_tx_bd {
 		__le16 frm_len;
 		union {
 			struct {
-				u8 reserved[3];
+				u8 l3_start:7;
+				u8 ipcs:1;
+				u8 l3_hdr_size:7;
+				u8 l3t:1;
+				u8 resv:5;
+				u8 l4t:3;
 				u8 flags;
 			}; /* default layout */
 			__le32 txstart;
@@ -582,10 +587,10 @@  union enetc_tx_bd {
 };
 
 enum enetc_txbd_flags {
-	ENETC_TXBD_FLAGS_RES0 = BIT(0), /* reserved */
+	ENETC_TXBD_FLAGS_L4CS = BIT(0), /* For ENETC 4.1 and later */
 	ENETC_TXBD_FLAGS_TSE = BIT(1),
 	ENETC_TXBD_FLAGS_W = BIT(2),
-	ENETC_TXBD_FLAGS_RES3 = BIT(3), /* reserved */
+	ENETC_TXBD_FLAGS_CSUM_LSO = BIT(3), /* For ENETC 4.1 and later */
 	ENETC_TXBD_FLAGS_TXSTART = BIT(4),
 	ENETC_TXBD_FLAGS_EX = BIT(6),
 	ENETC_TXBD_FLAGS_F = BIT(7)
@@ -594,6 +599,9 @@  enum enetc_txbd_flags {
 #define ENETC_TXBD_TXSTART_MASK GENMASK(24, 0)
 #define ENETC_TXBD_FLAGS_OFFSET 24
 
+#define ENETC_TXBD_L4T_UDP	BIT(0)
+#define ENETC_TXBD_L4T_TCP	BIT(1)
+
 static inline __le32 enetc_txbd_set_tx_start(u64 tx_start, u8 flags)
 {
 	u32 temp;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 91e79582a541..3a8a5b6d8c26 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -122,6 +122,9 @@  void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
 	if (si->drvdata->rx_csum)
 		priv->active_offloads |= ENETC_F_RXCSUM;
 
+	if (si->drvdata->tx_csum)
+		priv->active_offloads |= ENETC_F_TXCSUM;
+
 	/* TODO: currently, i.MX95 ENETC driver does not support advanced features */
 	if (!is_enetc_rev1(si)) {
 		ndev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_LOOPBACK);