Commit 67d2656b authored by Diana Wang's avatar Diana Wang Committed by David S. Miller
Browse files

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: default avatarDiana Wang <na.wang@corigine.com>
Reviewed-by: default avatarLouis Peens <louis.peens@corigine.com>
Signed-off-by: default avatarSimon Horman <simon.horman@corigine.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5ee4bba2
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@

#include <linux/bpf_trace.h>
#include <linux/netdevice.h>
#include <linux/bitfield.h>

#include "../nfp_app.h"
#include "../nfp_net.h"
@@ -703,7 +704,7 @@ bool
nfp_nfd3_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;
@@ -721,6 +722,17 @@ nfp_nfd3_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;
@@ -1049,9 +1061,11 @@ static int nfp_nfd3_rx(struct nfp_net_rx_ring *rx_ring, int budget)
		}
#endif

		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_nfd3_rx_drop(dp, r_vec, rx_ring, NULL, skb);
			continue;
		}

		if (meta_len_xdp)
			skb_metadata_set(skb, meta_len_xdp);

+1 −0
Original line number Diff line number Diff line
@@ -247,6 +247,7 @@ nfp_nfd3_print_tx_descs(struct seq_file *file,
	 NFP_NET_CFG_CTRL_L2BC | NFP_NET_CFG_CTRL_L2MC |		\
	 NFP_NET_CFG_CTRL_RXCSUM | NFP_NET_CFG_CTRL_TXCSUM |		\
	 NFP_NET_CFG_CTRL_RXVLAN | NFP_NET_CFG_CTRL_TXVLAN |		\
	 NFP_NET_CFG_CTRL_RXVLAN_V2 | NFP_NET_CFG_CTRL_RXQINQ |		\
	 NFP_NET_CFG_CTRL_GATHER | NFP_NET_CFG_CTRL_LSO |		\
	 NFP_NET_CFG_CTRL_CTAG_FILTER | NFP_NET_CFG_CTRL_CMSG_DATA |	\
	 NFP_NET_CFG_CTRL_RINGCFG | NFP_NET_CFG_CTRL_RSS |		\
+6 −3
Original line number Diff line number Diff line
@@ -94,9 +94,12 @@ static void nfp_nfd3_xsk_rx_skb(struct nfp_net_rx_ring *rx_ring,

	nfp_nfd3_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))) {
		dev_kfree_skb_any(skb);
		nfp_net_xsk_rx_drop(r_vec, xrxbuf);
		return;
	}

	if (meta_xdp)
		skb_metadata_set(skb,
				 xrxbuf->xdp->data - xrxbuf->xdp->data_meta);
+17 −4
Original line number Diff line number Diff line
@@ -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);

+1 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ nfp_nfdk_print_tx_descs(struct seq_file *file,
	 NFP_NET_CFG_CTRL_L2BC | NFP_NET_CFG_CTRL_L2MC |		\
	 NFP_NET_CFG_CTRL_RXCSUM | NFP_NET_CFG_CTRL_TXCSUM |		\
	 NFP_NET_CFG_CTRL_RXVLAN |					\
	 NFP_NET_CFG_CTRL_RXVLAN_V2 | NFP_NET_CFG_CTRL_RXQINQ |		\
	 NFP_NET_CFG_CTRL_GATHER | NFP_NET_CFG_CTRL_LSO |		\
	 NFP_NET_CFG_CTRL_CTAG_FILTER | NFP_NET_CFG_CTRL_CMSG_DATA |	\
	 NFP_NET_CFG_CTRL_RINGCFG | NFP_NET_CFG_CTRL_IRQMOD |		\
Loading