diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-08-31 16:43:06 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-08-31 16:43:06 -0700 |
commit | 9e9fb7655ed585da8f468e29221f0ba194a5f613 (patch) | |
tree | d2c51887389b8297635a5b90d5766897f00fe928 /drivers/net/ethernet/mellanox/mlxsw | |
parent | 86ac54e79fe09b34c52691a780a6e31d12fa57f4 (diff) | |
parent | 29ce8f9701072fc221d9c38ad952de1a9578f95c (diff) |
Merge tag 'net-next-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Jakub Kicinski:
"Core:
- Enable memcg accounting for various networking objects.
BPF:
- Introduce bpf timers.
- Add perf link and opaque bpf_cookie which the program can read out
again, to be used in libbpf-based USDT library.
- Add bpf_task_pt_regs() helper to access user space pt_regs in
kprobes, to help user space stack unwinding.
- Add support for UNIX sockets for BPF sockmap.
- Extend BPF iterator support for UNIX domain sockets.
- Allow BPF TCP congestion control progs and bpf iterators to call
bpf_setsockopt(), e.g. to switch to another congestion control
algorithm.
Protocols:
- Support IOAM Pre-allocated Trace with IPv6.
- Support Management Component Transport Protocol.
- bridge: multicast: add vlan support.
- netfilter: add hooks for the SRv6 lightweight tunnel driver.
- tcp:
- enable mid-stream window clamping (by user space or BPF)
- allow data-less, empty-cookie SYN with TFO_SERVER_COOKIE_NOT_REQD
- more accurate DSACK processing for RACK-TLP
- mptcp:
- add full mesh path manager option
- add partial support for MP_FAIL
- improve use of backup subflows
- optimize option processing
- af_unix: add OOB notification support.
- ipv6: add IFLA_INET6_RA_MTU to expose MTU value advertised by the
router.
- mac80211: Target Wake Time support in AP mode.
- can: j1939: extend UAPI to notify about RX status.
Driver APIs:
- Add page frag support in page pool API.
- Many improvements to the DSA (distributed switch) APIs.
- ethtool: extend IRQ coalesce uAPI with timer reset modes.
- devlink: control which auxiliary devices are created.
- Support CAN PHYs via the generic PHY subsystem.
- Proper cross-chip support for tag_8021q.
- Allow TX forwarding for the software bridge data path to be
offloaded to capable devices.
Drivers:
- veth: more flexible channels number configuration.
- openvswitch: introduce per-cpu upcall dispatch.
- Add internet mix (IMIX) mode to pktgen.
- Transparently handle XDP operations in the bonding driver.
- Add LiteETH network driver.
- Renesas (ravb):
- support Gigabit Ethernet IP
- NXP Ethernet switch (sja1105):
- fast aging support
- support for "H" switch topologies
- traffic termination for ports under VLAN-aware bridge
- Intel 1G Ethernet
- support getcrosststamp() with PCIe PTM (Precision Time
Measurement) for better time sync
- support Credit-Based Shaper (CBS) offload, enabling HW traffic
prioritization and bandwidth reservation
- Broadcom Ethernet (bnxt)
- support pulse-per-second output
- support larger Rx rings
- Mellanox Ethernet (mlx5)
- support ethtool RSS contexts and MQPRIO channel mode
- support LAG offload with bridging
- support devlink rate limit API
- support packet sampling on tunnels
- Huawei Ethernet (hns3):
- basic devlink support
- add extended IRQ coalescing support
- report extended link state
- Netronome Ethernet (nfp):
- add conntrack offload support
- Broadcom WiFi (brcmfmac):
- add WPA3 Personal with FT to supported cipher suites
- support 43752 SDIO device
- Intel WiFi (iwlwifi):
- support scanning hidden 6GHz networks
- support for a new hardware family (Bz)
- Xen pv driver:
- harden netfront against malicious backends
- Qualcomm mobile
- ipa: refactor power management and enable automatic suspend
- mhi: move MBIM to WWAN subsystem interfaces
Refactor:
- Ambient BPF run context and cgroup storage cleanup.
- Compat rework for ndo_ioctl.
Old code removal:
- prism54 remove the obsoleted driver, deprecated by the p54 driver.
- wan: remove sbni/granch driver"
* tag 'net-next-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1715 commits)
net: Add depends on OF_NET for LiteX's LiteETH
ipv6: seg6: remove duplicated include
net: hns3: remove unnecessary spaces
net: hns3: add some required spaces
net: hns3: clean up a type mismatch warning
net: hns3: refine function hns3_set_default_feature()
ipv6: remove duplicated 'net/lwtunnel.h' include
net: w5100: check return value after calling platform_get_resource()
net/mlxbf_gige: Make use of devm_platform_ioremap_resourcexxx()
net: mdio: mscc-miim: Make use of the helper function devm_platform_ioremap_resource()
net: mdio-ipq4019: Make use of devm_platform_ioremap_resource()
fou: remove sparse errors
ipv4: fix endianness issue in inet_rtm_getroute_build_skb()
octeontx2-af: Set proper errorcode for IPv4 checksum errors
octeontx2-af: Fix static code analyzer reported issues
octeontx2-af: Fix mailbox errors in nix_rss_flowkey_cfg
octeontx2-af: Fix loop in free and unmap counter
af_unix: fix potential NULL deref in unix_dgram_connect()
dpaa2-eth: Replace strlcpy with strscpy
octeontx2-af: Use NDC TX for transmit packet data
...
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/core.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 84 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c | 94 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 44 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 32 |
10 files changed, 187 insertions, 92 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Kconfig b/drivers/net/ethernet/mellanox/mlxsw/Kconfig index 12871c8dc7c1..d1ae248e125c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/Kconfig +++ b/drivers/net/ethernet/mellanox/mlxsw/Kconfig @@ -58,10 +58,10 @@ config MLXSW_SPECTRUM depends on NET_IPGRE || NET_IPGRE=n depends on IPV6_GRE || IPV6_GRE=n depends on VXLAN || VXLAN=n + depends on PTP_1588_CLOCK_OPTIONAL select GENERIC_ALLOCATOR select PARMAN select OBJAGG - imply PTP_1588_CLOCK select NET_PTP_CLASSIFY if PTP_1588_CLOCK default m help diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index e775f08fb464..f080fab3de2b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -1927,7 +1927,8 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, if (!reload) { alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size; - devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size); + devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size, + mlxsw_bus_info->dev); if (!devlink) { err = -ENOMEM; goto err_devlink_alloc; @@ -1974,7 +1975,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, goto err_emad_init; if (!reload) { - err = devlink_register(devlink, mlxsw_bus_info->dev); + err = devlink_register(devlink); if (err) goto err_devlink_register; } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 88699e678544..250c5a24264d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -1207,7 +1207,7 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = { .ndo_vlan_rx_kill_vid = mlxsw_sp_port_kill_vid, .ndo_set_features = mlxsw_sp_set_features, .ndo_get_devlink_port = mlxsw_sp_port_get_devlink_port, - .ndo_do_ioctl = mlxsw_sp_port_ioctl, + .ndo_eth_ioctl = mlxsw_sp_port_ioctl, }; static int @@ -2717,6 +2717,22 @@ mlxsw_sp_sample_trigger_params_unset(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_netdevice_event(struct notifier_block *unused, unsigned long event, void *ptr); +#define MLXSW_SP_DEFAULT_PARSING_DEPTH 96 +#define MLXSW_SP_INCREASED_PARSING_DEPTH 128 +#define MLXSW_SP_DEFAULT_VXLAN_UDP_DPORT 4789 + +static void mlxsw_sp_parsing_init(struct mlxsw_sp *mlxsw_sp) +{ + mlxsw_sp->parsing.parsing_depth = MLXSW_SP_DEFAULT_PARSING_DEPTH; + mlxsw_sp->parsing.vxlan_udp_dport = MLXSW_SP_DEFAULT_VXLAN_UDP_DPORT; + mutex_init(&mlxsw_sp->parsing.lock); +} + +static void mlxsw_sp_parsing_fini(struct mlxsw_sp *mlxsw_sp) +{ + mutex_destroy(&mlxsw_sp->parsing.lock); +} + static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, const struct mlxsw_bus_info *mlxsw_bus_info, struct netlink_ext_ack *extack) @@ -2727,6 +2743,7 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, mlxsw_sp->core = mlxsw_core; mlxsw_sp->bus_info = mlxsw_bus_info; + mlxsw_sp_parsing_init(mlxsw_sp); mlxsw_core_emad_string_tlv_enable(mlxsw_core); err = mlxsw_sp_base_mac_get(mlxsw_sp); @@ -2926,6 +2943,7 @@ err_policers_init: mlxsw_sp_fids_fini(mlxsw_sp); err_fids_init: mlxsw_sp_kvdl_fini(mlxsw_sp); + mlxsw_sp_parsing_fini(mlxsw_sp); return err; } @@ -3046,6 +3064,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core) mlxsw_sp_policers_fini(mlxsw_sp); mlxsw_sp_fids_fini(mlxsw_sp); mlxsw_sp_kvdl_fini(mlxsw_sp); + mlxsw_sp_parsing_fini(mlxsw_sp); } /* Per-FID flood tables are used for both "true" 802.1D FIDs and emulated @@ -3611,6 +3630,69 @@ void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port) dev_put(mlxsw_sp_port->dev); } +int mlxsw_sp_parsing_depth_inc(struct mlxsw_sp *mlxsw_sp) +{ + char mprs_pl[MLXSW_REG_MPRS_LEN]; + int err = 0; + + mutex_lock(&mlxsw_sp->parsing.lock); + + if (refcount_inc_not_zero(&mlxsw_sp->parsing.parsing_depth_ref)) + goto out_unlock; + + mlxsw_reg_mprs_pack(mprs_pl, MLXSW_SP_INCREASED_PARSING_DEPTH, + mlxsw_sp->parsing.vxlan_udp_dport); + err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl); + if (err) + goto out_unlock; + + mlxsw_sp->parsing.parsing_depth = MLXSW_SP_INCREASED_PARSING_DEPTH; + refcount_set(&mlxsw_sp->parsing.parsing_depth_ref, 1); + +out_unlock: + mutex_unlock(&mlxsw_sp->parsing.lock); + return err; +} + +void mlxsw_sp_parsing_depth_dec(struct mlxsw_sp *mlxsw_sp) +{ + char mprs_pl[MLXSW_REG_MPRS_LEN]; + + mutex_lock(&mlxsw_sp->parsing.lock); + + if (!refcount_dec_and_test(&mlxsw_sp->parsing.parsing_depth_ref)) + goto out_unlock; + + mlxsw_reg_mprs_pack(mprs_pl, MLXSW_SP_DEFAULT_PARSING_DEPTH, + mlxsw_sp->parsing.vxlan_udp_dport); + mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl); + mlxsw_sp->parsing.parsing_depth = MLXSW_SP_DEFAULT_PARSING_DEPTH; + +out_unlock: + mutex_unlock(&mlxsw_sp->parsing.lock); +} + +int mlxsw_sp_parsing_vxlan_udp_dport_set(struct mlxsw_sp *mlxsw_sp, + __be16 udp_dport) +{ + char mprs_pl[MLXSW_REG_MPRS_LEN]; + int err; + + mutex_lock(&mlxsw_sp->parsing.lock); + + mlxsw_reg_mprs_pack(mprs_pl, mlxsw_sp->parsing.parsing_depth, + be16_to_cpu(udp_dport)); + err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl); + if (err) + goto out_unlock; + + mlxsw_sp->parsing.vxlan_udp_dport = be16_to_cpu(udp_dport); + +out_unlock: + mutex_unlock(&mlxsw_sp->parsing.lock); + return err; +} + static void mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port *mlxsw_sp_port, struct net_device *lag_dev) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index f99db88ee884..3a43cba6d23c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -148,6 +148,13 @@ struct mlxsw_sp_port_mapping { u8 lane; }; +struct mlxsw_sp_parsing { + refcount_t parsing_depth_ref; + u16 parsing_depth; + u16 vxlan_udp_dport; + struct mutex lock; /* Protects parsing configuration */ +}; + struct mlxsw_sp { struct mlxsw_sp_port **ports; struct mlxsw_core *core; @@ -173,6 +180,7 @@ struct mlxsw_sp { struct mlxsw_sp_counter_pool *counter_pool; struct mlxsw_sp_span *span; struct mlxsw_sp_trap *trap; + struct mlxsw_sp_parsing parsing; const struct mlxsw_sp_switchdev_ops *switchdev_ops; const struct mlxsw_sp_kvdl_ops *kvdl_ops; const struct mlxsw_afa_ops *afa_ops; @@ -652,6 +660,10 @@ struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev); struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev); void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port); struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev); +int mlxsw_sp_parsing_depth_inc(struct mlxsw_sp *mlxsw_sp); +void mlxsw_sp_parsing_depth_dec(struct mlxsw_sp *mlxsw_sp); +int mlxsw_sp_parsing_vxlan_udp_dport_set(struct mlxsw_sp *mlxsw_sp, + __be16 udp_dport); /* spectrum_dcb.c */ #ifdef CONFIG_MLXSW_SPECTRUM_DCB diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h index d8104fc6c900..98d1fdc25eac 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h @@ -29,7 +29,6 @@ struct mlxsw_sp_nve { unsigned int num_max_mc_entries[MLXSW_SP_L3_PROTO_MAX]; u32 tunnel_index; u16 ul_rif_index; /* Reserved for Spectrum */ - unsigned int inc_parsing_depth_refs; }; struct mlxsw_sp_nve_ops { diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c index b84bb4b65098..d018d2da5949 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c @@ -10,14 +10,6 @@ #include "spectrum.h" #include "spectrum_nve.h" -/* Eth (18B) | IPv6 (40B) | UDP (8B) | VxLAN (8B) | Eth (14B) | IPv6 (40B) - * - * In the worst case - where we have a VLAN tag on the outer Ethernet - * header and IPv6 in overlay and underlay - we need to parse 128 bytes - */ -#define MLXSW_SP_NVE_VXLAN_PARSING_DEPTH 128 -#define MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH 96 - #define MLXSW_SP_NVE_VXLAN_SUPPORTED_FLAGS (VXLAN_F_UDP_ZERO_CSUM_TX | \ VXLAN_F_LEARN) @@ -115,66 +107,6 @@ static void mlxsw_sp_nve_vxlan_config(const struct mlxsw_sp_nve *nve, config->udp_dport = cfg->dst_port; } -static int __mlxsw_sp_nve_parsing_set(struct mlxsw_sp *mlxsw_sp, - unsigned int parsing_depth, - __be16 udp_dport) -{ - char mprs_pl[MLXSW_REG_MPRS_LEN]; - - mlxsw_reg_mprs_pack(mprs_pl, parsing_depth, be16_to_cpu(udp_dport)); - return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl); -} - -static int mlxsw_sp_nve_parsing_set(struct mlxsw_sp *mlxsw_sp, - __be16 udp_dport) -{ - int parsing_depth = mlxsw_sp->nve->inc_parsing_depth_refs ? - MLXSW_SP_NVE_VXLAN_PARSING_DEPTH : - MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH; - - return __mlxsw_sp_nve_parsing_set(mlxsw_sp, parsing_depth, udp_dport); -} - -static int -__mlxsw_sp_nve_inc_parsing_depth_get(struct mlxsw_sp *mlxsw_sp, - __be16 udp_dport) -{ - int err; - - mlxsw_sp->nve->inc_parsing_depth_refs++; - - err = mlxsw_sp_nve_parsing_set(mlxsw_sp, udp_dport); - if (err) - goto err_nve_parsing_set; - return 0; - -err_nve_parsing_set: - mlxsw_sp->nve->inc_parsing_depth_refs--; - return err; -} - -static void -__mlxsw_sp_nve_inc_parsing_depth_put(struct mlxsw_sp *mlxsw_sp, - __be16 udp_dport) -{ - mlxsw_sp->nve->inc_parsing_depth_refs--; - mlxsw_sp_nve_parsing_set(mlxsw_sp, udp_dport); -} - -int mlxsw_sp_nve_inc_parsing_depth_get(struct mlxsw_sp *mlxsw_sp) -{ - __be16 udp_dport = mlxsw_sp->nve->config.udp_dport; - - return __mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp, udp_dport); -} - -void mlxsw_sp_nve_inc_parsing_depth_put(struct mlxsw_sp *mlxsw_sp) -{ - __be16 udp_dport = mlxsw_sp->nve->config.udp_dport; - - __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, udp_dport); -} - static void mlxsw_sp_nve_vxlan_config_prepare(char *tngcr_pl, const struct mlxsw_sp_nve_config *config) @@ -238,10 +170,14 @@ static int mlxsw_sp1_nve_vxlan_init(struct mlxsw_sp_nve *nve, struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp; int err; - err = __mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp, config->udp_dport); + err = mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, config->udp_dport); if (err) return err; + err = mlxsw_sp_parsing_depth_inc(mlxsw_sp); + if (err) + goto err_parsing_depth_inc; + err = mlxsw_sp1_nve_vxlan_config_set(mlxsw_sp, config); if (err) goto err_config_set; @@ -263,7 +199,9 @@ err_promote_decap: err_rtdp_set: mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp); err_config_set: - __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0); + mlxsw_sp_parsing_depth_dec(mlxsw_sp); +err_parsing_depth_inc: + mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0); return err; } @@ -275,7 +213,8 @@ static void mlxsw_sp1_nve_vxlan_fini(struct mlxsw_sp_nve *nve) mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id, config->ul_proto, &config->ul_sip); mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp); - __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0); + mlxsw_sp_parsing_depth_dec(mlxsw_sp); + mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0); } static int @@ -412,10 +351,14 @@ static int mlxsw_sp2_nve_vxlan_init(struct mlxsw_sp_nve *nve, struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp; int err; - err = __mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp, config->udp_dport); + err = mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, config->udp_dport); if (err) return err; + err = mlxsw_sp_parsing_depth_inc(mlxsw_sp); + if (err) + goto err_parsing_depth_inc; + err = mlxsw_sp2_nve_vxlan_config_set(mlxsw_sp, config); if (err) goto err_config_set; @@ -438,7 +381,9 @@ err_promote_decap: err_rtdp_set: mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp); err_config_set: - __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0); + mlxsw_sp_parsing_depth_dec(mlxsw_sp); +err_parsing_depth_inc: + mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0); return err; } @@ -450,7 +395,8 @@ static void mlxsw_sp2_nve_vxlan_fini(struct mlxsw_sp_nve *nve) mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id, config->ul_proto, &config->ul_sip); mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp); - __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0); + mlxsw_sp_parsing_depth_dec(mlxsw_sp); + mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0); } const struct mlxsw_sp_nve_ops mlxsw_sp2_nve_vxlan_ops = { diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c index bfef65d1587c..1a180384e7e8 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c @@ -975,14 +975,14 @@ static int mlxsw_sp1_ptp_mtpppc_update(struct mlxsw_sp_port *mlxsw_sp_port, } if ((ing_types || egr_types) && !(orig_ing_types || orig_egr_types)) { - err = mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp); + err = mlxsw_sp_parsing_depth_inc(mlxsw_sp); if (err) { netdev_err(mlxsw_sp_port->dev, "Failed to increase parsing depth"); return err; } } if (!(ing_types || egr_types) && (orig_ing_types || orig_egr_types)) - mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp); + mlxsw_sp_parsing_depth_dec(mlxsw_sp); return mlxsw_sp1_ptp_mtpppc_set(mlxsw_sp_port->mlxsw_sp, ing_types, egr_types); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index f69cbb3852d5..19bb3ca0515e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -9484,6 +9484,7 @@ struct mlxsw_sp_mp_hash_config { DECLARE_BITMAP(fields, __MLXSW_REG_RECR2_FIELD_CNT); DECLARE_BITMAP(inner_headers, __MLXSW_REG_RECR2_HEADER_CNT); DECLARE_BITMAP(inner_fields, __MLXSW_REG_RECR2_INNER_FIELD_CNT); + bool inc_parsing_depth; }; #define MLXSW_SP_MP_HASH_HEADER_SET(_headers, _header) \ @@ -9654,6 +9655,7 @@ static void mlxsw_sp_mp6_hash_init(struct mlxsw_sp *mlxsw_sp, MLXSW_SP_MP_HASH_FIELD_SET(fields, IPV6_FLOW_LABEL); /* Inner */ mlxsw_sp_mp_hash_inner_l3(config); + config->inc_parsing_depth = true; break; case 3: /* Outer */ @@ -9678,22 +9680,53 @@ static void mlxsw_sp_mp6_hash_init(struct mlxsw_sp *mlxsw_sp, MLXSW_SP_MP_HASH_FIELD_SET(fields, TCP_UDP_DPORT); /* Inner */ mlxsw_sp_mp_hash_inner_custom(config, hash_fields); + if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_MASK) + config->inc_parsing_depth = true; break; } } +static int mlxsw_sp_mp_hash_parsing_depth_adjust(struct mlxsw_sp *mlxsw_sp, + bool old_inc_parsing_depth, + bool new_inc_parsing_depth) +{ + int err; + + if (!old_inc_parsing_depth && new_inc_parsing_depth) { + err = mlxsw_sp_parsing_depth_inc(mlxsw_sp); + if (err) + return err; + mlxsw_sp->router->inc_parsing_depth = true; + } else if (old_inc_parsing_depth && !new_inc_parsing_depth) { + mlxsw_sp_parsing_depth_dec(mlxsw_sp); + mlxsw_sp->router->inc_parsing_depth = false; + } + + return 0; +} + static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp) { + bool old_inc_parsing_depth, new_inc_parsing_depth; struct mlxsw_sp_mp_hash_config config = {}; char recr2_pl[MLXSW_REG_RECR2_LEN]; unsigned long bit; u32 seed; + int err; seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac), 0); mlxsw_reg_recr2_pack(recr2_pl, seed); mlxsw_sp_mp4_hash_init(mlxsw_sp, &config); mlxsw_sp_mp6_hash_init(mlxsw_sp, &config); + old_inc_parsing_depth = mlxsw_sp->router->inc_parsing_depth; + new_inc_parsing_depth = config.inc_parsing_depth; + err = mlxsw_sp_mp_hash_parsing_depth_adjust(mlxsw_sp, + old_inc_parsing_depth, + new_inc_parsing_depth); + if (err) + return err; + for_each_set_bit(bit, config.headers, __MLXSW_REG_RECR2_HEADER_CNT) mlxsw_reg_recr2_outer_header_enables_set(recr2_pl, bit, 1); for_each_set_bit(bit, config.fields, __MLXSW_REG_RECR2_FIELD_CNT) @@ -9703,7 +9736,16 @@ static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp) for_each_set_bit(bit, config.inner_fields, __MLXSW_REG_RECR2_INNER_FIELD_CNT) mlxsw_reg_recr2_inner_header_fields_enable_set(recr2_pl, bit, 1); - return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(recr2), recr2_pl); + err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(recr2), recr2_pl); + if (err) + goto err_reg_write; + + return 0; + +err_reg_write: + mlxsw_sp_mp_hash_parsing_depth_adjust(mlxsw_sp, new_inc_parsing_depth, + old_inc_parsing_depth); + return err; } #else static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h index c5d7007f9173..25d3eae63501 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h @@ -81,6 +81,7 @@ struct mlxsw_sp_router { size_t adj_grp_size_ranges_count; struct delayed_work nh_grp_activity_dw; struct list_head nh_res_grp_list; + bool inc_parsing_depth; }; struct mlxsw_sp_fib_entry_priv { diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index 8f90cd323d5f..22fede5cb32c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -335,14 +335,16 @@ mlxsw_sp_bridge_port_find(struct mlxsw_sp_bridge *bridge, static struct mlxsw_sp_bridge_port * mlxsw_sp_bridge_port_create(struct mlxsw_sp_bridge_device *bridge_device, - struct net_device *brport_dev) + struct net_device *brport_dev, + struct netlink_ext_ack *extack) { struct mlxsw_sp_bridge_port *bridge_port; struct mlxsw_sp_port *mlxsw_sp_port; + int err; bridge_port = kzalloc(sizeof(*bridge_port), GFP_KERNEL); if (!bridge_port) - return NULL; + return ERR_PTR(-ENOMEM); mlxsw_sp_port = mlxsw_sp_port_dev_lower_find(brport_dev); bridge_port->lagged = mlxsw_sp_port->lagged; @@ -359,12 +361,23 @@ mlxsw_sp_bridge_port_create(struct mlxsw_sp_bridge_device *bridge_device, list_add(&bridge_port->list, &bridge_device->ports_list); bridge_port->ref_count = 1; + err = switchdev_bridge_port_offload(brport_dev, mlxsw_sp_port->dev, + NULL, NULL, NULL, false, extack); + if (err) + goto err_switchdev_offload; + return bridge_port; + +err_switchdev_offload: + list_del(&bridge_port->list); + kfree(bridge_port); + return ERR_PTR(err); } static void mlxsw_sp_bridge_port_destroy(struct mlxsw_sp_bridge_port *bridge_port) { + switchdev_bridge_port_unoffload(bridge_port->dev, NULL, NULL, NULL); list_del(&bridge_port->list); WARN_ON(!list_empty(&bridge_port->vlans_list)); kfree(bridge_port); @@ -390,9 +403,10 @@ mlxsw_sp_bridge_port_get(struct mlxsw_sp_bridge *bridge, if (IS_ERR(bridge_device)) return ERR_CAST(bridge_device); - bridge_port = mlxsw_sp_bridge_port_create(bridge_device, brport_dev); - if (!bridge_port) { - err = -ENOMEM; + bridge_port = mlxsw_sp_bridge_port_create(bridge_device, brport_dev, + extack); + if (IS_ERR(bridge_port)) { + err = PTR_ERR(bridge_port); goto err_bridge_port_create; } @@ -1569,7 +1583,6 @@ mlxsw_sp_mc_write_mdb_entry(struct mlxsw_sp *mlxsw_sp, { long *flood_bitmap; int num_of_ports; - int alloc_size; u16 mid_idx; int err; @@ -1579,18 +1592,17 @@ mlxsw_sp_mc_write_mdb_entry(struct mlxsw_sp *mlxsw_sp, return false; num_of_ports = mlxsw_core_max_ports(mlxsw_sp->core); - alloc_size = sizeof(long) * BITS_TO_LONGS(num_of_ports); - flood_bitmap = kzalloc(alloc_size, GFP_KERNEL); + flood_bitmap = bitmap_alloc(num_of_ports, GFP_KERNEL); if (!flood_bitmap) return false; - bitmap_copy(flood_bitmap, mid->ports_in_mid, num_of_ports); + bitmap_copy(flood_bitmap, mid->ports_in_mid, num_of_ports); mlxsw_sp_mc_get_mrouters_bitmap(flood_bitmap, bridge_device, mlxsw_sp); mid->mid = mid_idx; err = mlxsw_sp_port_smid_full_entry(mlxsw_sp, mid_idx, flood_bitmap, bridge_device->mrouter); - kfree(flood_bitmap); + bitmap_free(flood_bitmap); if (err) return false; |