[PATCH net-next 2/2] net: phy: aquantia: allow forcing order of MDI pairs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Normally, the MDI reversal configuration is taken from the MDI_CFG pin.
However, some hardware designs require overriding the value configured
by that bootstrap pin. The PHY allows doing that by setting a bit which
allows ignoring the state of the MDI_CFG pin and configuring whether
the order of MDI pairs should be normal (ABCD) or reverse (DCBA).

Introduce two boolean properties which allow forcing either normal or
reverse order of the MDI pairs from DT.

Signed-off-by: Daniel Golle <daniel@xxxxxxxxxxxxxx>
---
 drivers/net/phy/aquantia/aquantia_main.c | 35 ++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index e982e9ce44a59..33a6eb55d99d4 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/bitfield.h>
+#include <linux/of.h>
 #include <linux/phy.h>
 
 #include "aquantia.h"
@@ -71,6 +72,11 @@
 #define MDIO_AN_TX_VEND_INT_MASK2		0xd401
 #define MDIO_AN_TX_VEND_INT_MASK2_LINK		BIT(0)
 
+#define PMAPMD_RSVD_VEND_PROV			0xe400
+#define PMAPMD_RSVD_VEND_PROV_MDI_CONF		GENMASK(1, 0)
+#define PMAPMD_RSVD_VEND_PROV_MDI_REVERSE	BIT(0)
+#define PMAPMD_RSVD_VEND_PROV_MDI_FORCE		BIT(1)
+
 #define MDIO_AN_RX_LP_STAT1			0xe820
 #define MDIO_AN_RX_LP_STAT1_1000BASET_FULL	BIT(15)
 #define MDIO_AN_RX_LP_STAT1_1000BASET_HALF	BIT(14)
@@ -474,6 +480,31 @@ static void aqr107_chip_info(struct phy_device *phydev)
 		   fw_major, fw_minor, build_id, prov_id);
 }
 
+int aqr107_config_mdi(struct phy_device *phydev)
+{
+	struct device_node *np = phydev->mdio.dev.of_node;
+	bool force_normal, force_reverse;
+
+	force_normal = of_property_read_bool(np, "marvell,force-mdi-order-normal");
+	force_reverse = of_property_read_bool(np, "marvell,force-mdi-order-reverse");
+
+	if (force_normal && force_reverse)
+		return -EINVAL;
+
+	if (force_normal)
+		return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_RSVD_VEND_PROV,
+				      PMAPMD_RSVD_VEND_PROV_MDI_CONF,
+				      PMAPMD_RSVD_VEND_PROV_MDI_FORCE);
+
+	if (force_reverse)
+		return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_RSVD_VEND_PROV,
+				      PMAPMD_RSVD_VEND_PROV_MDI_CONF,
+				      PMAPMD_RSVD_VEND_PROV_MDI_REVERSE |
+				      PMAPMD_RSVD_VEND_PROV_MDI_FORCE);
+
+	return 0;
+}
+
 static int aqr107_config_init(struct phy_device *phydev)
 {
 	struct aqr107_priv *priv = phydev->priv;
@@ -503,6 +534,10 @@ static int aqr107_config_init(struct phy_device *phydev)
 	if (ret)
 		return ret;
 
+	ret = aqr107_config_mdi(phydev);
+	if (ret)
+		return ret;
+
 	/* Restore LED polarity state after reset */
 	for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {
 		ret = aqr_phy_led_active_low_set(phydev, index, led_active_low);
-- 
2.46.0




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux