summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
diff options
context:
space:
mode:
authorDiana Wang <na.wang@corigine.com>2022-07-02 09:35:50 +0200
committerDavid S. Miller <davem@davemloft.net>2022-07-04 10:44:08 +0100
commit67d2656b48f108bcf8819f05374c68cfedda3133 (patch)
tree08dd80cfbd486594fe4fcafd97d4b7d985dc799a /drivers/net/ethernet/netronome/nfp/nfdk/dp.c
parent5ee4bba272d171e797c1b3c7b5ff889c3a2f0ec9 (diff)
nfp: support RX VLAN ctag/stag strip
Add support for RX VLAN ctag/stag strip which may be configured via ethtool. e.g. # ethtool -K $DEV rx-vlan-offload on # ethtool -K $DEV rx-vlan-stag-hw-parse on Ctag-stripped and stag-stripped cannot be enabled at the same time because currently the kernel supports only one layer of VLAN stripping. The NIC supplies VLAN strip information as packet metadata. The fields of this VLAN metadata are: * strip flag: 1 for stripped; 0 for unstripped * tci: VLAN TCI ID * tpid: 1 for ETH_P_8021AD; 0 for ETH_P_8021Q Configuration control bits NFP_NET_CFG_CTRL_RXVLAN_V2 and NFP_NET_CFG_CTRL_RXQINQ are to signal availability of ctag-strip and stag-strip features of the firmware. Signed-off-by: Diana Wang <na.wang@corigine.com> Reviewed-by: Louis Peens <louis.peens@corigine.com> Signed-off-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/nfdk/dp.c')
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfdk/dp.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfdk/dp.c b/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
index 85dd376a6adc..34fe179513bf 100644
--- a/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
+++ b/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
@@ -716,7 +716,7 @@ static bool
nfp_nfdk_parse_meta(struct net_device *netdev, struct nfp_meta_parsed *meta,
void *data, void *pkt, unsigned int pkt_len, int meta_len)
{
- u32 meta_info;
+ u32 meta_info, vlan_info;
meta_info = get_unaligned_be32(data);
data += 4;
@@ -734,6 +734,17 @@ nfp_nfdk_parse_meta(struct net_device *netdev, struct nfp_meta_parsed *meta,
meta->mark = get_unaligned_be32(data);
data += 4;
break;
+ case NFP_NET_META_VLAN:
+ vlan_info = get_unaligned_be32(data);
+ if (FIELD_GET(NFP_NET_META_VLAN_STRIP, vlan_info)) {
+ meta->vlan.stripped = true;
+ meta->vlan.tpid = FIELD_GET(NFP_NET_META_VLAN_TPID_MASK,
+ vlan_info);
+ meta->vlan.tci = FIELD_GET(NFP_NET_META_VLAN_TCI_MASK,
+ vlan_info);
+ }
+ data += 4;
+ break;
case NFP_NET_META_PORTID:
meta->portid = get_unaligned_be32(data);
data += 4;
@@ -1169,9 +1180,11 @@ static int nfp_nfdk_rx(struct nfp_net_rx_ring *rx_ring, int budget)
nfp_nfdk_rx_csum(dp, r_vec, rxd, &meta, skb);
- if (rxd->rxd.flags & PCIE_DESC_RX_VLAN)
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
- le16_to_cpu(rxd->rxd.vlan));
+ if (unlikely(!nfp_net_vlan_strip(skb, rxd, &meta))) {
+ nfp_nfdk_rx_drop(dp, r_vec, rx_ring, NULL, skb);
+ continue;
+ }
+
if (meta_len_xdp)
skb_metadata_set(skb, meta_len_xdp);