summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/device-tree-bindings/net/ti,dp83867.txt5
-rw-r--r--drivers/net/phy/ti.c39
2 files changed, 44 insertions, 0 deletions
diff --git a/doc/device-tree-bindings/net/ti,dp83867.txt b/doc/device-tree-bindings/net/ti,dp83867.txt
index cb77fdf082..f31c2da902 100644
--- a/doc/device-tree-bindings/net/ti,dp83867.txt
+++ b/doc/device-tree-bindings/net/ti,dp83867.txt
@@ -8,6 +8,10 @@ Required properties:
for applicable values
- ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h
for applicable values
+ - enet-phy-lane-swap - Indicates that PHY will swap the TX/RX lanes to
+ compensate for the board being designed with the lanes swapped.
+ - enet-phy-no-lane-swap - Indicates that PHY will disable swap of the
+ TX/RX lanes.
Default child nodes are standard Ethernet PHY device
nodes as described in doc/devicetree/bindings/net/ethernet.txt
@@ -19,6 +23,7 @@ Example:
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ enet-phy-lane-no-swap;
};
Datasheet can be found:
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
index f870e6d662..cef59420d2 100644
--- a/drivers/net/phy/ti.c
+++ b/drivers/net/phy/ti.c
@@ -89,12 +89,22 @@
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f
+/* CFG4 bits */
+#define DP83867_CFG4_PORT_MIRROR_EN BIT(0)
+
+enum {
+ DP83867_PORT_MIRRORING_KEEP,
+ DP83867_PORT_MIRRORING_EN,
+ DP83867_PORT_MIRRORING_DIS,
+};
+
struct dp83867_private {
int rx_id_delay;
int tx_id_delay;
int fifo_depth;
int io_impedance;
bool rxctrl_strap_quirk;
+ int port_mirroring;
};
/**
@@ -163,6 +173,26 @@ void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
phy_write(phydev, addr, MII_MMD_DATA, data);
}
+static int dp83867_config_port_mirroring(struct phy_device *phydev)
+{
+ struct dp83867_private *dp83867 =
+ (struct dp83867_private *)phydev->priv;
+ u16 val;
+
+ val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
+ phydev->addr);
+
+ if (dp83867->port_mirroring == DP83867_PORT_MIRRORING_EN)
+ val |= DP83867_CFG4_PORT_MIRROR_EN;
+ else
+ val &= ~DP83867_CFG4_PORT_MIRROR_EN;
+
+ phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
+ phydev->addr, val);
+
+ return 0;
+}
+
#if defined(CONFIG_DM_ETH)
/**
* dp83867_data_init - Convenience function for setting PHY specific data
@@ -197,6 +227,12 @@ static int dp83867_of_init(struct phy_device *phydev)
dp83867->fifo_depth = ofnode_read_u32_default(node, "ti,fifo-depth",
-1);
+ if (ofnode_read_bool(node, "enet-phy-lane-swap"))
+ dp83867->port_mirroring = DP83867_PORT_MIRRORING_EN;
+
+ if (ofnode_read_bool(node, "enet-phy-lane-no-swap"))
+ dp83867->port_mirroring = DP83867_PORT_MIRRORING_DIS;
+
return 0;
}
@@ -315,6 +351,9 @@ static int dp83867_config(struct phy_device *phydev)
}
}
+ if (dp83867->port_mirroring != DP83867_PORT_MIRRORING_KEEP)
+ dp83867_config_port_mirroring(phydev);
+
genphy_config_aneg(phydev);
return 0;