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

Merge branch 'sfc-encapsulated-filters'

Edward Cree says:

====================
sfc: encapsulated filters

This series adds support for setting up filters for encapsulated traffic on
SFC 8000-series adapters, which recognise VXLAN, GENEVE and NVGRE packets by
parsing packet headers.  (VXLAN and GENEVE will only be recognised if the
driver on the primary PF has notified the firmware of relevant UDP ports,
which this driver does not yet do.)
While the driver currently has no way of using these filters for flow
steering, it is nonetheless necessary to insert catch-all (aka 'default')
filters to direct this traffic, similar to the existing unencapsulated uni-
and multi-cast catch-all filters, as otherwise the traffic will be dropped
by the NIC - implementation details of the hardware filtering mean that the
traffic will not get matched on outer MAC address to unencapsulated catch-
all filters.  (Yes, this is a mess.)
Although this is, therefore, fixing a bug in the existing driver, it's a bug
which has existed since 8000 series support was added, and the fix involves
quite a big patch with an 'adding features' flavour to it, hence why this is
for net-next rather than net and stable.

v2: move netif_cond_dbg into netdevice.h and its own patch
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2b368b23 9b410801
This diff is collapsed.
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* @EFX_FILTER_MATCH_OUTER_VID: Match by outer VLAN ID * @EFX_FILTER_MATCH_OUTER_VID: Match by outer VLAN ID
* @EFX_FILTER_MATCH_IP_PROTO: Match by IP transport protocol * @EFX_FILTER_MATCH_IP_PROTO: Match by IP transport protocol
* @EFX_FILTER_MATCH_LOC_MAC_IG: Match by local MAC address I/G bit. * @EFX_FILTER_MATCH_LOC_MAC_IG: Match by local MAC address I/G bit.
* @EFX_FILTER_MATCH_ENCAP_TYPE: Match by encapsulation type.
* Used for RX default unicast and multicast/broadcast filters. * Used for RX default unicast and multicast/broadcast filters.
* *
* Only some combinations are supported, depending on NIC type: * Only some combinations are supported, depending on NIC type:
...@@ -54,6 +55,7 @@ enum efx_filter_match_flags { ...@@ -54,6 +55,7 @@ enum efx_filter_match_flags {
EFX_FILTER_MATCH_OUTER_VID = 0x0100, EFX_FILTER_MATCH_OUTER_VID = 0x0100,
EFX_FILTER_MATCH_IP_PROTO = 0x0200, EFX_FILTER_MATCH_IP_PROTO = 0x0200,
EFX_FILTER_MATCH_LOC_MAC_IG = 0x0400, EFX_FILTER_MATCH_LOC_MAC_IG = 0x0400,
EFX_FILTER_MATCH_ENCAP_TYPE = 0x0800,
}; };
/** /**
...@@ -98,6 +100,26 @@ enum efx_filter_flags { ...@@ -98,6 +100,26 @@ enum efx_filter_flags {
EFX_FILTER_FLAG_TX = 0x10, EFX_FILTER_FLAG_TX = 0x10,
}; };
/** enum efx_encap_type - types of encapsulation
* @EFX_ENCAP_TYPE_NONE: no encapsulation
* @EFX_ENCAP_TYPE_VXLAN: VXLAN encapsulation
* @EFX_ENCAP_TYPE_NVGRE: NVGRE encapsulation
* @EFX_ENCAP_TYPE_GENEVE: GENEVE encapsulation
* @EFX_ENCAP_FLAG_IPV6: indicates IPv6 outer frame
*
* Contains both enumerated types and flags.
* To get just the type, OR with @EFX_ENCAP_TYPES_MASK.
*/
enum efx_encap_type {
EFX_ENCAP_TYPE_NONE = 0,
EFX_ENCAP_TYPE_VXLAN = 1,
EFX_ENCAP_TYPE_NVGRE = 2,
EFX_ENCAP_TYPE_GENEVE = 3,
EFX_ENCAP_TYPES_MASK = 7,
EFX_ENCAP_FLAG_IPV6 = 8,
};
/** /**
* struct efx_filter_spec - specification for a hardware filter * struct efx_filter_spec - specification for a hardware filter
* @match_flags: Match type flags, from &enum efx_filter_match_flags * @match_flags: Match type flags, from &enum efx_filter_match_flags
...@@ -118,6 +140,8 @@ enum efx_filter_flags { ...@@ -118,6 +140,8 @@ enum efx_filter_flags {
* @rem_host: Remote IP host to match, if %EFX_FILTER_MATCH_REM_HOST is set * @rem_host: Remote IP host to match, if %EFX_FILTER_MATCH_REM_HOST is set
* @loc_port: Local TCP/UDP port to match, if %EFX_FILTER_MATCH_LOC_PORT is set * @loc_port: Local TCP/UDP port to match, if %EFX_FILTER_MATCH_LOC_PORT is set
* @rem_port: Remote TCP/UDP port to match, if %EFX_FILTER_MATCH_REM_PORT is set * @rem_port: Remote TCP/UDP port to match, if %EFX_FILTER_MATCH_REM_PORT is set
* @encap_type: Encapsulation type to match (from &enum efx_encap_type), if
* %EFX_FILTER_MATCH_ENCAP_TYPE is set
* *
* The efx_filter_init_rx() or efx_filter_init_tx() function *must* be * The efx_filter_init_rx() or efx_filter_init_tx() function *must* be
* used to initialise the structure. The efx_filter_set_*() functions * used to initialise the structure. The efx_filter_set_*() functions
...@@ -144,7 +168,8 @@ struct efx_filter_spec { ...@@ -144,7 +168,8 @@ struct efx_filter_spec {
__be32 rem_host[4]; __be32 rem_host[4];
__be16 loc_port; __be16 loc_port;
__be16 rem_port; __be16 rem_port;
/* total 64 bytes */ u32 encap_type:4;
/* total 65 bytes */
}; };
enum { enum {
...@@ -269,4 +294,18 @@ static inline int efx_filter_set_mc_def(struct efx_filter_spec *spec) ...@@ -269,4 +294,18 @@ static inline int efx_filter_set_mc_def(struct efx_filter_spec *spec)
return 0; return 0;
} }
static inline void efx_filter_set_encap_type(struct efx_filter_spec *spec,
enum efx_encap_type encap_type)
{
spec->match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
spec->encap_type = encap_type;
}
static inline enum efx_encap_type efx_filter_get_encap_type(
const struct efx_filter_spec *spec)
{
if (spec->match_flags & EFX_FILTER_MATCH_ENCAP_TYPE)
return spec->encap_type;
return EFX_ENCAP_TYPE_NONE;
}
#endif /* EFX_FILTER_H */ #endif /* EFX_FILTER_H */
...@@ -837,9 +837,7 @@ static int _efx_mcdi_rpc(struct efx_nic *efx, unsigned int cmd, ...@@ -837,9 +837,7 @@ static int _efx_mcdi_rpc(struct efx_nic *efx, unsigned int cmd,
outbuf, outlen, outlen_actual, outbuf, outlen, outlen_actual,
quiet, NULL, raw_rc); quiet, NULL, raw_rc);
} else { } else {
netif_printk(efx, hw, netif_cond_dbg(efx, hw, efx->net_dev, rc == -EPERM, err,
rc == -EPERM ? KERN_DEBUG : KERN_ERR,
efx->net_dev,
"MC command 0x%x failed after proxy auth rc=%d\n", "MC command 0x%x failed after proxy auth rc=%d\n",
cmd, rc); cmd, rc);
...@@ -1084,8 +1082,7 @@ void efx_mcdi_display_error(struct efx_nic *efx, unsigned cmd, ...@@ -1084,8 +1082,7 @@ void efx_mcdi_display_error(struct efx_nic *efx, unsigned cmd,
code = MCDI_DWORD(outbuf, ERR_CODE); code = MCDI_DWORD(outbuf, ERR_CODE);
if (outlen >= MC_CMD_ERR_ARG_OFST + 4) if (outlen >= MC_CMD_ERR_ARG_OFST + 4)
err_arg = MCDI_DWORD(outbuf, ERR_ARG); err_arg = MCDI_DWORD(outbuf, ERR_ARG);
netif_printk(efx, hw, rc == -EPERM ? KERN_DEBUG : KERN_ERR, netif_cond_dbg(efx, hw, efx->net_dev, rc == -EPERM, err,
efx->net_dev,
"MC command 0x%x inlen %zu failed rc=%d (raw=%d) arg=%d\n", "MC command 0x%x inlen %zu failed rc=%d (raw=%d) arg=%d\n",
cmd, inlen, rc, code, err_arg); cmd, inlen, rc, code, err_arg);
} }
...@@ -2057,8 +2054,8 @@ int efx_mcdi_get_workarounds(struct efx_nic *efx, unsigned int *impl_out, ...@@ -2057,8 +2054,8 @@ int efx_mcdi_get_workarounds(struct efx_nic *efx, unsigned int *impl_out,
/* Older firmware lacks GET_WORKAROUNDS and this isn't especially /* Older firmware lacks GET_WORKAROUNDS and this isn't especially
* terrifying. The call site will have to deal with it though. * terrifying. The call site will have to deal with it though.
*/ */
netif_printk(efx, hw, rc == -ENOSYS ? KERN_DEBUG : KERN_ERR, netif_cond_dbg(efx, hw, efx->net_dev, rc == -ENOSYS, err,
efx->net_dev, "%s: failed rc=%d\n", __func__, rc); "%s: failed rc=%d\n", __func__, rc);
return rc; return rc;
} }
......
...@@ -4347,6 +4347,15 @@ do { \ ...@@ -4347,6 +4347,15 @@ do { \
}) })
#endif #endif
/* if @cond then downgrade to debug, else print at @level */
#define netif_cond_dbg(priv, type, netdev, cond, level, fmt, args...) \
do { \
if (cond) \
netif_dbg(priv, type, netdev, fmt, ##args); \
else \
netif_ ## level(priv, type, netdev, fmt, ##args); \
} while (0)
#if defined(VERBOSE_DEBUG) #if defined(VERBOSE_DEBUG)
#define netif_vdbg netif_dbg #define netif_vdbg netif_dbg
#else #else
......
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