ice: Implement VLAN tag hint
authorLarysa Zaremba <larysa.zaremba@intel.com>
Tue, 5 Dec 2023 21:08:39 +0000 (22:08 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 14 Dec 2023 00:16:41 +0000 (16:16 -0800)
Implement .xmo_rx_vlan_tag callback to allow XDP code to read
packet's VLAN tag.

At the same time, use vlan_tci instead of vlan_tag in touched code,
because VLAN tag often refers to VLAN proto and VLAN TCI combined,
while in the code we clearly store only VLAN TCI.

Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
Link: https://lore.kernel.org/r/20231205210847.28460-11-larysa.zaremba@intel.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_txrx.c
drivers/net/ethernet/intel/ice/ice_txrx.h
drivers/net/ethernet/intel/ice/ice_txrx_lib.c
drivers/net/ethernet/intel/ice/ice_txrx_lib.h
drivers/net/ethernet/intel/ice/ice_xsk.c

index 0a2415dd78f1fb47da3f38b37f5d55324b865ecb..86f704850aa6ed88f1d95832e06c571ec67adf4d 100644 (file)
@@ -6043,6 +6043,23 @@ ice_fix_features(struct net_device *netdev, netdev_features_t features)
        return features;
 }
 
+/**
+ * ice_set_rx_rings_vlan_proto - update rings with new stripped VLAN proto
+ * @vsi: PF's VSI
+ * @vlan_ethertype: VLAN ethertype (802.1Q or 802.1ad) in network byte order
+ *
+ * Store current stripped VLAN proto in ring packet context,
+ * so it can be accessed more efficiently by packet processing code.
+ */
+static void
+ice_set_rx_rings_vlan_proto(struct ice_vsi *vsi, __be16 vlan_ethertype)
+{
+       u16 i;
+
+       ice_for_each_alloc_rxq(vsi, i)
+               vsi->rx_rings[i]->pkt_ctx.vlan_proto = vlan_ethertype;
+}
+
 /**
  * ice_set_vlan_offload_features - set VLAN offload features for the PF VSI
  * @vsi: PF's VSI
@@ -6085,6 +6102,9 @@ ice_set_vlan_offload_features(struct ice_vsi *vsi, netdev_features_t features)
        if (strip_err || insert_err)
                return -EIO;
 
+       ice_set_rx_rings_vlan_proto(vsi, enable_stripping ?
+                                   htons(vlan_ethertype) : 0);
+
        return 0;
 }
 
index 99ea47011fe0080a66a5385e576e06242a15181a..59617f055e35304bbac229c44b37b8f052b97c66 100644 (file)
@@ -1183,7 +1183,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
                struct sk_buff *skb;
                unsigned int size;
                u16 stat_err_bits;
-               u16 vlan_tag = 0;
+               u16 vlan_tci;
 
                /* get the Rx desc from Rx ring based on 'next_to_clean' */
                rx_desc = ICE_RX_DESC(rx_ring, ntc);
@@ -1278,7 +1278,7 @@ construct_skb:
                        continue;
                }
 
-               vlan_tag = ice_get_vlan_tag_from_rx_desc(rx_desc);
+               vlan_tci = ice_get_vlan_tci(rx_desc);
 
                /* pad the skb if needed, to make a valid ethernet frame */
                if (eth_skb_pad(skb))
@@ -1292,7 +1292,7 @@ construct_skb:
 
                ice_trace(clean_rx_irq_indicate, rx_ring, rx_desc, skb);
                /* send completed skb up the stack */
-               ice_receive_skb(rx_ring, skb, vlan_tag);
+               ice_receive_skb(rx_ring, skb, vlan_tci);
 
                /* update budget accounting */
                total_rx_pkts++;
