net: hibmcge: Add support for checksum offload
authorJijie Shao <shaojijie@huawei.com>
Fri, 28 Feb 2025 11:54:07 +0000 (19:54 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 4 Mar 2025 12:45:33 +0000 (13:45 +0100)
This patch implements the rx checksum offload feature.

The tx checksum offload processing in .ndo_start_xmit()
has been accepted. This patch also adds the tx checksum
feature, including NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM

Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c

index 969df60..688f408 100644 (file)
@@ -14,6 +14,9 @@
 #include "hbg_txrx.h"
 #include "hbg_debugfs.h"
 
+#define HBG_SUPPORT_FEATURES (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
+                            NETIF_F_RXCSUM)
+
 static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled)
 {
        struct hbg_irq_info *info;
@@ -419,6 +422,9 @@ static int hbg_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (ret)
                return ret;
 
+       /* set default features */
+       netdev->features |= HBG_SUPPORT_FEATURES;
+       netdev->hw_features |= HBG_SUPPORT_FEATURES;
        netdev->priv_flags |= IFF_UNICAST_FLT;
 
        netdev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
index 35dd351..8d814c8 100644 (file)
@@ -202,8 +202,14 @@ static int hbg_napi_tx_recycle(struct napi_struct *napi, int budget)
 }
 
 static bool hbg_rx_check_l3l4_error(struct hbg_priv *priv,
-                                   struct hbg_rx_desc *desc)
+                                   struct hbg_rx_desc *desc,
+                                   struct sk_buff *skb)
 {
+       bool rx_checksum_offload = !!(priv->netdev->features & NETIF_F_RXCSUM);
+
+       skb->ip_summed = rx_checksum_offload ?
+                        CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
+
        if (likely(!FIELD_GET(HBG_RX_DESC_W4_L3_ERR_CODE_M, desc->word4) &&
                   !FIELD_GET(HBG_RX_DESC_W4_L4_ERR_CODE_M, desc->word4)))
                return true;
@@ -215,8 +221,13 @@ static bool hbg_rx_check_l3l4_error(struct hbg_priv *priv,
                priv->stats.rx_desc_l3_wrong_head_cnt++;
                return false;
        case HBG_L3_CSUM_ERR:
+               skb->ip_summed = CHECKSUM_NONE;
                priv->stats.rx_desc_l3_csum_err_cnt++;
-               return false;
+
+               /* Don't drop packets on csum validation failure,
+                * suggest by Jakub
+                */
+               break;
        case HBG_L3_LEN_ERR:
                priv->stats.rx_desc_l3_len_err_cnt++;
                return false;
@@ -238,8 +249,13 @@ static bool hbg_rx_check_l3l4_error(struct hbg_priv *priv,
                priv->stats.rx_desc_l4_len_err_cnt++;
                return false;
        case HBG_L4_CSUM_ERR:
+               skb->ip_summed = CHECKSUM_NONE;
                priv->stats.rx_desc_l4_csum_err_cnt++;
-               return false;
+
+               /* Don't drop packets on csum validation failure,
+                * suggest by Jakub
+                */
+               break;
        case HBG_L4_ZERO_PORT_NUM:
                priv->stats.rx_desc_l4_zero_port_num_cnt++;
                return false;
@@ -322,7 +338,8 @@ static void hbg_update_rx_protocol_stats(struct hbg_priv *priv,
        hbg_update_rx_ip_protocol_stats(priv, desc);
 }
 
-static bool hbg_rx_pkt_check(struct hbg_priv *priv, struct hbg_rx_desc *desc)
+static bool hbg_rx_pkt_check(struct hbg_priv *priv, struct hbg_rx_desc *desc,
+                            struct sk_buff *skb)
 {
        if (unlikely(FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, desc->word2) >
                     priv->dev_specs.max_frame_len)) {
@@ -342,7 +359,7 @@ static bool hbg_rx_pkt_check(struct hbg_priv *priv, struct hbg_rx_desc *desc)
                return false;
        }
 
-       if (unlikely(!hbg_rx_check_l3l4_error(priv, desc))) {
+       if (unlikely(!hbg_rx_check_l3l4_error(priv, desc, skb))) {
                priv->stats.rx_desc_l3l4_err_cnt++;
                return false;
        }
@@ -413,7 +430,7 @@ static int hbg_napi_rx_poll(struct napi_struct *napi, int budget)
                rx_desc = (struct hbg_rx_desc *)buffer->skb->data;
                pkt_len = FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2);
 
-               if (unlikely(!hbg_rx_pkt_check(priv, rx_desc))) {
+               if (unlikely(!hbg_rx_pkt_check(priv, rx_desc, buffer->skb))) {
                        hbg_buffer_free(buffer);
                        goto next_buffer;
                }