]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
hinic3: Add RX VLAN offload support
authorFan Gong <gongfan1@huawei.com>
Tue, 10 Mar 2026 01:04:52 +0000 (09:04 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 12 Mar 2026 11:13:48 +0000 (12:13 +0100)
Add vlan offload processing in RX process.

Co-developed-by: Zhu Yikai <zhuyikai1@h-partners.com>
Signed-off-by: Zhu Yikai <zhuyikai1@h-partners.com>
Signed-off-by: Fan Gong <gongfan1@huawei.com>
Link: https://patch.msgid.link/22cf02a014c2beb7b5f92ab5e6de38c4dd928125.1773062356.git.zhuyikai1@h-partners.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h

index 1236ec233b7fc766d75891bf0743560cad6bba91..309ab590137979c678acac71ea23efddf524a4a8 100644 (file)
@@ -328,6 +328,7 @@ static void hinic3_rx_csum(struct hinic3_rxq *rxq, u32 offload_type,
        u32 ip_type = RQ_CQE_OFFOLAD_TYPE_GET(offload_type, IP_TYPE);
        u32 csum_err = RQ_CQE_STATUS_GET(status, CSUM_ERR);
        struct net_device *netdev = rxq->netdev;
+       bool l2_tunnel;
 
        if (!(netdev->features & NETIF_F_RXCSUM))
                return;
@@ -350,6 +351,12 @@ static void hinic3_rx_csum(struct hinic3_rxq *rxq, u32 offload_type,
        case HINIC3_RX_UDP_PKT:
        case HINIC3_RX_SCTP_PKT:
                skb->ip_summed = CHECKSUM_UNNECESSARY;
+               l2_tunnel = HINIC3_GET_RX_TUNNEL_PKT_FORMAT(offload_type) ==
+                           HINIC3_RX_PKT_FORMAT_VXLAN ? 1 : 0;
+               if (l2_tunnel) {
+                       /* If we checked the outer header let the stack know */
+                       skb->csum_level = 1;
+               }
                break;
        default:
                skb->ip_summed = CHECKSUM_NONE;
@@ -390,6 +397,14 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
        offload_type = le32_to_cpu(rx_cqe->offload_type);
        hinic3_rx_csum(rxq, offload_type, status, skb);
 
+       if ((netdev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+           RQ_CQE_OFFOLAD_TYPE_GET(offload_type, VLAN_EN)) {
+               u16 vid = RQ_CQE_SGE_GET(vlan_len, VLAN);
+
+               /* if the packet is a vlan pkt, the vid may be 0 */
+               __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
+       }
+
        num_lro = RQ_CQE_STATUS_GET(status, NUM_LRO);
        if (num_lro)
                hinic3_lro_set_gso_params(skb, num_lro);
index 31622e0a63d06d37bc317129fc2953e74b584dfd..06d1b3299e7cf4053256a8bd960ec539a22434ce 100644 (file)
@@ -15,6 +15,9 @@
 #define RQ_CQE_OFFOLAD_TYPE_GET(val, member) \
        FIELD_GET(RQ_CQE_OFFOLAD_TYPE_##member##_MASK, val)
 
+#define HINIC3_GET_RX_TUNNEL_PKT_FORMAT(offload_type) \
+       RQ_CQE_OFFOLAD_TYPE_GET(offload_type, TUNNEL_PKT_FORMAT)
+
 #define RQ_CQE_SGE_VLAN_MASK  GENMASK(15, 0)
 #define RQ_CQE_SGE_LEN_MASK   GENMASK(31, 16)
 #define RQ_CQE_SGE_GET(val, member) \