summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/mv88e6xxx/chip.c
AgeCommit message (Collapse)Author
2023-03-17net: dsa: mv88e6xxx: mask apparently non-existing phys during probingKlaus Kudielka
To avoid excessive mdio bus transactions during probing, mask all phy addresses that do not exist (there is a 1:1 mapping between switch port number and phy address). Suggested-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Klaus Kudielka <klaus.kudielka@gmail.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2023-03-17net: dsa: mv88e6xxx: move call to mv88e6xxx_mdios_register()Klaus Kudielka
Call the rather expensive mv88e6xxx_mdios_register() at the beginning of mv88e6xxx_setup(). This avoids the double call via mv88e6xxx_probe() during boot. For symmetry, call mv88e6xxx_mdios_unregister() at the end of mv88e6xxx_teardown(). Link: https://lore.kernel.org/lkml/449bde236c08d5ab5e54abd73b645d8b29955894.camel@gmail.com/ Suggested-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Klaus Kudielka <klaus.kudielka@gmail.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Tested-by: Vladimir Oltean <olteanv@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2023-03-17net: dsa: mv88e6xxx: re-order functionsKlaus Kudielka
Move mv88e6xxx_setup() below mv88e6xxx_mdios_register(), so that we are able to call the latter one from here. Do the same thing for the inverse functions. Signed-off-by: Klaus Kudielka <klaus.kudielka@gmail.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2023-03-16net: dsa: mv88e6xxx: fix max_mtu of 1492 on 6165, 6191, 6220, 6250, 6290Vladimir Oltean
There are 3 classes of switch families that the driver is aware of, as far as mv88e6xxx_change_mtu() is concerned: - MTU configuration is available per port. Here, the chip->info->ops->port_set_jumbo_size() method will be present. - MTU configuration is global to the switch. Here, the chip->info->ops->set_max_frame_size() method will be present. - We don't know how to change the MTU. Here, none of the above methods will be present. Switch families MV88E6165, MV88E6191, MV88E6220, MV88E6250 and MV88E6290 fall in category 3. The blamed commit has adjusted the MTU for all 3 categories by EDSA_HLEN (8 bytes), resulting in a new maximum MTU of 1492 being reported by the driver for these switches. I don't have the hardware to test, but I do have a MV88E6390 switch on which I can simulate this by commenting out its .port_set_jumbo_size definition from mv88e6390_ops. The result is this set of messages at probe time: mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 1 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 2 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 3 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 4 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 5 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 6 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 7 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 8 It is highly implausible that there exist Ethernet switches which don't support the standard MTU of 1500 octets, and this is what the DSA framework says as well - the error comes from dsa_slave_create() -> dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN). But the error messages are alarming, and it would be good to suppress them. As a consequence of this unlikeliness, we reimplement mv88e6xxx_get_max_mtu() and mv88e6xxx_change_mtu() on switches from the 3rd category as follows: the maximum supported MTU is 1500, and any request to set the MTU to a value larger than that fails in dev_validate_mtu(). Fixes: b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when setting MTU for DSA and CPU ports") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2023-01-16net: dsa: mv88e6xxx: Enable PTP receive for mv88e6390Kurt Kanzenbach
The switch receives management traffic such as STP and LLDP. However, PTP messages are not received, only transmitted. Ideally, the switch would trap all PTP messages to the management CPU. This particular switch has a PTP block which identifies PTP messages and traps them to a dedicated port. There is a register to program this destination. This is not used at the moment. Therefore, program it to the same port as the MGMT traffic is trapped to. This allows to receive PTP messages as soon as timestamping is enabled. In addition, the datasheet mentions that this register is not valid e.g., for 6190 variants. So, add a new PTP operation which is added for the 6390 and 6290 devices. Tested simply like this on Marvell 88E6390, revision 1: |/ # ptp4l -2 -i lan4 --tx_timestamp_timeout=40 -m |[...] |ptp4l[147.450]: master offset 56 s2 freq +1262 path delay 413 |ptp4l[148.450]: master offset 22 s2 freq +1244 path delay 434 |ptp4l[149.450]: master offset 5 s2 freq +1234 path delay 446 |ptp4l[150.451]: master offset 3 s2 freq +1233 path delay 451 |ptp4l[151.451]: master offset 1 s2 freq +1232 path delay 451 |ptp4l[152.451]: master offset -3 s2 freq +1229 path delay 451 |ptp4l[153.451]: master offset 9 s2 freq +1240 path delay 451 Link: https://lore.kernel.org/r/CAFSKS=PJBpvtRJxrR4sG1hyxpnUnQpiHg4SrUNzAhkWnyt9ivg@mail.gmail.com Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Tested-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2023-01-10net: dsa: mv88e6xxx: Separate C22 and C45 transactionsAndrew Lunn
The global2 SMI MDIO bus driver can perform both C22 and C45 transfers. Create separate functions for each and register the C45 versions using the new API calls where appropriate. Update the SERDES code to make use of these new accessors. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Michael Walle <michael@walle.cc> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2023-01-10net: dsa: mv88e6xxx: mac-auth/MAB implementationHans J. Schultz
This implementation for the Marvell mv88e6xxx chip series is based on handling ATU miss violations occurring when packets ingress on a port that is locked with learning on. This will trigger a SWITCHDEV_FDB_ADD_TO_BRIDGE event, which will result in the bridge module adding a locked FDB entry. This bridge FDB entry will not age out as it has the extern_learn flag set. Userspace daemons can listen to these events and either accept or deny access for the host, by either replacing the locked FDB entry with a simple entry or leave the locked entry. If the host MAC address is already present on another port, a ATU member violation will occur, but to no real effect, and the packet will be dropped in hardware. Statistics on these violations can be shown with the command and example output of interest: ethtool -S ethX NIC statistics: ... atu_member_violation: 5 atu_miss_violation: 23 ... Where ethX is the interface of the MAB enabled port. Furthermore, as added vlan interfaces where the vid is not added to the VTU will cause ATU miss violations reporting the FID as MV88E6XXX_FID_STANDALONE, we need to check and skip the miss violations handling in this case. Signed-off-by: Hans J. Schultz <netdev@kapio-technology.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2023-01-10net: dsa: mv88e6xxx: change default return of mv88e6xxx_port_bridge_flagsHans J. Schultz
The default return value -EOPNOTSUPP of mv88e6xxx_port_bridge_flags() came from the return value of the DSA method port_egress_floods() in commit 4f85901f0063 ("net: dsa: mv88e6xxx: add support for bridge flags"), but the DSA API was changed in commit a8b659e7ff75 ("net: dsa: act as passthrough for bridge port flags"), resulting in the return value -EOPNOTSUPP not being valid anymore, and sections for new flags will not need to set the return value to zero on success, as with the new mab flag added in a following patch. Signed-off-by: Hans J. Schultz <netdev@kapio-technology.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2022-12-15net: dsa: mv88e6xxx: avoid reg_lock deadlock in mv88e6xxx_setup_port()Vladimir Oltean
In the blamed commit, it was not noticed that one implementation of chip->info->ops->phylink_get_caps(), called by mv88e6xxx_get_caps(), may access hardware registers, and in doing so, it takes the mv88e6xxx_reg_lock(). Namely, this is mv88e6352_phylink_get_caps(). This is a problem because mv88e6xxx_get_caps(), apart from being a top-level function (method invoked by dsa_switch_ops), is now also directly called from mv88e6xxx_setup_port(), which runs under the mv88e6xxx_reg_lock() taken by mv88e6xxx_setup(). Therefore, when running on mv88e6352, the reg_lock would be acquired a second time and the system would deadlock on driver probe. The things that mv88e6xxx_setup() can compete with in terms of register access with are the IRQ handlers and MDIO bus operations registered by mv88e6xxx_probe(). So there is a real need to acquire the register lock. The register lock can, in principle, be dropped and re-acquired pretty much at will within the driver, as long as no operations that involve waiting for indirect access to complete (essentially, callers of mv88e6xxx_smi_direct_wait() and mv88e6xxx_wait_mask()) are interrupted with the lock released. However, I would guess that in mv88e6xxx_setup(), the critical section is kept open for such a long time just in order to optimize away multiple lock/unlock operations on the registers. We could, in principle, drop the reg_lock right before the mv88e6xxx_setup_port() -> mv88e6xxx_get_caps() call, and re-acquire it immediately afterwards. But this would look ugly, because mv88e6xxx_setup_port() would release a lock which it didn't acquire, but the caller did. A cleaner solution to this issue comes from the observation that struct mv88e6xxxx_ops methods generally assume they are called with the reg_lock already acquired. Whereas mv88e6352_phylink_get_caps() is more the exception rather than the norm, in that it acquires the lock itself. Let's enforce the same locking pattern/convention for chip->info->ops->phylink_get_caps() as well, and make mv88e6xxx_get_caps(), the top-level function, acquire the register lock explicitly, for this one implementation that will access registers for port 4 to work properly. This means that mv88e6xxx_setup_port() will no longer call the top-level function, but the low-level mv88e6xxx_ops method which expects the correct calling context (register lock held). Compared to chip->info->ops->phylink_get_caps(), mv88e6xxx_get_caps() also fixes up the supported_interfaces bitmap for internal ports, since that can be done generically and does not require per-switch knowledge. That's code which will no longer execute, however mv88e6xxx_setup_port() doesn't need that. It just needs to look at the mac_capabilities bitmap. Fixes: cc1049ccee20 ("net: dsa: mv88e6xxx: fix speed setting for CPU/DSA ports") Reported-by: Maksim Kiselev <bigunclemax@gmail.com> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Tested-by: Maksim Kiselev <bigunclemax@gmail.com> Link: https://lore.kernel.org/r/20221214110120.3368472-1-vladimir.oltean@nxp.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2022-12-08Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
No conflicts. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-12-07net: dsa: mv88e6xxx: accept phy-mode = "internal" for internal PHY portsVladimir Oltean
The ethernet-controller dt-schema, mostly pushed forward by Linux, has the "internal" PHY mode for denoting MAC connections to an internal PHY. U-Boot may provide device tree blobs where this phy-mode is specified, so make the Linux driver accept them. It appears that the current behavior with phy-mode = "internal" was introduced when mv88e6xxx started reporting supported_interfaces to phylink. Prior to that, I don't think it would have any issues accepting this phy-mode. Fixes: d4ebf12bcec4 ("net: dsa: mv88e6xxx: populate supported_interfaces and mac_capabilities") Link: https://lore.kernel.org/linux-arm-kernel/20221205172709.kglithpbhdbsakvd@skbuf/T/ Reported-by: Tim Harvey <tharvey@gateworks.com> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Tested-by: Tim Harvey <tharvey@gateworks.com> # imx6q-gw904.dts Link: https://lore.kernel.org/r/20221205194845.2131161-1-vladimir.oltean@nxp.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2022-11-11net: dsa: mv88e6xxx: enable set_policyAngelo Dureghello
Enabling set_policy capability for mv88e6321. Signed-off-by: Angelo Dureghello <angelo.dureghello@timesys.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Link: https://lore.kernel.org/r/20221110091027.998073-1-angelo.dureghello@timesys.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-10-31net: dsa: mv88e6xxx: Add RGMII delay to 88E6320Steffen Bätz
Currently, the .port_set_rgmii_delay hook is missing for the 88E6320 family, which causes failure to retrieve an IP address via DHCP. Add mv88e6320_port_set_rgmii_delay() that allows applying the RGMII delay for ports 2, 5, and 6, which are the only ports that can be used in RGMII mode. Tested on a custom i.MX8MN board connected to an 88E6320 switch. This change also applies safely to the 88E6321 variant. The only difference between 88E6320 versus 88E6321 is the temperature grade and pinout. They share exactly the same MDIO register map for ports 2, 5, and 6, which are the only ports that can be used in RGMII mode. Signed-off-by: Steffen Bätz <steffen@innosonix.de> [fabio: Improved commit log and extended it to mv88e6321_ops] Signed-off-by: Fabio Estevam <festevam@denx.de> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Link: https://lore.kernel.org/r/20221028163158.198108-1-festevam@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-09-22net: dsa: mv88e6xxx: remove unnecessary dev_set_drvdata()Yang Yingliang
Remove unnecessary dev_set_drvdata() in ->remove(), the driver_data will be set to NULL in device_unbind_cleanup() after calling ->remove(). Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-09-20net: dsa: propagate extack to port_lag_joinVladimir Oltean
Drivers could refuse to offload a LAG configuration for a variety of reasons, mainly having to do with its TX type. Additionally, since DSA masters may now also be LAG interfaces, and this will translate into a call to port_lag_join on the CPU ports, there may be extra restrictions there. Propagate the netlink extack to this DSA method in order for drivers to give a meaningful error message back to the user. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2022-08-31net: move from strlcpy with unused retval to strscpyWolfram Sang
Follow the advice of the below link and prefer 'strscpy' in this subsystem. Conversion is 1:1 because the return value is not used. Generated by a coccinelle script. Link: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/ Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Acked-by: Marc Kleine-Budde <mkl@pengutronix.de> # for CAN Link: https://lore.kernel.org/r/20220830201457.7984-1-wsa+renesas@sang-engineering.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-08-26net: dsa: mv88e6xxx: support RGMII cmodeMarcus Carlberg
Since the probe defaults all interfaces to the highest speed possible (10GBASE-X in mv88e6393x) before the phy mode configuration from the devicetree is considered it is currently impossible to use port 0 in RGMII mode. This change will allow RGMII modes to be configurable for port 0 enabling port 0 to be configured as RGMII as well as serial depending on configuration. Signed-off-by: Marcus Carlberg <marcus.carlberg@axis.com> Link: https://lore.kernel.org/r/20220822144136.16627-1-marcus.carlberg@axis.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-07-27net: dsa: mv88e6xxx: fix speed setting for CPU/DSA portsMarcin Wojtas
Commit 3c783b83bd0f ("net: dsa: mv88e6xxx: get rid of SPEED_MAX setting") stopped relying on SPEED_MAX constant and hardcoded speed settings for the switch ports and rely on phylink configuration. It turned out, however, that when the relevant code is called, the mac_capabilites of CPU/DSA port remain unset. mv88e6xxx_setup_port() is called via mv88e6xxx_setup() in dsa_tree_setup_switches(), which precedes setting the caps in phylink_get_caps down in the chain of dsa_tree_setup_ports(). As a result the mac_capabilites are 0 and the default speed for CPU/DSA port is 10M at the start. To fix that, execute mv88e6xxx_get_caps() and obtain the capabilities driectly. Fixes: 3c783b83bd0f ("net: dsa: mv88e6xxx: get rid of SPEED_MAX setting") Signed-off-by: Marcin Wojtas <mw@semihalf.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20220726230918.2772378-1-mw@semihalf.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-06-23net: dsa: mv88e6xxx: get rid of SPEED_MAX settingRussell King
Currently, all the device specific speed setting functions convert SPEED_MAX to the actual speed of the port. Rather than having each of the mv88e6xxx chip specifics handling SPEED_MAX, derive it from the mac_capabilities instead. This is only needed for CPU and DSA ports, so move the logic up into mv88e6xxx_setup_port() - which allows us to kill off all users of SPEED_MAX throughout the driver. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-05-27net: dsa: mv88e6xxx: Fix refcount leak in mv88e6xxx_mdios_registerMiaoqian Lin
of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. mv88e6xxx_mdio_register() pass the device node to of_mdiobus_register(). We don't need the device node after it. Add missing of_node_put() to avoid refcount leak. Fixes: a3c53be55c95 ("net: dsa: mv88e6xxx: Support multiple MDIO busses") Signed-off-by: Miaoqian Lin <linmq006@gmail.com> Reviewed-by: Marek Behún <kabel@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-05-12net: dsa: remove port argument from ->change_tag_protocol()Vladimir Oltean
DSA has not supported (and probably will not support in the future either) independent tagging protocols per CPU port. Different switch drivers have different requirements, some may need to replicate some settings for each CPU port, some may need to apply some settings on a single CPU port, while some may have to configure some global settings and then some per-CPU-port settings. In any case, the current model where DSA calls ->change_tag_protocol for each CPU port turns out to be impractical for drivers where there are global things to be done. For example, felix calls dsa_tag_8021q_register(), which makes no sense per CPU port, so it suppresses the second call. Let drivers deal with replication towards all CPU ports, and remove the CPU port argument from the function prototype. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Acked-by: Luiz Angelo Daros de Luca <luizluca@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-05-01net: dsa: mv88e6xxx: Cosmetic change spaces to tabs in dsa_switch_opsMarek Behún
All but 5 methods in dsa_swith_ops use tabs for indentation. Change the 5 methods that break this rule. Signed-off-by: Marek Behún <kabel@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-04-28net: dsa: mv88e6xxx: Single chip mode detection for MV88E6*41Nathan Rossi
The mv88e6xxx driver expects switches that are configured in single chip addressing mode to have the MDIO address configured as 0. This is due to the switch ADDR pins representing the single chip addressing mode as 0. However depending on the device (e.g. MV88E6*41) the switch does not respond on address 0 or any other address below 16 (the first port address) in single chip addressing mode. This allows for other devices to be on the same shared MDIO bus despite the switch being in single chip addressing mode. When using a switch that works this way it is not possible to configure switch driver as single chip addressing via device tree, along with another MDIO device on the same bus with address 0, as both devices would have the same address of 0 resulting in mdiobus_register_device -EBUSY errors for one of the devices with address 0. In order to support this configuration the switch node can have its MDIO address configured as 16 (the first address that the device responds to). During initialization the driver will treat this address similar to how address 0 is, however because this address is also a valid multi-chip address (in certain switch models, but not all) the driver will configure the SMI in single chip addressing mode and attempt to detect the switch model. If the device is configured in single chip addressing mode this will succeed and the initialization process can continue. If it fails to detect a valid model this is because the switch model register is not a valid register when in multi-chip mode, it will then fall back to the existing SMI initialization process using the MDIO address as the multi-chip mode address. This detection method is safe if the device is in either mode because the single chip addressing mode read is a direct SMI/MDIO read operation and has no side effects compared to the SMI writes required for the multi-chip addressing mode. In order to implement this change, the reset gpio configuration is moved to occur before any SMI initialization. This ensures that the device has the same/correct reset gpio state for both mv88e6xxx_smi_init calls. Signed-off-by: Nathan Rossi <nathan@nathanrossi.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Link: https://lore.kernel.org/r/20220427130928.540007-1-nathan@nathanrossi.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-03-21net: dsa: mv88e6xxx: Fill in STU support for all supported chipsTobias Waldekranz
Some chips using the split VTU/STU design will not accept VTU entries who's SID points to an invalid STU entry. Therefore, mark all those chips with either the mv88e6352_g1_stu_* or mv88e6390_g1_stu_* ops as appropriate. Notably, chips for the Opal Plus (6085/6097) era seem to use a different implementation than those from Agate (6352) and onwards, even though their external interface is the same. The former happily accepts VTU entries referencing invalid STU entries, while the latter does not. This fixes an issue where the driver would fail to probe switch trees that contained chips of the Agate/Topaz generation which did not declare STU support, as loaded VTU entries would be read back as invalid. Fixes: 49c98c1dc7d9 ("net: dsa: mv88e6xxx: Disentangle STU from VTU") Reported-by: Marek Behún <kabel@kernel.org> Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Tested-by: Marek Behún <kabel@kernel.org> Link: https://lore.kernel.org/r/20220319110345.555270-1-tobias@waldekranz.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-03-21net: dsa: mv88e6xxx: Ensure STU support in VLAN MSTI callbackTobias Waldekranz
In the same way that we check for STU support in the MST state callback, we should also verify it before trying to change a VLANs MSTI membership. Fixes: acaf4d2e36b3 ("net: dsa: mv88e6xxx: MST Offloading") Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Tested-by: Marek Behún <kabel@kernel.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-03-17net: dsa: pass extack to dsa_switch_ops :: port_mirror_add()Vladimir Oltean
Drivers might have error messages to propagate to user space, most common being that they support a single mirror port. Propagate the netlink extack so that they can inform user space in a verbal way of their limitations. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-03-17net: dsa: mv88e6xxx: MST OffloadingTobias Waldekranz
Allocate a SID in the STU for each MSTID in use by a bridge and handle the mapping of MSTIDs to VLANs using the SID field of each VTU entry. Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-03-17net: dsa: mv88e6xxx: Disentangle STU from VTUTobias Waldekranz
In early LinkStreet silicon (e.g. 6095/6185), the per-VLAN STP states were kept in the VTU - there was no concept of a SID. Later, the information was split into two tables, where the VTU only tracked memberships and deferred the STP state tracking to the STU via a pointer (SID). This meant that a group of VLANs could share the same STU entry. Most likely, this was done to align with MSTP (802.1Q-2018, Clause 13), which is built on this principle. While the VTU is still 4k lines on most devices, the STU is capped at 64 entries. This means that the current stategy, updating STU info whenever a VTU entry is updated, can not easily support MSTP because: - The maximum number of VIDs would also be capped at 64, as we would have to allocate one SID for every VTU entry - even if many VLANs would effectively share the same MST. - MSTP updates would be unnecessarily slow as you would have to iterate over all VLANs that share the same MST. In order to support MSTP offloading in the future, manage the STU as a separate entity from the VTU. Only add support for newer hardware with separate VTU and STU. VTU-only devices can also be supported, but essentially this requires a software implementation of an STU (fanning out state changed to all VLANs tied to the same MST). Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-27net: dsa: pass extack to .port_bridge_join driver methodsVladimir Oltean
As FDB isolation cannot be enforced between VLAN-aware bridges in lack of hardware assistance like extra FID bits, it seems plausible that many DSA switches cannot do it. Therefore, they need to reject configurations with multiple VLAN-aware bridges from the two code paths that can transition towards that state: - joining a VLAN-aware bridge - toggling VLAN awareness on an existing bridge The .port_vlan_filtering method already propagates the netlink extack to the driver, let's propagate it from .port_bridge_join too, to make sure that the driver can use the same function for both. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-27net: dsa: request drivers to perform FDB isolationVladimir Oltean
For DSA, to encourage drivers to perform FDB isolation simply means to track which bridge does each FDB and MDB entry belong to. It then becomes the driver responsibility to use something that makes the FDB entry from one bridge not match the FDB lookup of ports from other bridges. The top-level functions where the bridge is determined are: - dsa_port_fdb_{add,del} - dsa_port_host_fdb_{add,del} - dsa_port_mdb_{add,del} - dsa_port_host_mdb_{add,del} aka the pre-crosschip-notifier functions. Changing the API to pass a reference to a bridge is not superfluous, and looking at the passed bridge argument is not the same as having the driver look at dsa_to_port(ds, port)->bridge from the ->port_fdb_add() method. DSA installs FDB and MDB entries on shared (CPU and DSA) ports as well, and those do not have any dp->bridge information to retrieve, because they are not in any bridge - they are merely the pipes that serve the user ports that are in one or multiple bridges. The struct dsa_bridge associated with each FDB/MDB entry is encapsulated in a larger "struct dsa_db" database. Although only databases associated to bridges are notified for now, this API will be the starting point for implementing IFF_UNICAST_FLT in DSA. There, the idea is to install FDB entries on the CPU port which belong to the corresponding user port's port database. These are supposed to match only when the port is standalone. It is better to introduce the API in its expected final form than to introduce it for bridges first, then to have to change drivers which may have made one or more assumptions. Drivers can use the provided bridge.num, but they can also use a different numbering scheme that is more convenient. DSA must perform refcounting on the CPU and DSA ports by also taking into account the bridge number. So if two bridges request the same local address, DSA must notify the driver twice, once for each bridge. In fact, if the driver supports FDB isolation, DSA must perform refcounting per bridge, but if the driver doesn't, DSA must refcount host addresses across all bridges, otherwise it would be telling the driver to delete an FDB entry for a bridge and the driver would delete it for all bridges. So introduce a bool fdb_isolation in drivers which would make all bridge databases passed to the cross-chip notifier have the same number (0). This makes dsa_mac_addr_find() -> dsa_db_equal() say that all bridge databases are the same database - which is essentially the legacy behavior. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-24net: dsa: create a dsa_lag structureVladimir Oltean
The main purpose of this change is to create a data structure for a LAG as seen by DSA. This is similar to what we have for bridging - we pass a copy of this structure by value to ->port_lag_join and ->port_lag_leave. For now we keep the lag_dev, id and a reference count in it. Future patches will add a list of FDB entries for the LAG (these also need to be refcounted to work properly). The LAG structure is created using dsa_port_lag_create() and destroyed using dsa_port_lag_destroy(), just like we have for bridging. Because now, the dsa_lag itself is refcounted, we can simplify dsa_lag_map() and dsa_lag_unmap(). These functions need to keep a LAG in the dst->lags array only as long as at least one port uses it. The refcounting logic inside those functions can be removed now - they are called only when we should perform the operation. dsa_lag_dev() is renamed to dsa_lag_by_id() and now returns the dsa_lag structure instead of the lag_dev net_device. dsa_lag_foreach_port() now takes the dsa_lag structure as argument. dst->lags holds an array of dsa_lag structures. dsa_lag_map() now also saves the dsa_lag->id value, so that linear walking of dst->lags in drivers using dsa_lag_id() is no longer necessary. They can just look at lag.id. dsa_port_lag_id_get() is a helper, similar to dsa_port_bridge_num_get(), which can be used by drivers to get the LAG ID assigned by DSA to a given port. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-24net: dsa: mv88e6xxx: use dsa_switch_for_each_port in mv88e6xxx_lag_sync_masksVladimir Oltean
Make the intent of the code more clear by using the dedicated helper for iterating over the ports of a switch. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-24net: dsa: make LAG IDs one-basedVladimir Oltean
The DSA LAG API will be changed to become more similar with the bridge data structures, where struct dsa_bridge holds an unsigned int num, which is generated by DSA and is one-based. We have a similar thing going with the DSA LAG, except that isn't stored anywhere, it is calculated dynamically by dsa_lag_id() by iterating through dst->lags. The idea of encoding an invalid (or not requested) LAG ID as zero for the purpose of simplifying checks in drivers means that the LAG IDs passed by DSA to drivers need to be one-based too. So back-and-forth conversion is needed when indexing the dst->lags array, as well as in drivers which assume a zero-based index. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-24net: dsa: mv88e6xxx: rename references to "lag" as "lag_dev"Vladimir Oltean
In preparation of converting struct net_device *dp->lag_dev into a struct dsa_lag *dp->lag, we need to rename, for consistency purposes, all occurrences of the "lag" variable in mv88e6xxx to "lag_dev". Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-23net: dsa: mv88e6xxx: Add support for bridge port locked modeHans Schultz
Supporting bridge ports in locked mode using the drop on lock feature in Marvell mv88e6xxx switchcores is described in the '88E6096/88E6097/88E6097F Datasheet', sections 4.4.6, 4.4.7 and 5.1.2.1 (Drop on Lock). This feature is implemented here facilitated by the locked port flag. Signed-off-by: Hans Schultz <schultz.hans+netdev@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-17Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
No conflicts. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-14net: dsa: mv88e6xxx: Fix validation of built-in PHYs on 6095/6097Tobias Waldekranz
These chips have 8 built-in FE PHYs and 3 SERDES interfaces that can run at 1G. With the blamed commit, the built-in PHYs could no longer be connected to, using an MII PHY interface mode. Create a separate .phylink_get_caps callback for these chips, which takes the FE/GE split into consideration. Fixes: 2ee84cfefb1e ("net: dsa: mv88e6xxx: convert to phylink_generic_validate()") Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Link: https://lore.kernel.org/r/20220213185154.3262207-1-tobias@waldekranz.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-14net: dsa: mv88e6xxx: flush switchdev FDB workqueue before removing VLANVladimir Oltean
mv88e6xxx is special among DSA drivers in that it requires the VTU to contain the VID of the FDB entry it modifies in mv88e6xxx_port_db_load_purge(), otherwise it will return -EOPNOTSUPP. Sometimes due to races this is not always satisfied even if external code does everything right (first deletes the FDB entries, then the VLAN), because DSA commits to hardware FDB entries asynchronously since commit c9eb3e0f8701 ("net: dsa: Add support for learning FDB through notification"). Therefore, the mv88e6xxx driver must close this race condition by itself, by asking DSA to flush the switchdev workqueue of any FDB deletions in progress, prior to exiting a VLAN. Fixes: c9eb3e0f8701 ("net: dsa: Add support for learning FDB through notification") Reported-by: Rafael Richter <rafael.richter@gin.de> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-11dsa: mv88e6xxx: make serdes SGMII/Fiber tx amplitude configurableHolger Brunck
The mv88e6352, mv88e6240 and mv88e6176 have a serdes interface. This patch allows to configure the output swing to a desired value in the phy-handle of the port. The value which is peak to peak has to be specified in microvolts. As the chips only supports eight dedicated values we return EINVAL if the value in the DTS does not match one of these values. Signed-off-by: Holger Brunck <holger.brunck@hitachienergy.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Marek Behún <kabel@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-10Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
No conflicts. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-10net: dsa: mv88e6xxx: fix use-after-free in mv88e6xxx_mdios_unregisterVladimir Oltean
Since struct mv88e6xxx_mdio_bus *mdio_bus is the bus->priv of something allocated with mdiobus_alloc_size(), this means that mdiobus_free(bus) will free the memory backing the mdio_bus as well. Therefore, the mdio_bus->list element is freed memory, but we continue to iterate through the list of MDIO buses using that list element. To fix this, use the proper list iterator that handles element deletion by keeping a copy of the list element next pointer. Fixes: f53a2ce893b2 ("net: dsa: mv88e6xxx: don't use devres for mdiobus") Reported-by: Rafael Richter <rafael.richter@gin.de> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://lore.kernel.org/r/20220210174017.3271099-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-08net: dsa: mv88e6xxx: don't use devres for mdiobusVladimir Oltean
As explained in commits: 74b6d7d13307 ("net: dsa: realtek: register the MDIO bus under devres") 5135e96a3dd2 ("net: dsa: don't allocate the slave_mii_bus using devres") mdiobus_free() will panic when called from devm_mdiobus_free() <- devres_release_all() <- __device_release_driver(), and that mdiobus was not previously unregistered. The mv88e6xxx is an MDIO device, so the initial set of constraints that I thought would cause this (I2C or SPI buses which call ->remove on ->shutdown) do not apply. But there is one more which applies here. If the DSA master itself is on a bus that calls ->remove from ->shutdown (like dpaa2-eth, which is on the fsl-mc bus), there is a device link between the switch and the DSA master, and device_links_unbind_consumers() will unbind the Marvell switch driver on shutdown. systemd-shutdown[1]: Powering off. mv88e6085 0x0000000008b96000:00 sw_gl0: Link is Down fsl-mc dpbp.9: Removing from iommu group 7 fsl-mc dpbp.8: Removing from iommu group 7 ------------[ cut here ]------------ kernel BUG at drivers/net/phy/mdio_bus.c:677! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 5.16.5-00040-gdc05f73788e5 #15 pc : mdiobus_free+0x44/0x50 lr : devm_mdiobus_free+0x10/0x20 Call trace: mdiobus_free+0x44/0x50 devm_mdiobus_free+0x10/0x20 devres_release_all+0xa0/0x100 __device_release_driver+0x190/0x220 device_release_driver_internal+0xac/0xb0 device_links_unbind_consumers+0xd4/0x100 __device_release_driver+0x4c/0x220 device_release_driver_internal+0xac/0xb0 device_links_unbind_consumers+0xd4/0x100 __device_release_driver+0x94/0x220 device_release_driver+0x28/0x40 bus_remove_device+0x118/0x124 device_del+0x174/0x420 fsl_mc_device_remove+0x24/0x40 __fsl_mc_device_remove+0xc/0x20 device_for_each_child+0x58/0xa0 dprc_remove+0x90/0xb0 fsl_mc_driver_remove+0x20/0x5c __device_release_driver+0x21c/0x220 device_release_driver+0x28/0x40 bus_remove_device+0x118/0x124 device_del+0x174/0x420 fsl_mc_bus_remove+0x80/0x100 fsl_mc_bus_shutdown+0xc/0x1c platform_shutdown+0x20/0x30 device_shutdown+0x154/0x330 kernel_power_off+0x34/0x6c __do_sys_reboot+0x15c/0x250 __arm64_sys_reboot+0x20/0x30 invoke_syscall.constprop.0+0x4c/0xe0 do_el0_svc+0x4c/0x150 el0_svc+0x24/0xb0 el0t_64_sync_handler+0xa8/0xb0 el0t_64_sync+0x178/0x17c So the same treatment must be applied to all DSA switch drivers, which is: either use devres for both the mdiobus allocation and registration, or don't use devres at all. The Marvell driver already has a good structure for mdiobus removal, so just plug in mdiobus_free and get rid of devres. Fixes: ac3a68d56651 ("net: phy: don't abuse devres in devm_mdiobus_register()") Reported-by: Rafael Richter <Rafael.Richter@gin.de> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Tested-by: Daniel Klauer <daniel.klauer@gin.de> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-02-07net: dsa: mv88e6xxx: Unlock on error in mv88e6xxx_port_bridge_join()Dan Carpenter
Call mv88e6xxx_reg_unlock(chip) before returning on this error path. Fixes: 7af4a361a62f ("net: dsa: mv88e6xxx: Improve isolation of standalone ports") Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-07net: dsa: mv88e6xxx: Fix off by in one in mv88e6185_phylink_get_caps()Dan Carpenter
The <= ARRAY_SIZE() needs to be < ARRAY_SIZE() to prevent an out of bounds error. Fixes: d4ebf12bcec4 ("net: dsa: mv88e6xxx: populate supported_interfaces and mac_capabilities") Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-03net: dsa: mv88e6xxx: convert to phylink_generic_validate()Russell King (Oracle)
Now that the mv88e6xxx chip drivers are supplying the supported interfaces and MAC capabilities, switch the driver to use the generic phylink validation implementation by removing our own validation implementations. This causes DSA to call phylink_generic_validate() on our behalf. Reviewed-by: Marek Behún <kabel@kernel.org> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-03net: dsa: mv88e6xxx: populate supported_interfaces and mac_capabilitiesRussell King (Oracle)
Populate the supported interfaces and MAC capabilities for the Marvell MV88E6xxx DSA switches in preparation to using these for the validation functionality. Patch co-authored by Marek. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: Marek Behún <kabel@kernel.org> [ fixed 6341 and 6393x ] Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-03net: dsa: mv88e6xxx: Improve multichip isolation of standalone portsTobias Waldekranz
Given that standalone ports are now configured to bypass the ATU and forward all frames towards the upstream port, extend the ATU bypass to multichip systems. Load VID 0 (standalone) into the VTU with the policy bit set. Since VID 4095 (bridged) is already loaded, we now know that all VIDs in use are always available in all VTUs. Therefore, we can safely enable 802.1Q on DSA ports. Setting the DSA ports' VTU policy to TRAP means that all incoming frames on VID 0 will be classified as MGMT - as a result, the ATU is bypassed on all subsequent switches. With this isolation in place, we are able to support configurations that are simultaneously very quirky and very useful. Quirky because it involves looping cables between local switchports like in this example: CPU | .------. .---0---. | .----0----. | sw0 | | | sw1 | '-1-2-3-' | '-1-2-3-4-' $ @ '---' $ @ % % We have three physically looped pairs ($, @, and %). This is very useful because it allows us to run the kernel's kselftests for the bridge on mv88e6xxx hardware. Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-03net: dsa: mv88e6xxx: Enable port policy support on 6097Tobias Waldekranz
This chip has support for the same per-port policy actions found in later versions of LinkStreet devices. Fixes: f3a2cd326e44 ("net: dsa: mv88e6xxx: introduce .port_set_policy") Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-02-03net: dsa: mv88e6xxx: Improve isolation of standalone portsTobias Waldekranz
Clear MapDA on standalone ports to bypass any ATU lookup that might point the packet in the wrong direction. This means that all packets are flooded using the PVT config. So make sure that standalone ports are only allowed to communicate with the local upstream port. Here is a scenario in which this is needed: CPU | .----. .---0---. | .--0--. | sw0 | | | sw1 | '-1-2-3-' | '-1-2-' '---' - sw0p1 and sw1p1 are bridged - sw0p2 and sw1p2 are in standalone mode - Learning must be enabled on sw0p3 in order for hardware forwarding to work properly between bridged ports 1. A packet with SA :aa comes in on sw1p2 1a. Egresses sw1p0 1b. Ingresses sw0p3, ATU adds an entry for :aa towards port 3 1c. Egresses sw0p0 2. A packet with DA :aa comes in on sw0p2 2a. If an ATU lookup is done at this point, the packet will be incorrectly forwarded towards sw0p3. With this change in place, the ATU is bypassed and the packet is forwarded in accordance with the PVT, which only contains the CPU port. Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-01-31net: dsa: mv88e6xxx: Improve performance of busy bit pollingTobias Waldekranz
Avoid a long delay when a busy bit is still set and has to be polled again. Measurements on a system with 2 Opals (6097F) and one Agate (6352) show that even with this much tighter loop, we have about a 50% chance of the bit being cleared on the first poll, all other accesses see the bit being cleared on the second poll. On a standard MDIO bus running MDC at 2.5MHz, a single access with 32 bits of preamble plus 32 bits of data takes 64*(1/2.5MHz) = 25.6us. This means that mv88e6xxx_smi_direct_wait took 26us + CPU overhead in the fast scenario, but 26us + 1500us + 26us + CPU overhead in the slow case - bringing the average close to 1ms. With this change in place, the slow case is closer to 2*26us + CPU overhead, with the average well below 100us - a 10x improvement. This translates to real-world winnings. On a 3-chip 20-port system, the modprobe time drops by 88%: Before: root@coronet:~# time modprobe mv88e6xxx real 0m 15.99s user 0m 0.00s sys 0m 1.52s After: root@coronet:~# time modprobe mv88e6xxx real 0m 2.21s user 0m 0.00s sys 0m 1.54s Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>