Commit 070258ef authored by David S. Miller's avatar David S. Miller

Merge branch 'marvell-mdio-ACPI'

Marcin Wojtas says:

====================
ACPI MDIO support for Marvell controllers

The third version of the patchset main change is
dropping a clock handling optimisation patch
for mvmdio driver. Other than that it sets
explicit dependency on FWNODE_MDIO for CONFIG_FSL_XGMAC_MDIO
and applies minor cosmetic improvements (please see the
'Changelog' below).

The firmware ACPI description is exposed in the public github branch:
https://github.com/semihalf-wojtas-marcin/edk2-platforms/commits/acpi-mdio-r20210613
There is also MacchiatoBin firmware binary available for testing:
https://drive.google.com/file/d/1eigP_aeM4wYQpEaLAlQzs3IN_w1-kQr0

I'm looking forward to the comments or remarks.

Best regards,
Marcin

Changelog:
v2->v3
* Rebase on top of net-next/master.
* Drop "net: mvmdio: simplify clock handling" patch.
* 1/6 - fix code block comments.
* 2/6 - unchanged
* 3/6 - add "depends on FWNODE_MDIO" for CONFIG_FSL_XGMAC_MDIO
* 4/6 - drop mention about the clocks from the commit message.
* 5/6 - unchanged
* 6/6 - add Andrew's RB.

v1->v2
* 1/7 - new patch
* 2/7 - new patch
* 3/7 - new patch
* 4/7 - new patch
* 5/7 - remove unnecessary `if (has_acpi_companion())` and rebase onto
        the new clock handling
