ENETC rev 4.1 supports TCP and UDP checksum offload for receive, the bit
108 of the Rx BD will be set if the TCP/UDP checksum is correct. Since
this capability is not defined in register, the rx_csum bit is added to
struct enetc_drvdata to indicate whether the device supports Rx checksum
offload.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc.c | 14 ++++++++++----
drivers/net/ethernet/freescale/enetc/enetc.h | 2 ++
drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 ++
.../net/ethernet/freescale/enetc/enetc_pf_common.c | 3 +++
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 35634c516e26..3137b6ee62d3 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -1011,10 +1011,15 @@ static void enetc_get_offloads(struct enetc_bdr *rx_ring,
/* TODO: hashing */
if (rx_ring->ndev->features & NETIF_F_RXCSUM) {
- u16 inet_csum = le16_to_cpu(rxbd->r.inet_csum);
-
- skb->csum = csum_unfold((__force __sum16)~htons(inet_csum));
- skb->ip_summed = CHECKSUM_COMPLETE;
+ if (priv->active_offloads & ENETC_F_RXCSUM &&
+ le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_L4_CSUM_OK) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else {
+ u16 inet_csum = le16_to_cpu(rxbd->r.inet_csum);
+
+ skb->csum = csum_unfold((__force __sum16)~htons(inet_csum));
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ }
}
if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) {
@@ -3281,6 +3286,7 @@ static const struct enetc_drvdata enetc_pf_data = {
static const struct enetc_drvdata enetc4_pf_data = {
.sysclk_freq = ENETC_CLK_333M,
.pmac_offset = ENETC4_PMAC_OFFSET,
+ .rx_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 72fa03dbc2dd..5b65f79e05be 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -234,6 +234,7 @@ enum enetc_errata {
struct enetc_drvdata {
u32 pmac_offset; /* Only valid for PSI which supports 802.1Qbu */
+ u8 rx_csum:1;
u64 sysclk_freq;
const struct ethtool_ops *eth_ops;
};
@@ -341,6 +342,7 @@ enum enetc_active_offloads {
ENETC_F_QBV = BIT(9),
ENETC_F_QCI = BIT(10),
ENETC_F_QBU = BIT(11),
+ ENETC_F_RXCSUM = BIT(12),
};
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 7c3285584f8a..4b8fd1879005 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -645,6 +645,8 @@ union enetc_rx_bd {
#define ENETC_RXBD_LSTATUS(flags) ((flags) << 16)
#define ENETC_RXBD_FLAG_VLAN BIT(9)
#define ENETC_RXBD_FLAG_TSTMP BIT(10)
+/* UDP and TCP checksum offload, for ENETC 4.1 and later */
+#define ENETC_RXBD_FLAG_L4_CSUM_OK BIT(12)
#define ENETC_RXBD_FLAG_TPID GENMASK(1, 0)
#define ENETC_MAC_ADDR_FILT_CNT 8 /* # of supported entries per port */
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 0eecfc833164..91e79582a541 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -119,6 +119,9 @@ void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
ndev->priv_flags |= IFF_UNICAST_FLT;
+ if (si->drvdata->rx_csum)
+ priv->active_offloads |= ENETC_F_RXCSUM;
+
/* 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);
--
2.34.1
On Thu, Nov 07, 2024 at 11:38:13AM +0800, Wei Fang wrote: > ENETC rev 4.1 supports TCP and UDP checksum offload for receive, the bit > 108 of the Rx BD will be set if the TCP/UDP checksum is correct. Since > this capability is not defined in register, the rx_csum bit is added to > struct enetc_drvdata to indicate whether the device supports Rx checksum > offload. > > Signed-off-by: Wei Fang <wei.fang@nxp.com> > --- Reviewed-by: Frank Li <Frank.Li@nxp.com> > drivers/net/ethernet/freescale/enetc/enetc.c | 14 ++++++++++---- > drivers/net/ethernet/freescale/enetc/enetc.h | 2 ++ > drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 ++ > .../net/ethernet/freescale/enetc/enetc_pf_common.c | 3 +++ > 4 files changed, 17 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c > index 35634c516e26..3137b6ee62d3 100644 > --- a/drivers/net/ethernet/freescale/enetc/enetc.c > +++ b/drivers/net/ethernet/freescale/enetc/enetc.c > @@ -1011,10 +1011,15 @@ static void enetc_get_offloads(struct enetc_bdr *rx_ring, > > /* TODO: hashing */ > if (rx_ring->ndev->features & NETIF_F_RXCSUM) { > - u16 inet_csum = le16_to_cpu(rxbd->r.inet_csum); > - > - skb->csum = csum_unfold((__force __sum16)~htons(inet_csum)); > - skb->ip_summed = CHECKSUM_COMPLETE; > + if (priv->active_offloads & ENETC_F_RXCSUM && > + le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_L4_CSUM_OK) { > + skb->ip_summed = CHECKSUM_UNNECESSARY; > + } else { > + u16 inet_csum = le16_to_cpu(rxbd->r.inet_csum); > + > + skb->csum = csum_unfold((__force __sum16)~htons(inet_csum)); > + skb->ip_summed = CHECKSUM_COMPLETE; > + } > } > > if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) { > @@ -3281,6 +3286,7 @@ static const struct enetc_drvdata enetc_pf_data = { > static const struct enetc_drvdata enetc4_pf_data = { > .sysclk_freq = ENETC_CLK_333M, > .pmac_offset = ENETC4_PMAC_OFFSET, > + .rx_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 72fa03dbc2dd..5b65f79e05be 100644 > --- a/drivers/net/ethernet/freescale/enetc/enetc.h > +++ b/drivers/net/ethernet/freescale/enetc/enetc.h > @@ -234,6 +234,7 @@ enum enetc_errata { > > struct enetc_drvdata { > u32 pmac_offset; /* Only valid for PSI which supports 802.1Qbu */ > + u8 rx_csum:1; > u64 sysclk_freq; > const struct ethtool_ops *eth_ops; > }; > @@ -341,6 +342,7 @@ enum enetc_active_offloads { > ENETC_F_QBV = BIT(9), > ENETC_F_QCI = BIT(10), > ENETC_F_QBU = BIT(11), > + ENETC_F_RXCSUM = BIT(12), > }; > > 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 7c3285584f8a..4b8fd1879005 100644 > --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h > +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h > @@ -645,6 +645,8 @@ union enetc_rx_bd { > #define ENETC_RXBD_LSTATUS(flags) ((flags) << 16) > #define ENETC_RXBD_FLAG_VLAN BIT(9) > #define ENETC_RXBD_FLAG_TSTMP BIT(10) > +/* UDP and TCP checksum offload, for ENETC 4.1 and later */ > +#define ENETC_RXBD_FLAG_L4_CSUM_OK BIT(12) > #define ENETC_RXBD_FLAG_TPID GENMASK(1, 0) > > #define ENETC_MAC_ADDR_FILT_CNT 8 /* # of supported entries per port */ > diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c > index 0eecfc833164..91e79582a541 100644 > --- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c > +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c > @@ -119,6 +119,9 @@ void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev, > > ndev->priv_flags |= IFF_UNICAST_FLT; > > + if (si->drvdata->rx_csum) > + priv->active_offloads |= ENETC_F_RXCSUM; > + > /* 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); > -- > 2.34.1 >
© 2016 - 2024 Red Hat, Inc.