index ce3434c73a4be15c171de321ae3de566ab3cb7a2..b3379ff736747887a7404c5d020b865bc10a5024 100644 (file)
@@ -259,6 +259,7 @@ enum ice_rx_dtype {
 
 struct ice_pkt_ctx {
        u64 cached_phctime;
+       __be16 vlan_proto;
 };
 
 struct ice_xdp_buff {
@@ -335,7 +336,10 @@ struct ice_rx_ring {
        /* CL3 - 3rd cacheline starts here */
        union {
                struct ice_pkt_ctx pkt_ctx;
-               u64 cached_phctime;
+               struct {
+                       u64 cached_phctime;
+                       __be16 vlan_proto;
+               };
        };
        struct bpf_prog *xdp_prog;
        u16 rx_offset;
index 09610c5615a8ecb420a62b9b07bdebbff2deee59..25ffb539b4740c7e600fb7933493d7cc32dd516d 100644 (file)
@@ -599,7 +599,33 @@ static int ice_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash,
        return 0;
 }
 
+/**
+ * ice_xdp_rx_vlan_tag - VLAN tag XDP hint handler
+ * @ctx: XDP buff pointer
+ * @vlan_proto: destination address for VLAN protocol
+ * @vlan_tci: destination address for VLAN TCI
+ *
+ * Copy VLAN tag (if was stripped) and corresponding protocol
+ * to the destination address.
+ */
+static int ice_xdp_rx_vlan_tag(const struct xdp_md *ctx, __be16 *vlan_proto,
+                              u16 *vlan_tci)
+{
+       const struct ice_xdp_buff *xdp_ext = (void *)ctx;
+
+       *vlan_proto = xdp_ext->pkt_ctx->vlan_proto;
+       if (!*vlan_proto)
+               return -ENODATA;
+
+       *vlan_tci = ice_get_vlan_tci(xdp_ext->eop_desc);
+       if (!*vlan_tci)
+               return -ENODATA;
+
+       return 0;
+}
+
 const struct xdp_metadata_ops ice_xdp_md_ops = {
        .xmo_rx_timestamp               = ice_xdp_rx_hw_ts,
        .xmo_rx_hash                    = ice_xdp_rx_hash,
+       .xmo_rx_vlan_tag                = ice_xdp_rx_vlan_tag,
 };
index 81b8856d8e1340b896a67ad5d6e1a6012fb72803..3893af1c11f3bc753f43e73cf29ed17a0d0886d5 100644 (file)
@@ -84,7 +84,7 @@ ice_build_ctob(u64 td_cmd, u64 td_offset, unsigned int size, u64 td_tag)
 }
 
 /**
- * ice_get_vlan_tag_from_rx_desc - get VLAN from Rx flex descriptor
+ * ice_get_vlan_tci - get VLAN TCI from Rx flex descriptor
  * @rx_desc: Rx 32b flex descriptor with RXDID=2
  *
  * The OS and current PF implementation only support stripping a single VLAN tag
@@ -92,7 +92,7 @@ ice_build_ctob(u64 td_cmd, u64 td_offset, unsigned int size, u64 td_tag)
  * one is found return the tag, else return 0 to mean no VLAN tag was found.
  */
 static inline u16
-ice_get_vlan_tag_from_rx_desc(union ice_32b_rx_flex_desc *rx_desc)
+ice_get_vlan_tci(const union ice_32b_rx_flex_desc *rx_desc)
 {
        u16 stat_err_bits;
 
index 11b6114ab83d1b2bad885973dc28eb09690fe7c5..5d1ae8e4058a4ae43bb0fb2be98070cf1f2e9559 100644 (file)
@@ -868,7 +868,7 @@ int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring, int budget)
                struct xdp_buff *xdp;
                struct sk_buff *skb;
                u16 stat_err_bits;
-               u16 vlan_tag = 0;
+               u16 vlan_tci;
 
                rx_desc = ICE_RX_DESC(rx_ring, ntc);
 
@@ -946,10 +946,10 @@ construct_skb:
                total_rx_bytes += skb->len;
                total_rx_packets++;
 
-               vlan_tag = ice_get_vlan_tag_from_rx_desc(rx_desc);
+               vlan_tci = ice_get_vlan_tci(rx_desc);
 
                ice_process_skb_fields(rx_ring, rx_desc, skb);
-               ice_receive_skb(rx_ring, skb, vlan_tag);
+               ice_receive_skb(rx_ring, skb, vlan_tci);
        }
 
        rx_ring->next_to_clean = ntc;