* 6/7 - remove deprecated comment
* 7/7 - no changes
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 64295f0d 8d909440
...@@ -50,6 +50,21 @@ phy-mode ...@@ -50,6 +50,21 @@ phy-mode
The "phy-mode" _DSD property is used to describe the connection to The "phy-mode" _DSD property is used to describe the connection to
the PHY. The valid values for "phy-mode" are defined in [4]. the PHY. The valid values for "phy-mode" are defined in [4].
managed
-------
Optional property, which specifies the PHY management type.
The valid values for "managed" are defined in [4].
fixed-link
----------
The "fixed-link" is described by a data-only subnode of the
MAC port, which is linked in the _DSD package via
hierarchical data extension (UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b
in accordance with [5] "_DSD Implementation Guide" document).
The subnode should comprise a required property ("speed") and
possibly the optional ones - complete list of parameters and
their values are specified in [4].
The following ASL example illustrates the usage of these properties. The following ASL example illustrates the usage of these properties.
DSDT entry for MDIO node DSDT entry for MDIO node
...@@ -128,6 +143,48 @@ phy-mode and phy-handle are used as explained earlier. ...@@ -128,6 +143,48 @@ phy-mode and phy-handle are used as explained earlier.
}) })
} }
MAC node example where "managed" property is specified.
-------------------------------------------------------
.. code-block:: none
Scope(\_SB.PP21.ETH0)
{
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"phy-mode", "sgmii"},
Package () {"managed", "in-band-status"}
}
})
}
MAC node example with a "fixed-link" subnode.
---------------------------------------------
.. code-block:: none
Scope(\_SB.PP21.ETH1)
{
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"phy-mode", "sgmii"},
},
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () {"fixed-link", "LNK0"}
}
})
Name (LNK0, Package(){ // Data-only subnode of port
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"speed", 1000},
Package () {"full-duplex", 1}
}
})
}
References References
========== ==========
...@@ -138,3 +195,5 @@ References ...@@ -138,3 +195,5 @@ References
[3] Documentation/firmware-guide/acpi/DSD-properties-rules.rst [3] Documentation/firmware-guide/acpi/DSD-properties-rules.rst
[4] Documentation/devicetree/bindings/net/ethernet-controller.yaml [4] Documentation/devicetree/bindings/net/ethernet-controller.yaml
[5] https://github.com/UEFI/DSD-Guide/blob/main/dsd-guide.pdf
...@@ -67,9 +67,7 @@ config FSL_PQ_MDIO ...@@ -67,9 +67,7 @@ config FSL_PQ_MDIO
config FSL_XGMAC_MDIO config FSL_XGMAC_MDIO
tristate "Freescale XGMAC MDIO" tristate "Freescale XGMAC MDIO"
select PHYLIB depends on FWNODE_MDIO
depends on OF
select OF_MDIO
help help
This driver supports the MDIO bus on the Fman 10G Ethernet MACs, and This driver supports the MDIO bus on the Fman 10G Ethernet MACs, and
on the FMan mEMAC (which supports both Clauses 22 and 45) on the FMan mEMAC (which supports both Clauses 22 and 45)
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/acpi_mdio.h> #include <linux/fwnode_mdio.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mdio.h> #include <linux/mdio.h>
...@@ -246,7 +246,6 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum) ...@@ -246,7 +246,6 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
static int xgmac_mdio_probe(struct platform_device *pdev) static int xgmac_mdio_probe(struct platform_device *pdev)
{ {
struct fwnode_handle *fwnode;
struct mdio_fsl_priv *priv; struct mdio_fsl_priv *priv;
struct resource *res; struct resource *res;
struct mii_bus *bus; struct mii_bus *bus;
...@@ -291,13 +290,7 @@ static int xgmac_mdio_probe(struct platform_device *pdev) ...@@ -291,13 +290,7 @@ static int xgmac_mdio_probe(struct platform_device *pdev)
priv->has_a011043 = device_property_read_bool(&pdev->dev, priv->has_a011043 = device_property_read_bool(&pdev->dev,
"fsl,erratum-a011043"); "fsl,erratum-a011043");
fwnode = pdev->dev.fwnode; ret = fwnode_mdiobus_register(bus, pdev->dev.fwnode);
if (is_of_node(fwnode))
ret = of_mdiobus_register(bus, to_of_node(fwnode));
else if (is_acpi_node(fwnode))
ret = acpi_mdiobus_register(bus, fwnode);
else
ret = -EINVAL;
if (ret) { if (ret) {
dev_err(&pdev->dev, "cannot register MDIO bus\n"); dev_err(&pdev->dev, "cannot register MDIO bus\n");
goto err_registration; goto err_registration;
......
...@@ -17,8 +17,10 @@ ...@@ -17,8 +17,10 @@
* warranty of any kind, whether express or implied. * warranty of any kind, whether express or implied.
*/ */
#include <linux/acpi.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/fwnode_mdio.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -281,7 +283,7 @@ static int orion_mdio_probe(struct platform_device *pdev) ...@@ -281,7 +283,7 @@ static int orion_mdio_probe(struct platform_device *pdev)
struct orion_mdio_dev *dev; struct orion_mdio_dev *dev;
int i, ret; int i, ret;
type = (enum orion_mdio_bus_type)of_device_get_match_data(&pdev->dev); type = (enum orion_mdio_bus_type)device_get_match_data(&pdev->dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) { if (!r) {
...@@ -369,7 +371,7 @@ static int orion_mdio_probe(struct platform_device *pdev) ...@@ -369,7 +371,7 @@ static int orion_mdio_probe(struct platform_device *pdev)
goto out_mdio; goto out_mdio;
} }
ret = of_mdiobus_register(bus, pdev->dev.of_node); ret = fwnode_mdiobus_register(bus, pdev->dev.fwnode);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret); dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
goto out_mdio; goto out_mdio;
...@@ -421,12 +423,20 @@ static const struct of_device_id orion_mdio_match[] = { ...@@ -421,12 +423,20 @@ static const struct of_device_id orion_mdio_match[] = {
}; };
MODULE_DEVICE_TABLE(of, orion_mdio_match); MODULE_DEVICE_TABLE(of, orion_mdio_match);
static const struct acpi_device_id orion_mdio_acpi_match[] = {
{ "MRVL0100", BUS_TYPE_SMI },
{ "MRVL0101", BUS_TYPE_XSMI },
{ },
};
MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match);
static struct platform_driver orion_mdio_driver = { static struct platform_driver orion_mdio_driver = {
.probe = orion_mdio_probe, .probe = orion_mdio_probe,
.remove = orion_mdio_remove, .remove = orion_mdio_remove,
.driver = { .driver = {
.name = "orion-mdio", .name = "orion-mdio",
.of_match_table = orion_mdio_match, .of_match_table = orion_mdio_match,
.acpi_match_table = ACPI_PTR(orion_mdio_acpi_match),
}, },
}; };
......
...@@ -1197,9 +1197,6 @@ struct mvpp2_port { ...@@ -1197,9 +1197,6 @@ struct mvpp2_port {
/* Firmware node associated to the port */ /* Firmware node associated to the port */
struct fwnode_handle *fwnode; struct fwnode_handle *fwnode;
/* Is a PHY always connected to the port */
bool has_phy;
/* Per-port registers' base address */ /* Per-port registers' base address */
void __iomem *base; void __iomem *base;
void __iomem *stats_base; void __iomem *stats_base;
......
...@@ -4793,9 +4793,8 @@ static int mvpp2_open(struct net_device *dev) ...@@ -4793,9 +4793,8 @@ static int mvpp2_open(struct net_device *dev)
goto err_cleanup_txqs; goto err_cleanup_txqs;
} }
/* Phylink isn't supported yet in ACPI mode */ if (port->phylink) {
if (port->of_node) { err = phylink_fwnode_phy_connect(port->phylink, port->fwnode, 0);
err = phylink_of_phy_connect(port->phylink, port->of_node, 0);
if (err) { if (err) {
netdev_err(port->dev, "could not attach PHY (%d)\n", netdev_err(port->dev, "could not attach PHY (%d)\n",
err); err);
...@@ -6703,6 +6702,19 @@ static void mvpp2_acpi_start(struct mvpp2_port *port) ...@@ -6703,6 +6702,19 @@ static void mvpp2_acpi_start(struct mvpp2_port *port)
SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false); SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false);
} }
/* In order to ensure backward compatibility for ACPI, check if the port
* firmware node comprises the necessary description allowing to use phylink.
*/
static bool mvpp2_use_acpi_compat_mode(struct fwnode_handle *port_fwnode)
{
if (!is_acpi_node(port_fwnode))
return false;
return (!fwnode_property_present(port_fwnode, "phy-handle") &&
!fwnode_property_present(port_fwnode, "managed") &&
!fwnode_get_named_child_node(port_fwnode, "fixed-link"));
}
/* Ports initialization */ /* Ports initialization */
static int mvpp2_port_probe(struct platform_device *pdev, static int mvpp2_port_probe(struct platform_device *pdev,
struct fwnode_handle *port_fwnode, struct fwnode_handle *port_fwnode,
...@@ -6778,7 +6790,6 @@ static int mvpp2_port_probe(struct platform_device *pdev, ...@@ -6778,7 +6790,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
port = netdev_priv(dev); port = netdev_priv(dev);
port->dev = dev; port->dev = dev;
port->fwnode = port_fwnode; port->fwnode = port_fwnode;
port->has_phy = !!of_find_property(port_node, "phy", NULL);
port->ntxqs = ntxqs; port->ntxqs = ntxqs;
port->nrxqs = nrxqs; port->nrxqs = nrxqs;
port->priv = priv; port->priv = priv;
...@@ -6921,8 +6932,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, ...@@ -6921,8 +6932,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE; dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
dev->dev.of_node = port_node; dev->dev.of_node = port_node;
/* Phylink isn't used w/ ACPI as of now */ if (!mvpp2_use_acpi_compat_mode(port_fwnode)) {
if (port_node) {
port->phylink_config.dev = &dev->dev; port->phylink_config.dev = &dev->dev;
port->phylink_config.type = PHYLINK_NETDEV; port->phylink_config.type = PHYLINK_NETDEV;
...@@ -6934,6 +6944,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, ...@@ -6934,6 +6944,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
} }
port->phylink = phylink; port->phylink = phylink;
} else { } else {
dev_warn(&pdev->dev, "Use link irqs for port#%d. FW update required\n", port->id);
port->phylink = NULL; port->phylink = NULL;
} }
......
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/acpi_mdio.h>
#include <linux/fwnode_mdio.h> #include <linux/fwnode_mdio.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/phy.h> #include <linux/phy.h>
MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>"); MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>");
...@@ -142,3 +144,23 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus, ...@@ -142,3 +144,23 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
return 0; return 0;
} }
EXPORT_SYMBOL(fwnode_mdiobus_register_phy); EXPORT_SYMBOL(fwnode_mdiobus_register_phy);
/**
* fwnode_mdiobus_register - bring up all the PHYs on a given MDIO bus and
* attach them to it.
* @bus: Target MDIO bus.
* @fwnode: Pointer to fwnode of the MDIO controller.
*
* Return values are determined accordingly to acpi_/of_ mdiobus_register()
* operation.
*/
int fwnode_mdiobus_register(struct mii_bus *bus, struct fwnode_handle *fwnode)
{
if (is_acpi_node(fwnode))
return acpi_mdiobus_register(bus, fwnode);
else if (is_of_node(fwnode))
return of_mdiobus_register(bus, to_of_node(fwnode));
else
return -EINVAL;
}
EXPORT_SYMBOL(fwnode_mdiobus_register);
...@@ -16,6 +16,7 @@ int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio, ...@@ -16,6 +16,7 @@ int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
int fwnode_mdiobus_register_phy(struct mii_bus *bus, int fwnode_mdiobus_register_phy(struct mii_bus *bus,
struct fwnode_handle *child, u32 addr); struct fwnode_handle *child, u32 addr);
int fwnode_mdiobus_register(struct mii_bus *bus, struct fwnode_handle *fwnode);
#else /* CONFIG_FWNODE_MDIO */ #else /* CONFIG_FWNODE_MDIO */
int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio, int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
struct phy_device *phy, struct phy_device *phy,
...@@ -30,6 +31,17 @@ static inline int fwnode_mdiobus_register_phy(struct mii_bus *bus, ...@@ -30,6 +31,17 @@ static inline int fwnode_mdiobus_register_phy(struct mii_bus *bus,
{ {
return -EINVAL; return -EINVAL;
} }
static inline int fwnode_mdiobus_register(struct mii_bus *bus,
struct fwnode_handle *fwnode)
{
/*
* Fall back to mdiobus_register() function to register a bus.
* This way, we don't have to keep compat bits around in drivers.
*/
return mdiobus_register(mdio);
}
#endif #endif
#endif /* __LINUX_FWNODE_MDIO_H */ #endif /* __LINUX_FWNODE_MDIO_H */
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