mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-29 16:25:42 -04:00
Merge branch 'nfp-vlan-strip-and-insert'
Simon Horman says: ==================== nfp: support VLAN strip and insert this series adds support to the NFP driver for HW offload of both: * RX VLAN ctag/stag strip * TX VLAN ctag insert ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -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"
|
||||
@@ -166,30 +167,35 @@ nfp_nfd3_tx_csum(struct nfp_net_dp *dp, struct nfp_net_r_vector *r_vec,
|
||||
u64_stats_update_end(&r_vec->tx_sync);
|
||||
}
|
||||
|
||||
static int nfp_nfd3_prep_tx_meta(struct sk_buff *skb, u64 tls_handle)
|
||||
static int nfp_nfd3_prep_tx_meta(struct nfp_net_dp *dp, struct sk_buff *skb, u64 tls_handle)
|
||||
{
|
||||
struct metadata_dst *md_dst = skb_metadata_dst(skb);
|
||||
unsigned char *data;
|
||||
bool vlan_insert;
|
||||
u32 meta_id = 0;
|
||||
int md_bytes;
|
||||
|
||||
if (likely(!md_dst && !tls_handle))
|
||||
return 0;
|
||||
if (unlikely(md_dst && md_dst->type != METADATA_HW_PORT_MUX)) {
|
||||
if (!tls_handle)
|
||||
return 0;
|
||||
md_dst = NULL;
|
||||
if (unlikely(md_dst || tls_handle)) {
|
||||
if (unlikely(md_dst && md_dst->type != METADATA_HW_PORT_MUX))
|
||||
md_dst = NULL;
|
||||
}
|
||||
|
||||
md_bytes = 4 + !!md_dst * 4 + !!tls_handle * 8;
|
||||
vlan_insert = skb_vlan_tag_present(skb) && (dp->ctrl & NFP_NET_CFG_CTRL_TXVLAN_V2);
|
||||
|
||||
if (!(md_dst || tls_handle || vlan_insert))
|
||||
return 0;
|
||||
|
||||
md_bytes = sizeof(meta_id) +
|
||||
!!md_dst * NFP_NET_META_PORTID_SIZE +
|
||||
!!tls_handle * NFP_NET_META_CONN_HANDLE_SIZE +
|
||||
vlan_insert * NFP_NET_META_VLAN_SIZE;
|
||||
|
||||
if (unlikely(skb_cow_head(skb, md_bytes)))
|
||||
return -ENOMEM;
|
||||
|
||||
meta_id = 0;
|
||||
data = skb_push(skb, md_bytes) + md_bytes;
|
||||
if (md_dst) {
|
||||
data -= 4;
|
||||
data -= NFP_NET_META_PORTID_SIZE;
|
||||
put_unaligned_be32(md_dst->u.port_info.port_id, data);
|
||||
meta_id = NFP_NET_META_PORTID;
|
||||
}
|
||||
@@ -197,13 +203,23 @@ static int nfp_nfd3_prep_tx_meta(struct sk_buff *skb, u64 tls_handle)
|
||||
/* conn handle is opaque, we just use u64 to be able to quickly
|
||||
* compare it to zero
|
||||
*/
|
||||
data -= 8;
|
||||
data -= NFP_NET_META_CONN_HANDLE_SIZE;
|
||||
memcpy(data, &tls_handle, sizeof(tls_handle));
|
||||
meta_id <<= NFP_NET_META_FIELD_SIZE;
|
||||
meta_id |= NFP_NET_META_CONN_HANDLE;
|
||||
}
|
||||
if (vlan_insert) {
|
||||
data -= NFP_NET_META_VLAN_SIZE;
|
||||
/* data type of skb->vlan_proto is __be16
|
||||
* so it fills metadata without calling put_unaligned_be16
|
||||
*/
|
||||
memcpy(data, &skb->vlan_proto, sizeof(skb->vlan_proto));
|
||||
put_unaligned_be16(skb_vlan_tag_get(skb), data + sizeof(skb->vlan_proto));
|
||||
meta_id <<= NFP_NET_META_FIELD_SIZE;
|
||||
meta_id |= NFP_NET_META_VLAN;
|
||||
}
|
||||
|
||||
data -= 4;
|
||||
data -= sizeof(meta_id);
|
||||
put_unaligned_be32(meta_id, data);
|
||||
|
||||
return md_bytes;
|
||||
@@ -257,7 +273,7 @@ netdev_tx_t nfp_nfd3_tx(struct sk_buff *skb, struct net_device *netdev)
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
md_bytes = nfp_nfd3_prep_tx_meta(skb, tls_handle);
|
||||
md_bytes = nfp_nfd3_prep_tx_meta(dp, skb, tls_handle);
|
||||
if (unlikely(md_bytes < 0))
|
||||
goto err_flush;
|
||||
|
||||
@@ -703,7 +719,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 +737,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 +1076,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);
|
||||
|
||||
|
||||
@@ -247,6 +247,8 @@ 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_TXVLAN_V2 | \
|
||||
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 | \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 | \
|
||||
|
||||
@@ -248,6 +248,8 @@ struct nfp_net_rx_desc {
|
||||
};
|
||||
|
||||
#define NFP_NET_META_FIELD_MASK GENMASK(NFP_NET_META_FIELD_SIZE - 1, 0)
|
||||
#define NFP_NET_VLAN_CTAG 0
|
||||
#define NFP_NET_VLAN_STAG 1
|
||||
|
||||
struct nfp_meta_parsed {
|
||||
u8 hash_type;
|
||||
@@ -256,6 +258,11 @@ struct nfp_meta_parsed {
|
||||
u32 mark;
|
||||
u32 portid;
|
||||
__wsum csum;
|
||||
struct {
|
||||
bool stripped;
|
||||
u8 tpid;
|
||||
u16 tci;
|
||||
} vlan;
|
||||
};
|
||||
|
||||
struct nfp_net_rx_hash {
|
||||
|
||||
@@ -1695,16 +1695,18 @@ static int nfp_net_set_features(struct net_device *netdev,
|
||||
|
||||
if (changed & NETIF_F_HW_VLAN_CTAG_RX) {
|
||||
if (features & NETIF_F_HW_VLAN_CTAG_RX)
|
||||
new_ctrl |= NFP_NET_CFG_CTRL_RXVLAN;
|
||||
new_ctrl |= nn->cap & NFP_NET_CFG_CTRL_RXVLAN_V2 ?:
|
||||
NFP_NET_CFG_CTRL_RXVLAN;
|
||||
else
|
||||
new_ctrl &= ~NFP_NET_CFG_CTRL_RXVLAN;
|
||||
new_ctrl &= ~NFP_NET_CFG_CTRL_RXVLAN_ANY;
|
||||
}
|
||||
|
||||
if (changed & NETIF_F_HW_VLAN_CTAG_TX) {
|
||||
if (features & NETIF_F_HW_VLAN_CTAG_TX)
|
||||
new_ctrl |= NFP_NET_CFG_CTRL_TXVLAN;
|
||||
new_ctrl |= nn->cap & NFP_NET_CFG_CTRL_TXVLAN_V2 ?:
|
||||
NFP_NET_CFG_CTRL_TXVLAN;
|
||||
else
|
||||
new_ctrl &= ~NFP_NET_CFG_CTRL_TXVLAN;
|
||||
new_ctrl &= ~NFP_NET_CFG_CTRL_TXVLAN_ANY;
|
||||
}
|
||||
|
||||
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
|
||||
@@ -1714,6 +1716,13 @@ static int nfp_net_set_features(struct net_device *netdev,
|
||||
new_ctrl &= ~NFP_NET_CFG_CTRL_CTAG_FILTER;
|
||||
}
|
||||
|
||||
if (changed & NETIF_F_HW_VLAN_STAG_RX) {
|
||||
if (features & NETIF_F_HW_VLAN_STAG_RX)
|
||||
new_ctrl |= NFP_NET_CFG_CTRL_RXQINQ;
|
||||
else
|
||||
new_ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ;
|
||||
}
|
||||
|
||||
if (changed & NETIF_F_SG) {
|
||||
if (features & NETIF_F_SG)
|
||||
new_ctrl |= NFP_NET_CFG_CTRL_GATHER;
|
||||
@@ -1742,6 +1751,27 @@ static int nfp_net_set_features(struct net_device *netdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static netdev_features_t
|
||||
nfp_net_fix_features(struct net_device *netdev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
if ((features & NETIF_F_HW_VLAN_CTAG_RX) &&
|
||||
(features & NETIF_F_HW_VLAN_STAG_RX)) {
|
||||
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
|
||||
features &= ~NETIF_F_HW_VLAN_CTAG_RX;
|
||||
netdev->wanted_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
|
||||
netdev_warn(netdev,
|
||||
"S-tag and C-tag stripping can't be enabled at the same time. Enabling S-tag stripping and disabling C-tag stripping\n");
|
||||
} else if (netdev->features & NETIF_F_HW_VLAN_STAG_RX) {
|
||||
features &= ~NETIF_F_HW_VLAN_STAG_RX;
|
||||
netdev->wanted_features &= ~NETIF_F_HW_VLAN_STAG_RX;
|
||||
netdev_warn(netdev,
|
||||
"S-tag and C-tag stripping can't be enabled at the same time. Enabling C-tag stripping and disabling S-tag stripping\n");
|
||||
}
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
||||
static netdev_features_t
|
||||
nfp_net_features_check(struct sk_buff *skb, struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
@@ -1977,6 +2007,7 @@ const struct net_device_ops nfp_nfd3_netdev_ops = {
|
||||
.ndo_change_mtu = nfp_net_change_mtu,
|
||||
.ndo_set_mac_address = nfp_net_set_mac_address,
|
||||
.ndo_set_features = nfp_net_set_features,
|
||||
.ndo_fix_features = nfp_net_fix_features,
|
||||
.ndo_features_check = nfp_net_features_check,
|
||||
.ndo_get_phys_port_name = nfp_net_get_phys_port_name,
|
||||
.ndo_bpf = nfp_net_xdp,
|
||||
@@ -2008,6 +2039,7 @@ const struct net_device_ops nfp_nfdk_netdev_ops = {
|
||||
.ndo_change_mtu = nfp_net_change_mtu,
|
||||
.ndo_set_mac_address = nfp_net_set_mac_address,
|
||||
.ndo_set_features = nfp_net_set_features,
|
||||
.ndo_fix_features = nfp_net_fix_features,
|
||||
.ndo_features_check = nfp_net_features_check,
|
||||
.ndo_get_phys_port_name = nfp_net_get_phys_port_name,
|
||||
.ndo_bpf = nfp_net_xdp,
|
||||
@@ -2061,7 +2093,7 @@ void nfp_net_info(struct nfp_net *nn)
|
||||
nn->fw_ver.extend, nn->fw_ver.class,
|
||||
nn->fw_ver.major, nn->fw_ver.minor,
|
||||
nn->max_mtu);
|
||||
nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
nn->cap,
|
||||
nn->cap & NFP_NET_CFG_CTRL_PROMISC ? "PROMISC " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_L2BC ? "L2BCFILT " : "",
|
||||
@@ -2070,6 +2102,9 @@ void nfp_net_info(struct nfp_net *nn)
|
||||
nn->cap & NFP_NET_CFG_CTRL_TXCSUM ? "TXCSUM " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_RXVLAN ? "RXVLAN " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_TXVLAN ? "TXVLAN " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_RXQINQ ? "RXQINQ " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_RXVLAN_V2 ? "RXVLANv2 " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_TXVLAN_V2 ? "TXVLAN2 " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_SCATTER ? "SCATTER " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_GATHER ? "GATHER " : "",
|
||||
nn->cap & NFP_NET_CFG_CTRL_LSO ? "TSO1 " : "",
|
||||
@@ -2357,31 +2392,40 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
|
||||
|
||||
netdev->vlan_features = netdev->hw_features;
|
||||
|
||||
if (nn->cap & NFP_NET_CFG_CTRL_RXVLAN) {
|
||||
if (nn->cap & NFP_NET_CFG_CTRL_RXVLAN_ANY) {
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
|
||||
nn->dp.ctrl |= NFP_NET_CFG_CTRL_RXVLAN;
|
||||
nn->dp.ctrl |= nn->cap & NFP_NET_CFG_CTRL_RXVLAN_V2 ?:
|
||||
NFP_NET_CFG_CTRL_RXVLAN;
|
||||
}
|
||||
if (nn->cap & NFP_NET_CFG_CTRL_TXVLAN) {
|
||||
if (nn->cap & NFP_NET_CFG_CTRL_TXVLAN_ANY) {
|
||||
if (nn->cap & NFP_NET_CFG_CTRL_LSO2) {
|
||||
nn_warn(nn, "Device advertises both TSO2 and TXVLAN. Refusing to enable TXVLAN.\n");
|
||||
} else {
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
|
||||
nn->dp.ctrl |= NFP_NET_CFG_CTRL_TXVLAN;
|
||||
nn->dp.ctrl |= nn->cap & NFP_NET_CFG_CTRL_TXVLAN_V2 ?:
|
||||
NFP_NET_CFG_CTRL_TXVLAN;
|
||||
}
|
||||
}
|
||||
if (nn->cap & NFP_NET_CFG_CTRL_CTAG_FILTER) {
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
nn->dp.ctrl |= NFP_NET_CFG_CTRL_CTAG_FILTER;
|
||||
}
|
||||
if (nn->cap & NFP_NET_CFG_CTRL_RXQINQ) {
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_STAG_RX;
|
||||
nn->dp.ctrl |= NFP_NET_CFG_CTRL_RXQINQ;
|
||||
}
|
||||
|
||||
netdev->features = netdev->hw_features;
|
||||
|
||||
if (nfp_app_has_tc(nn->app) && nn->port)
|
||||
netdev->hw_features |= NETIF_F_HW_TC;
|
||||
|
||||
/* Advertise but disable TSO by default. */
|
||||
netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
|
||||
nn->dp.ctrl &= ~NFP_NET_CFG_CTRL_LSO_ANY;
|
||||
/* Advertise but disable TSO by default.
|
||||
* C-Tag strip and S-Tag strip can't be supported simultaneously,
|
||||
* so enable C-Tag strip and disable S-Tag strip by default.
|
||||
*/
|
||||
netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_STAG_RX);
|
||||
nn->dp.ctrl &= ~(NFP_NET_CFG_CTRL_LSO_ANY | NFP_NET_CFG_CTRL_RXQINQ);
|
||||
|
||||
/* Finalise the netdev setup */
|
||||
switch (nn->dp.ops->version) {
|
||||
|
||||
@@ -31,10 +31,16 @@
|
||||
#define NFP_NET_LSO_MAX_HDR_SZ 255
|
||||
#define NFP_NET_LSO_MAX_SEGS 64
|
||||
|
||||
/* working with metadata vlan api (NFD version >= 2.0) */
|
||||
#define NFP_NET_META_VLAN_STRIP BIT(31)
|
||||
#define NFP_NET_META_VLAN_TPID_MASK GENMASK(19, 16)
|
||||
#define NFP_NET_META_VLAN_TCI_MASK GENMASK(15, 0)
|
||||
|
||||
/* Prepend field types */
|
||||
#define NFP_NET_META_FIELD_SIZE 4
|
||||
#define NFP_NET_META_HASH 1 /* next field carries hash type */
|
||||
#define NFP_NET_META_MARK 2
|
||||
#define NFP_NET_META_VLAN 4 /* ctag or stag type */
|
||||
#define NFP_NET_META_PORTID 5
|
||||
#define NFP_NET_META_CSUM 6 /* checksum complete type */
|
||||
#define NFP_NET_META_CONN_HANDLE 7
|
||||
@@ -42,6 +48,10 @@
|
||||
|
||||
#define NFP_META_PORT_ID_CTRL ~0U
|
||||
|
||||
/* Prepend field sizes */
|
||||
#define NFP_NET_META_VLAN_SIZE 4
|
||||
#define NFP_NET_META_PORTID_SIZE 4
|
||||
#define NFP_NET_META_CONN_HANDLE_SIZE 8
|
||||
/* Hash type pre-pended when a RSS hash was computed */
|
||||
#define NFP_NET_RSS_NONE 0
|
||||
#define NFP_NET_RSS_IPV4 1
|
||||
@@ -89,12 +99,15 @@
|
||||
#define NFP_NET_CFG_CTRL_LSO (0x1 << 10) /* LSO/TSO (version 1) */
|
||||
#define NFP_NET_CFG_CTRL_CTAG_FILTER (0x1 << 11) /* VLAN CTAG filtering */
|
||||
#define NFP_NET_CFG_CTRL_CMSG_DATA (0x1 << 12) /* RX cmsgs on data Qs */
|
||||
#define NFP_NET_CFG_CTRL_RXQINQ (0x1 << 13) /* Enable S-tag strip */
|
||||
#define NFP_NET_CFG_CTRL_RXVLAN_V2 (0x1 << 15) /* Enable C-tag strip */
|
||||
#define NFP_NET_CFG_CTRL_RINGCFG (0x1 << 16) /* Ring runtime changes */
|
||||
#define NFP_NET_CFG_CTRL_RSS (0x1 << 17) /* RSS (version 1) */
|
||||
#define NFP_NET_CFG_CTRL_IRQMOD (0x1 << 18) /* Interrupt moderation */
|
||||
#define NFP_NET_CFG_CTRL_MSIXAUTO (0x1 << 20) /* MSI-X auto-masking */
|
||||
#define NFP_NET_CFG_CTRL_TXRWB (0x1 << 21) /* Write-back of TX ring*/
|
||||
#define NFP_NET_CFG_CTRL_VEPA (0x1 << 22) /* Enable VEPA mode */
|
||||
#define NFP_NET_CFG_CTRL_TXVLAN_V2 (0x1 << 23) /* Enable VLAN C-tag insert*/
|
||||
#define NFP_NET_CFG_CTRL_VXLAN (0x1 << 24) /* VXLAN tunnel support */
|
||||
#define NFP_NET_CFG_CTRL_NVGRE (0x1 << 25) /* NVGRE tunnel support */
|
||||
#define NFP_NET_CFG_CTRL_BPF (0x1 << 27) /* BPF offload capable */
|
||||
@@ -111,6 +124,10 @@
|
||||
NFP_NET_CFG_CTRL_CSUM_COMPLETE)
|
||||
#define NFP_NET_CFG_CTRL_CHAIN_META (NFP_NET_CFG_CTRL_RSS2 | \
|
||||
NFP_NET_CFG_CTRL_CSUM_COMPLETE)
|
||||
#define NFP_NET_CFG_CTRL_RXVLAN_ANY (NFP_NET_CFG_CTRL_RXVLAN | \
|
||||
NFP_NET_CFG_CTRL_RXVLAN_V2)
|
||||
#define NFP_NET_CFG_CTRL_TXVLAN_ANY (NFP_NET_CFG_CTRL_TXVLAN | \
|
||||
NFP_NET_CFG_CTRL_TXVLAN_V2)
|
||||
|
||||
#define NFP_NET_CFG_UPDATE 0x0004
|
||||
#define NFP_NET_CFG_UPDATE_GEN (0x1 << 0) /* General update */
|
||||
|
||||
@@ -440,3 +440,27 @@ bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool nfp_net_vlan_strip(struct sk_buff *skb, const struct nfp_net_rx_desc *rxd,
|
||||
const struct nfp_meta_parsed *meta)
|
||||
{
|
||||
u16 tpid = 0, tci = 0;
|
||||
|
||||
if (rxd->rxd.flags & PCIE_DESC_RX_VLAN) {
|
||||
tpid = ETH_P_8021Q;
|
||||
tci = le16_to_cpu(rxd->rxd.vlan);
|
||||
} else if (meta->vlan.stripped) {
|
||||
if (meta->vlan.tpid == NFP_NET_VLAN_CTAG)
|
||||
tpid = ETH_P_8021Q;
|
||||
else if (meta->vlan.tpid == NFP_NET_VLAN_STAG)
|
||||
tpid = ETH_P_8021AD;
|
||||
else
|
||||
return false;
|
||||
|
||||
tci = meta->vlan.tci;
|
||||
}
|
||||
if (tpid)
|
||||
__vlan_hwaccel_put_tag(skb, htons(tpid), tci);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,8 @@ int nfp_net_tx_rings_prepare(struct nfp_net *nn, struct nfp_net_dp *dp);
|
||||
void nfp_net_rx_rings_free(struct nfp_net_dp *dp);
|
||||
void nfp_net_tx_rings_free(struct nfp_net_dp *dp);
|
||||
void nfp_net_rx_ring_reset(struct nfp_net_rx_ring *rx_ring);
|
||||
bool nfp_net_vlan_strip(struct sk_buff *skb, const struct nfp_net_rx_desc *rxd,
|
||||
const struct nfp_meta_parsed *meta);
|
||||
|
||||
enum nfp_nfd_version {
|
||||
NFP_NFD_VER_NFD3,
|
||||
|
||||
@@ -365,9 +365,9 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
|
||||
|
||||
netdev->vlan_features = netdev->hw_features;
|
||||
|
||||
if (repr_cap & NFP_NET_CFG_CTRL_RXVLAN)
|
||||
if (repr_cap & NFP_NET_CFG_CTRL_RXVLAN_ANY)
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
|
||||
if (repr_cap & NFP_NET_CFG_CTRL_TXVLAN) {
|
||||
if (repr_cap & NFP_NET_CFG_CTRL_TXVLAN_ANY) {
|
||||
if (repr_cap & NFP_NET_CFG_CTRL_LSO2)
|
||||
netdev_warn(netdev, "Device advertises both TSO2 and TXVLAN. Refusing to enable TXVLAN.\n");
|
||||
else
|
||||
@@ -375,11 +375,16 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
|
||||
}
|
||||
if (repr_cap & NFP_NET_CFG_CTRL_CTAG_FILTER)
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
if (repr_cap & NFP_NET_CFG_CTRL_RXQINQ)
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_STAG_RX;
|
||||
|
||||
netdev->features = netdev->hw_features;
|
||||
|
||||
/* Advertise but disable TSO by default. */
|
||||
netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
|
||||
/* Advertise but disable TSO by default.
|
||||
* C-Tag strip and S-Tag strip can't be supported simultaneously,
|
||||
* so enable C-Tag strip and disable S-Tag strip by default.
|
||||
*/
|
||||
netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_STAG_RX);
|
||||
netif_set_tso_max_segs(netdev, NFP_NET_LSO_MAX_SEGS);
|
||||
|
||||
netdev->priv_flags |= IFF_NO_QUEUE | IFF_DISABLE_NETPOLL;
|
||||
|
||||
Reference in New Issue
Block a user