From: Martin Habets <mhab...@solarflare.com> If it is not supported we simply disable the feature.
For the feature to work we need firmware filter support for OUTER_VID + LOC_MAC and for OUTER_VID + LOC_MAC_IG. The low-latency firmware can match on OUTER_VID + LOC_MAC but not on OUTER_VID + LOC_MAC_IG. For the capture packet firmware it is the other way around. Only the full-feature variant can match on both combinations. Incorporates a fix by Andrew Rybchenko <andrew.rybche...@oktetlabs.ru> in the net_dev->[hw_]features handling. Signed-off-by: Edward Cree <ec...@solarflare.com> --- drivers/net/ethernet/sfc/ef10.c | 13 +++++++++++++ drivers/net/ethernet/sfc/net_driver.h | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 626054d..353ceef 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -3977,6 +3977,7 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx) MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PARSER_DISP_INFO_IN_LEN); MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX); struct efx_ef10_nic_data *nic_data = efx->nic_data; + struct net_device *net_dev = efx->net_dev; unsigned int pd_match_pri, pd_match_count; struct efx_ef10_filter_table *table; struct efx_ef10_vlan *vlan; @@ -4026,6 +4027,18 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx) } } + if ((efx_supported_features(efx) & NETIF_F_HW_VLAN_CTAG_FILTER) && + !(efx_ef10_filter_match_supported(table, + (EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC)) && + efx_ef10_filter_match_supported(table, + (EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC_IG)))) { + netif_info(efx, probe, net_dev, + "VLAN filters are not supported in this firmware variant\n"); + net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; + efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; + net_dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; + } + table->entry = vzalloc(HUNT_FILTER_TBL_ROWS * sizeof(*table->entry)); if (!table->entry) { rc = -ENOMEM; diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 7613f79..9ff062a 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -1524,4 +1524,16 @@ static inline void efx_xmit_hwtstamp_pending(struct sk_buff *skb) skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; } +/* Get all supported features. + * If a feature is not fixed, it is present in hw_features. + * If a feature is fixed, it does not present in hw_features, but + * always in features. + */ +static inline netdev_features_t efx_supported_features(const struct efx_nic *efx) +{ + const struct net_device *net_dev = efx->net_dev; + + return net_dev->features | net_dev->hw_features; +} + #endif /* EFX_NET_DRIVER_H */