Commit fd4b96c4 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 5ee4bba2 d80702ff
......@@ -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;
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment