From 486dc391ef439d45db3f7eda2229560fd2b52a78 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 16 Oct 2024 10:58:34 +0100 Subject: [PATCH 01/16] net: phylink: allow mac_select_pcs() to remove a PCS phylink has historically not permitted a PCS to be removed. An attempt to permit this with phylink_set_pcs() resulted in comments indicating that there was no need for this. This behaviour has been propagated forward to the mac_select_pcs() approach as it was believed from these comments that changing this would be NAK'd. However, with mac_select_pcs(), it takes more code and thus complexity to maintain this behaviour, which can - and in this case has - resulted in a bug. If mac_select_pcs() returns NULL for a particular interface type, but there is already a PCS in-use, then we skip the pcs_validate() method, but continue using the old PCS. Also, it wouldn't be expected behaviour by implementers of mac_select_pcs(). Allow this by removing this old unnecessary restriction. Signed-off-by: Russell King (Oracle) Reviewed-by: Vladimir Oltean Signed-off-by: Andrew Lunn --- drivers/net/phy/phylink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 24a3144e870a..aa1139efc7e4 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -1184,7 +1184,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, return; } - pcs_changed = pcs && pl->pcs != pcs; + pcs_changed = pl->pcs != pcs; } phylink_pcs_poll_stop(pl); -- 2.51.0 From 6c48cd044cc8f81b65872c8771a333fbad95997c Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 16 Oct 2024 10:58:39 +0100 Subject: [PATCH 02/16] net: phylink: remove use of pl->pcs in phylink_validate_mac_and_pcs() When the mac_select_pcs() method is not implemented, there is no way for pl->pcs to be set to a non-NULL value. This was here to support the old phylink_set_pcs() method which has been removed a few years ago. Simplify the code in phylink_validate_mac_and_pcs(). Signed-off-by: Russell King (Oracle) Reviewed-by: Vladimir Oltean Signed-off-by: Andrew Lunn --- drivers/net/phy/phylink.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index aa1139efc7e4..94f3c5fd09ed 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -649,8 +649,8 @@ static int phylink_validate_mac_and_pcs(struct phylink *pl, unsigned long *supported, struct phylink_link_state *state) { + struct phylink_pcs *pcs = NULL; unsigned long capabilities; - struct phylink_pcs *pcs; int ret; /* Get the PCS for this interface mode */ @@ -658,8 +658,6 @@ static int phylink_validate_mac_and_pcs(struct phylink *pl, pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); if (IS_ERR(pcs)) return PTR_ERR(pcs); - } else { - pcs = pl->pcs; } if (pcs) { -- 2.51.0 From 7530ea26c810d506df37cc818d1b183c18a53238 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 16 Oct 2024 10:58:44 +0100 Subject: [PATCH 03/16] net: phylink: remove "using_mac_select_pcs" With DSA's implementation of the mac_select_pcs() method removed, we can now remove the detection of mac_select_pcs() implementation. Signed-off-by: Russell King (Oracle) Reviewed-by: Vladimir Oltean Signed-off-by: Andrew Lunn --- drivers/net/phy/phylink.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 94f3c5fd09ed..b5870f8666ac 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -79,7 +79,6 @@ struct phylink { unsigned int pcs_state; bool mac_link_dropped; - bool using_mac_select_pcs; struct sfp_bus *sfp_bus; bool sfp_may_have_phy; @@ -654,7 +653,7 @@ static int phylink_validate_mac_and_pcs(struct phylink *pl, int ret; /* Get the PCS for this interface mode */ - if (pl->using_mac_select_pcs) { + if (pl->mac_ops->mac_select_pcs) { pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); if (IS_ERR(pcs)) return PTR_ERR(pcs); @@ -1173,7 +1172,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, state->interface, state->advertising); - if (pl->using_mac_select_pcs) { + if (pl->mac_ops->mac_select_pcs) { pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); if (IS_ERR(pcs)) { phylink_err(pl, @@ -1689,7 +1688,6 @@ struct phylink *phylink_create(struct phylink_config *config, phy_interface_t iface, const struct phylink_mac_ops *mac_ops) { - bool using_mac_select_pcs = false; struct phylink *pl; int ret; @@ -1700,11 +1698,6 @@ struct phylink *phylink_create(struct phylink_config *config, return ERR_PTR(-EINVAL); } - if (mac_ops->mac_select_pcs && - mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) != - ERR_PTR(-EOPNOTSUPP)) - using_mac_select_pcs = true; - pl = kzalloc(sizeof(*pl), GFP_KERNEL); if (!pl) return ERR_PTR(-ENOMEM); @@ -1723,7 +1716,6 @@ struct phylink *phylink_create(struct phylink_config *config, return ERR_PTR(-EINVAL); } - pl->using_mac_select_pcs = using_mac_select_pcs; pl->phy_state.interface = iface; pl->link_interface = iface; if (iface == PHY_INTERFACE_MODE_MOCA) -- 2.51.0 From abb7c98b99f62d30bb070a8dfe08b1033b133c0c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 16 Oct 2024 12:05:54 +0300 Subject: [PATCH 04/16] tg3: Increase buffer size for IRQ label MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit GCC is not happy with the current code, e.g.: .../tg3.c:11313:37: error: ‘-txrx-’ directive output may be truncated writing 6 bytes into a region of size between 1 and 16 [-Werror=format-truncation=] 11313 | "%s-txrx-%d", tp->dev->name, irq_num); | ^~~~~~ .../tg3.c:11313:34: note: using the range [-2147483648, 2147483647] for directive argument 11313 | "%s-txrx-%d", tp->dev->name, irq_num); When `make W=1` is supplied, this prevents kernel building. Fix it by increasing the buffer size for IRQ label and use sizeoF() instead of hard coded constants. Signed-off-by: Andy Shevchenko Reviewed-by: Michael Chan Message-ID: <20241016090647.691022-1-andriy.shevchenko@linux.intel.com> Signed-off-by: Andrew Lunn --- drivers/net/ethernet/broadcom/tg3.c | 9 ++++----- drivers/net/ethernet/broadcom/tg3.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index d5916bbc1b3a..c20958607dd8 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -11342,18 +11342,17 @@ static int tg3_request_irq(struct tg3 *tp, int irq_num) else { name = &tnapi->irq_lbl[0]; if (tnapi->tx_buffers && tnapi->rx_rcb) - snprintf(name, IFNAMSIZ, + snprintf(name, sizeof(tnapi->irq_lbl), "%s-txrx-%d", tp->dev->name, irq_num); else if (tnapi->tx_buffers) - snprintf(name, IFNAMSIZ, + snprintf(name, sizeof(tnapi->irq_lbl), "%s-tx-%d", tp->dev->name, irq_num); else if (tnapi->rx_rcb) - snprintf(name, IFNAMSIZ, + snprintf(name, sizeof(tnapi->irq_lbl), "%s-rx-%d", tp->dev->name, irq_num); else - snprintf(name, IFNAMSIZ, + snprintf(name, sizeof(tnapi->irq_lbl), "%s-%d", tp->dev->name, irq_num); - name[IFNAMSIZ-1] = 0; } if (tg3_flag(tp, USING_MSI) || tg3_flag(tp, USING_MSIX)) { diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index cf1b2b123c7e..b473f8014d9c 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -3033,7 +3033,7 @@ struct tg3_napi { dma_addr_t rx_rcb_mapping; dma_addr_t tx_desc_mapping; - char irq_lbl[IFNAMSIZ]; + char irq_lbl[IFNAMSIZ + 6 + 10]; /* name + "-txrx-" + %d */ unsigned int irq_vec; }; -- 2.51.0 From 8e3037924a36505531999df8f5847a68b9272c41 Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:25 +0100 Subject: [PATCH 05/16] net: ravb: Factor out checksum offload enable bits Introduce new constants for the CSR1 (TX) and CSR2 (RX) checksum enable bits, removing the risk of inconsistency when we change which flags we enable. Reviewed-by: Sergey Shtylyov Signed-off-by: Paul Barker Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb.h | 4 ++++ drivers/net/ethernet/renesas/ravb_main.c | 9 ++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h index a7de5cf6b317..4e1e0a754cd9 100644 --- a/drivers/net/ethernet/renesas/ravb.h +++ b/drivers/net/ethernet/renesas/ravb.h @@ -998,6 +998,8 @@ enum CSR1_BIT { CSR1_TDHD = 0x08000000, }; +#define CSR1_CSUM_ENABLE (CSR1_TIP4 | CSR1_TTCP4 | CSR1_TUDP4) + enum CSR2_BIT { CSR2_RIP4 = 0x00000001, CSR2_RTCP4 = 0x00000010, @@ -1012,6 +1014,8 @@ enum CSR2_BIT { CSR2_RDHD = 0x08000000, }; +#define CSR2_CSUM_ENABLE (CSR2_RIP4 | CSR2_RTCP4 | CSR2_RUDP4 | CSR2_RICMP4) + #define DBAT_ENTRY_NUM 22 #define RX_QUEUE_OFFSET 4 #define NUM_RX_QUEUE 2 diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 41f88f8836f8..c8988c0c85a1 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -504,11 +504,10 @@ static void ravb_csum_init_gbeth(struct net_device *ndev) ndev->features &= ~NETIF_F_RXCSUM; } else { if (tx_enable) - ravb_write(ndev, CSR1_TIP4 | CSR1_TTCP4 | CSR1_TUDP4, CSR1); + ravb_write(ndev, CSR1_CSUM_ENABLE, CSR1); if (rx_enable) - ravb_write(ndev, CSR2_RIP4 | CSR2_RTCP4 | CSR2_RUDP4 | CSR2_RICMP4, - CSR2); + ravb_write(ndev, CSR2_CSUM_ENABLE, CSR2); } done: @@ -2531,7 +2530,7 @@ static int ravb_set_features_gbeth(struct net_device *ndev, spin_lock_irqsave(&priv->lock, flags); if (changed & NETIF_F_RXCSUM) { if (features & NETIF_F_RXCSUM) - val = CSR2_RIP4 | CSR2_RTCP4 | CSR2_RUDP4 | CSR2_RICMP4; + val = CSR2_CSUM_ENABLE; else val = 0; @@ -2542,7 +2541,7 @@ static int ravb_set_features_gbeth(struct net_device *ndev, if (changed & NETIF_F_HW_CSUM) { if (features & NETIF_F_HW_CSUM) - val = CSR1_TIP4 | CSR1_TTCP4 | CSR1_TUDP4; + val = CSR1_CSUM_ENABLE; else val = 0; -- 2.51.0 From c4e347a02b14fa2425337473fcb120c62936cbc5 Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:26 +0100 Subject: [PATCH 06/16] net: ravb: Disable IP header RX checksum offloading For IPv4 packets, the header checksum will always be checked in software in the RX path (inet_gro_receive() calls ip_fast_csum() unconditionally) so there is no advantage in asking the hardware to also calculate this checksum. Reviewed-by: Sergey Shtylyov Signed-off-by: Paul Barker Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb.h | 2 +- drivers/net/ethernet/renesas/ravb_main.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h index 4e1e0a754cd9..98496aa39f3d 100644 --- a/drivers/net/ethernet/renesas/ravb.h +++ b/drivers/net/ethernet/renesas/ravb.h @@ -1014,7 +1014,7 @@ enum CSR2_BIT { CSR2_RDHD = 0x08000000, }; -#define CSR2_CSUM_ENABLE (CSR2_RIP4 | CSR2_RTCP4 | CSR2_RUDP4 | CSR2_RICMP4) +#define CSR2_CSUM_ENABLE (CSR2_RTCP4 | CSR2_RUDP4 | CSR2_RICMP4) #define DBAT_ENTRY_NUM 22 #define RX_QUEUE_OFFSET 4 diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index c8988c0c85a1..43db69d03684 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -749,13 +749,18 @@ static void ravb_get_tx_tstamp(struct net_device *ndev) static void ravb_rx_csum_gbeth(struct sk_buff *skb) { struct skb_shared_info *shinfo = skb_shinfo(skb); - __wsum csum_ip_hdr, csum_proto; + __wsum csum_proto; skb_frag_t *last_frag; u8 *hw_csum; /* The hardware checksum status is contained in sizeof(__sum16) * 2 = 4 - * bytes appended to packet data. First 2 bytes is ip header checksum - * and last 2 bytes is protocol checksum. + * bytes appended to packet data. + * + * For ipv4, the first 2 bytes are the ip header checksum status. We can + * ignore this as it will always be re-checked in inet_gro_receive(). + * + * The last 2 bytes are the protocol checksum status which will be zero + * if the checksum has been validated. */ if (unlikely(skb->len < sizeof(__sum16) * 2)) return; @@ -771,16 +776,13 @@ static void ravb_rx_csum_gbeth(struct sk_buff *skb) hw_csum -= sizeof(__sum16); csum_proto = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum)); - hw_csum -= sizeof(__sum16); - csum_ip_hdr = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum)); - if (skb_is_nonlinear(skb)) skb_frag_size_sub(last_frag, 2 * sizeof(__sum16)); else skb_trim(skb, skb->len - 2 * sizeof(__sum16)); /* TODO: IPV6 Rx checksum */ - if (skb->protocol == htons(ETH_P_IP) && !csum_ip_hdr && !csum_proto) + if (skb->protocol == htons(ETH_P_IP) && !csum_proto) skb->ip_summed = CHECKSUM_UNNECESSARY; } -- 2.51.0 From 8d2109c1a51525c3586c5bf6f78ab1ce3c2908f8 Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:27 +0100 Subject: [PATCH 07/16] net: ravb: Drop IP protocol check from RX csum verification We do not need to confirm that the protocol is IPv4. If the hardware encounters an unsupported protocol, it will set the checksum value to 0xFFFF. Reviewed-by: Sergey Shtylyov Signed-off-by: Paul Barker Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 43db69d03684..4bc2532706c2 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -781,8 +781,7 @@ static void ravb_rx_csum_gbeth(struct sk_buff *skb) else skb_trim(skb, skb->len - 2 * sizeof(__sum16)); - /* TODO: IPV6 Rx checksum */ - if (skb->protocol == htons(ETH_P_IP) && !csum_proto) + if (!csum_proto) skb->ip_summed = CHECKSUM_UNNECESSARY; } -- 2.51.0 From 5a2d973e36061cbf8d1ba00a9294244522715e53 Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:28 +0100 Subject: [PATCH 08/16] net: ravb: Combine if conditions in RX csum validation We can merge the two if conditions on skb_is_nonlinear(). Since skb_frag_size_sub() and skb_trim() do not free memory, it is still safe to access the trimmed bytes at the end of the packet after these calls. Reviewed-by: Sergey Shtylyov Signed-off-by: Paul Barker Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb_main.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 4bc2532706c2..2f584c353c78 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -750,7 +750,6 @@ static void ravb_rx_csum_gbeth(struct sk_buff *skb) { struct skb_shared_info *shinfo = skb_shinfo(skb); __wsum csum_proto; - skb_frag_t *last_frag; u8 *hw_csum; /* The hardware checksum status is contained in sizeof(__sum16) * 2 = 4 @@ -766,21 +765,19 @@ static void ravb_rx_csum_gbeth(struct sk_buff *skb) return; if (skb_is_nonlinear(skb)) { - last_frag = &shinfo->frags[shinfo->nr_frags - 1]; + skb_frag_t *last_frag = &shinfo->frags[shinfo->nr_frags - 1]; + hw_csum = skb_frag_address(last_frag) + skb_frag_size(last_frag); + skb_frag_size_sub(last_frag, 2 * sizeof(__sum16)); } else { hw_csum = skb_tail_pointer(skb); + skb_trim(skb, skb->len - 2 * sizeof(__sum16)); } hw_csum -= sizeof(__sum16); csum_proto = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum)); - if (skb_is_nonlinear(skb)) - skb_frag_size_sub(last_frag, 2 * sizeof(__sum16)); - else - skb_trim(skb, skb->len - 2 * sizeof(__sum16)); - if (!csum_proto) skb->ip_summed = CHECKSUM_UNNECESSARY; } -- 2.51.0 From faacdbba01802c89f7043f9a47ad442c1195d307 Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:29 +0100 Subject: [PATCH 09/16] net: ravb: Simplify types in RX csum validation The hardware checksum value is used as a 16-bit flag, it is zero when the checksum has been validated and non-zero otherwise. Therefore we don't need to treat this as an actual __wsum type or call csum_unfold(), we can just use a u16 pointer. Signed-off-by: Paul Barker Reviewed-by: Sergey Shtylyov Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb_main.c | 26 +++++++++++------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 2f584c353c78..ca8f785b96b4 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -749,11 +749,11 @@ static void ravb_get_tx_tstamp(struct net_device *ndev) static void ravb_rx_csum_gbeth(struct sk_buff *skb) { struct skb_shared_info *shinfo = skb_shinfo(skb); - __wsum csum_proto; - u8 *hw_csum; + size_t csum_len; + u16 *hw_csum; - /* The hardware checksum status is contained in sizeof(__sum16) * 2 = 4 - * bytes appended to packet data. + /* The hardware checksum status is contained in 4 bytes appended to + * packet data. * * For ipv4, the first 2 bytes are the ip header checksum status. We can * ignore this as it will always be re-checked in inet_gro_receive(). @@ -761,24 +761,22 @@ static void ravb_rx_csum_gbeth(struct sk_buff *skb) * The last 2 bytes are the protocol checksum status which will be zero * if the checksum has been validated. */ - if (unlikely(skb->len < sizeof(__sum16) * 2)) + csum_len = sizeof(*hw_csum) * 2; + if (unlikely(skb->len < csum_len)) return; if (skb_is_nonlinear(skb)) { skb_frag_t *last_frag = &shinfo->frags[shinfo->nr_frags - 1]; - hw_csum = skb_frag_address(last_frag) + - skb_frag_size(last_frag); - skb_frag_size_sub(last_frag, 2 * sizeof(__sum16)); + hw_csum = (u16 *)(skb_frag_address(last_frag) + + skb_frag_size(last_frag)); + skb_frag_size_sub(last_frag, csum_len); } else { - hw_csum = skb_tail_pointer(skb); - skb_trim(skb, skb->len - 2 * sizeof(__sum16)); + hw_csum = (u16 *)skb_tail_pointer(skb); + skb_trim(skb, skb->len - csum_len); } - hw_csum -= sizeof(__sum16); - csum_proto = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum)); - - if (!csum_proto) + if (!get_unaligned(--hw_csum)) skb->ip_summed = CHECKSUM_UNNECESSARY; } -- 2.51.0 From 4574ba5b711d7f7968c116521ef58d46fd4f89b1 Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:30 +0100 Subject: [PATCH 10/16] net: ravb: Disable IP header TX checksum offloading For IPv4 packets, the header checksum will always be calculated in software in the TX path (Documentation/networking/checksum-offloads.rst says "No offloading of the IP header checksum is performed; it is always done in software.") so there is no advantage in asking the hardware to also calculate this checksum. Reviewed-by: Sergey Shtylyov Signed-off-by: Paul Barker Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h index 98496aa39f3d..a5b4f4fe77b1 100644 --- a/drivers/net/ethernet/renesas/ravb.h +++ b/drivers/net/ethernet/renesas/ravb.h @@ -998,7 +998,7 @@ enum CSR1_BIT { CSR1_TDHD = 0x08000000, }; -#define CSR1_CSUM_ENABLE (CSR1_TIP4 | CSR1_TTCP4 | CSR1_TUDP4) +#define CSR1_CSUM_ENABLE (CSR1_TTCP4 | CSR1_TUDP4) enum CSR2_BIT { CSR2_RIP4 = 0x00000001, -- 2.51.0 From e63b5fd02a00aab8e79691359e931dafcd9dfd05 Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:31 +0100 Subject: [PATCH 11/16] net: ravb: Simplify UDP TX checksum offload The GbEth IP will pass through a zero UDP checksum without asserting any error flags so we do not need to resort to software checksum calculation in this case. Reviewed-by: Sergey Shtylyov Signed-off-by: Paul Barker Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb_main.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index ca8f785b96b4..80c0d36bffcb 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -2075,20 +2075,11 @@ static bool ravb_can_tx_csum_gbeth(struct sk_buff *skb) switch (ip->protocol) { case IPPROTO_TCP: - break; case IPPROTO_UDP: - /* If the checksum value in the UDP header field is 0, TOE does - * not calculate checksum for UDP part of this frame as it is - * optional function as per standards. - */ - if (udp_hdr(skb)->check == 0) - return false; - break; + return true; default: return false; } - - return true; } /* Packet transmit function for Ethernet AVB */ -- 2.51.0 From 59cceae40c67d943687587912483d68226cd04de Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:32 +0100 Subject: [PATCH 12/16] net: ravb: Enable IPv6 RX checksum offloading for GbEth The GbEth IP supports offloading IPv6 TCP, UDP & ICMPv6 checksums in the RX path. Reviewed-by: Sergey Shtylyov Signed-off-by: Paul Barker Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h index a5b4f4fe77b1..e1e55e677215 100644 --- a/drivers/net/ethernet/renesas/ravb.h +++ b/drivers/net/ethernet/renesas/ravb.h @@ -1014,7 +1014,8 @@ enum CSR2_BIT { CSR2_RDHD = 0x08000000, }; -#define CSR2_CSUM_ENABLE (CSR2_RTCP4 | CSR2_RUDP4 | CSR2_RICMP4) +#define CSR2_CSUM_ENABLE (CSR2_RTCP4 | CSR2_RUDP4 | CSR2_RICMP4 | \ + CSR2_RTCP6 | CSR2_RUDP6 | CSR2_RICMP6) #define DBAT_ENTRY_NUM 22 #define RX_QUEUE_OFFSET 4 -- 2.51.0 From 85c171509821af048a45b435e0fac36edba6a0cb Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:33 +0100 Subject: [PATCH 13/16] net: ravb: Enable IPv6 TX checksum offload for GbEth The GbEth IP supports offloading IPv6 TCP, UDP & ICMPv6 checksums in the TX path. Signed-off-by: Paul Barker Reviewed-by: Sergey Shtylyov Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb.h | 2 +- drivers/net/ethernet/renesas/ravb_main.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h index e1e55e677215..d7b3810ce21b 100644 --- a/drivers/net/ethernet/renesas/ravb.h +++ b/drivers/net/ethernet/renesas/ravb.h @@ -998,7 +998,7 @@ enum CSR1_BIT { CSR1_TDHD = 0x08000000, }; -#define CSR1_CSUM_ENABLE (CSR1_TTCP4 | CSR1_TUDP4) +#define CSR1_CSUM_ENABLE (CSR1_TTCP4 | CSR1_TUDP4 | CSR1_TTCP6 | CSR1_TUDP6) enum CSR2_BIT { CSR2_RIP4 = 0x00000001, diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 80c0d36bffcb..14b4462331b0 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -2063,17 +2063,24 @@ out_unlock: static bool ravb_can_tx_csum_gbeth(struct sk_buff *skb) { - struct iphdr *ip = ip_hdr(skb); + u8 inner_protocol; /* TODO: Need to add support for VLAN tag 802.1Q */ if (skb_vlan_tag_present(skb)) return false; - /* TODO: Need to add hardware checksum for IPv6 */ - if (skb->protocol != htons(ETH_P_IP)) + switch (ntohs(skb->protocol)) { + case ETH_P_IP: + inner_protocol = ip_hdr(skb)->protocol; + break; + case ETH_P_IPV6: + inner_protocol = ipv6_hdr(skb)->nexthdr; + break; + default: return false; + } - switch (ip->protocol) { + switch (inner_protocol) { case IPPROTO_TCP: case IPPROTO_UDP: return true; -- 2.51.0 From 546875ccba938ba4f7b5c616a1a1e334c5f2903f Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Tue, 15 Oct 2024 14:36:34 +0100 Subject: [PATCH 14/16] net: ravb: Add VLAN checksum support The GbEth IP supports offloading checksum calculation for VLAN-tagged packets, provided that the EtherType is 0x8100 and only one VLAN tag is present. Signed-off-by: Paul Barker Reviewed-by: Sergey Shtylyov Signed-off-by: Andrew Lunn --- drivers/net/ethernet/renesas/ravb.h | 1 + drivers/net/ethernet/renesas/ravb_main.c | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h index d7b3810ce21b..7b48060c250b 100644 --- a/drivers/net/ethernet/renesas/ravb.h +++ b/drivers/net/ethernet/renesas/ravb.h @@ -1055,6 +1055,7 @@ struct ravb_hw_info { size_t gstrings_size; netdev_features_t net_hw_features; netdev_features_t net_features; + netdev_features_t vlan_features; int stats_len; u32 tccr_mask; u32 tx_max_frame_size; diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 14b4462331b0..bc56f1f4bec9 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -2063,13 +2063,27 @@ out_unlock: static bool ravb_can_tx_csum_gbeth(struct sk_buff *skb) { + u16 net_protocol = ntohs(skb->protocol); u8 inner_protocol; - /* TODO: Need to add support for VLAN tag 802.1Q */ - if (skb_vlan_tag_present(skb)) - return false; + /* GbEth IP can calculate the checksum if: + * - there are zero or one VLAN headers with TPID=0x8100 + * - the network protocol is IPv4 or IPv6 + * - the transport protocol is TCP, UDP or ICMP + * - the packet is not fragmented + */ + + if (net_protocol == ETH_P_8021Q) { + struct vlan_hdr vhdr, *vh; + + vh = skb_header_pointer(skb, ETH_HLEN, sizeof(vhdr), &vhdr); + if (!vh) + return false; + + net_protocol = ntohs(vh->h_vlan_encapsulated_proto); + } - switch (ntohs(skb->protocol)) { + switch (net_protocol) { case ETH_P_IP: inner_protocol = ip_hdr(skb)->protocol; break; @@ -2772,6 +2786,7 @@ static const struct ravb_hw_info gbeth_hw_info = { .gstrings_size = sizeof(ravb_gstrings_stats_gbeth), .net_hw_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM, .net_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM, + .vlan_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM, .stats_len = ARRAY_SIZE(ravb_gstrings_stats_gbeth), .tccr_mask = TCCR_TSRQ0, .tx_max_frame_size = 1522, @@ -2914,6 +2929,7 @@ static int ravb_probe(struct platform_device *pdev) ndev->features = info->net_features; ndev->hw_features = info->net_hw_features; + ndev->vlan_features = info->vlan_features; error = reset_control_deassert(rstc); if (error) -- 2.51.0 From 30d9d8f6a2d7e44a9f91737dd409dbc87ac6f6b7 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 15 Oct 2024 09:58:09 +0200 Subject: [PATCH 15/16] net: airoha: Fix typo in REG_CDM2_FWD_CFG configuration Fix typo in airoha_fe_init routine configuring CDM2_OAM_QSEL_MASK field of REG_CDM2_FWD_CFG register. This bug is not introducing any user visible problem since Frame Engine CDM2 port is used just by the second QDMA block and we currently enable just QDMA1 block connected to the MT7530 dsa switch via CDM1 port. Introduced by commit 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC") Reported-by: ChihWei Cheng Signed-off-by: Lorenzo Bianconi Reviewed-by: Simon Horman Message-ID: <20241015-airoha-eth-cdm2-fixes-v1-1-9dc6993286c3@kernel.org> Signed-off-by: Andrew Lunn --- drivers/net/ethernet/mediatek/airoha_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c index 836a957aad77..21d6eed8aece 100644 --- a/drivers/net/ethernet/mediatek/airoha_eth.c +++ b/drivers/net/ethernet/mediatek/airoha_eth.c @@ -1371,7 +1371,8 @@ static int airoha_fe_init(struct airoha_eth *eth) airoha_fe_set(eth, REG_GDM_MISC_CFG, GDM2_RDM_ACK_WAIT_PREF_MASK | GDM2_CHN_VLD_MODE_MASK); - airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, 15); + airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, + FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); /* init fragment and assemble Force Port */ /* NPU Core-3, NPU Bridge Channel-3 */ -- 2.51.0 From eb4f99c56ad30cb0f8c8e93a78b1200f5987e41e Mon Sep 17 00:00:00 2001 From: Menglong Dong Date: Tue, 15 Oct 2024 16:28:30 +0800 Subject: [PATCH 16/16] net: vxlan: replace VXLAN_INVALID_HDR with VNI_NOT_FOUND Replace the drop reason "SKB_DROP_REASON_VXLAN_INVALID_HDR" with "SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND" in encap_bypass_if_local(), as the latter is more accurate. Fixes: 790961d88b0e ("net: vxlan: use kfree_skb_reason() in encap_bypass_if_local()") Signed-off-by: Menglong Dong Reviewed-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/vxlan/vxlan_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index d507155e62ce..c1e48711f211 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -2341,7 +2341,7 @@ static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev, DEV_STATS_INC(dev, tx_errors); vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_ERRORS, 0); - kfree_skb_reason(skb, SKB_DROP_REASON_VXLAN_INVALID_HDR); + kfree_skb_reason(skb, SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND); return -ENOENT; } -- 2.51.0