Commit 9386d181 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'axienet-broken-link'



Andy Chiu says:

====================
Fix broken link on Xilinx's AXI Ethernet in SGMII mode

The Ethernet driver use phy-handle to reference the PCS/PMA PHY. This
could be a problem if one wants to configure an external PHY via phylink,
since it use the same phandle to get the PHY. To fix this, introduce a
dedicated pcs-handle to point to the PCS/PMA PHY and deprecate the use
of pointing it with phy-handle. A similar use case of pcs-handle can be
seen on dpaa2 as well.

--- patch v5 ---
 - Re-apply the v4 patch on the net tree.
 - Describe the pcs-handle DT binding at ethernet-controller level.
--- patch v6 ---
 - Remove "preferrably" to clearify usage of pcs_handle.
--- patch v7 ---
 - Rebase the patch on latest net/master
--- patch v8 ---
 - Rebase the patch on net-next/master
 - Add "reviewed-by" tag in PATCH 3/4: dt-bindings: net: add pcs-handle
   attribute
 - Remove "fix" tag in last commit message since this is not a critical
   bug and will not be back ported to stable.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fb5833d8 19c7a439
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -106,6 +106,12 @@ properties:
  phy-mode:
    $ref: "#/properties/phy-connection-type"

  pcs-handle:
    $ref: /schemas/types.yaml#/definitions/phandle
    description:
      Specifies a reference to a node representing a PCS PHY device on a MDIO
      bus to link with an external PHY (phy-handle) if exists.

  phy-handle:
    $ref: /schemas/types.yaml#/definitions/phandle
    description:
+7 −1
Original line number Diff line number Diff line
@@ -26,7 +26,8 @@ Required properties:
		  specified, the TX/RX DMA interrupts should be on that node
		  instead, and only the Ethernet core interrupt is optionally
		  specified here.
- phy-handle	: Should point to the external phy device.
- phy-handle	: Should point to the external phy device if exists. Pointing
		  this to the PCS/PMA PHY is deprecated and should be avoided.
		  See ethernet.txt file in the same directory.
- xlnx,rxmem	: Set to allocated memory buffer for Rx/Tx in the hardware

@@ -68,6 +69,11 @@ Optional properties:
		  required through the core's MDIO interface (i.e. always,
		  unless the PHY is accessed through a different bus).

 - pcs-handle: 	  Phandle to the internal PCS/PMA PHY in SGMII or 1000Base-X
		  modes, where "pcs-handle" should be used to point
		  to the PCS/PMA PHY, and "phy-handle" should point to an
		  external PHY if exists.

Example:
	axi_ethernet_eth: ethernet@40c00000 {
		compatible = "xlnx,axi-ethernet-1.00.a";
+0 −2
Original line number Diff line number Diff line
@@ -433,8 +433,6 @@ struct axienet_local {
	struct net_device *ndev;
	struct device *dev;

	struct device_node *phy_node;

	struct phylink *phylink;
	struct phylink_config phylink_config;

+18 −15
Original line number Diff line number Diff line
@@ -2064,25 +2064,33 @@ static int axienet_probe(struct platform_device *pdev)
	if (ret)
		goto cleanup_clk;

	lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
	if (lp->phy_node) {
	ret = axienet_mdio_setup(lp);
	if (ret)
		dev_warn(&pdev->dev,
			 "error registering MDIO bus: %d\n", ret);
	}

	if (lp->phy_mode == PHY_INTERFACE_MODE_SGMII ||
	    lp->phy_mode == PHY_INTERFACE_MODE_1000BASEX) {
		if (!lp->phy_node) {
			dev_err(&pdev->dev, "phy-handle required for 1000BaseX/SGMII\n");
		np = of_parse_phandle(pdev->dev.of_node, "pcs-handle", 0);
		if (!np) {
			/* Deprecated: Always use "pcs-handle" for pcs_phy.
			 * Falling back to "phy-handle" here is only for
			 * backward compatibility with old device trees.
			 */
			np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
		}
		if (!np) {
			dev_err(&pdev->dev, "pcs-handle (preferred) or phy-handle required for 1000BaseX/SGMII\n");
			ret = -EINVAL;
			goto cleanup_mdio;
		}
		lp->pcs_phy = of_mdio_find_device(lp->phy_node);
		lp->pcs_phy = of_mdio_find_device(np);
		if (!lp->pcs_phy) {
			ret = -EPROBE_DEFER;
			of_node_put(np);
			goto cleanup_mdio;
		}
		of_node_put(np);
		lp->pcs.ops = &axienet_pcs_ops;
		lp->pcs.poll = true;
	}
@@ -2125,8 +2133,6 @@ static int axienet_probe(struct platform_device *pdev)
		put_device(&lp->pcs_phy->dev);
	if (lp->mii_bus)
		axienet_mdio_teardown(lp);
	of_node_put(lp->phy_node);

cleanup_clk:
	clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, lp->misc_clks);
	clk_disable_unprepare(lp->axi_clk);
@@ -2155,9 +2161,6 @@ static int axienet_remove(struct platform_device *pdev)
	clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, lp->misc_clks);
	clk_disable_unprepare(lp->axi_clk);

	of_node_put(lp->phy_node);
	lp->phy_node = NULL;

	free_netdev(ndev);

	return 0;