[Feature][ZXW-199]Support ETH stability test project

Only Configure :No
Affected branch: master
Affected module: Ethernet
Is it affected on both ZXIC and MTK:only ZXIC
Self-test: Yes
Doc Update: Yes

Change-Id: If989f58ed56824b94a104a76315937f841c67b62
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/net/ethernet/zte/zx29_gmac.c b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/net/ethernet/zte/zx29_gmac.c
old mode 100755
new mode 100644
index b344482..a4d3372
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/net/ethernet/zte/zx29_gmac.c
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/net/ethernet/zte/zx29_gmac.c
@@ -1391,11 +1391,174 @@
 }

 /*jb.qi add for gamc power down on 20231116 end */

 

+/*zw.wang add for switching the primary/secondary mode of gmac on 20240118 start*/

+int mode_type = -1;

+

+ssize_t gmac_master_or_slave_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)

+{

+	struct platform_device *pdev	= to_platform_device(dev);

+	struct net_device 	*ndev		= platform_get_drvdata(pdev);

+	struct zx29_gmac_dev *priv = (struct zx29_gmac_dev *)netdev_priv(ndev);

+	int mmd = 0;

+	int reg = 0;

+	int val = 0;

+	int ret;

+

+	///read mode_type

+	ret = sscanf(buf, "%d", &mode_type);

+	if (ret < 1) {

+		printk(KERN_ERR "Please enter the number 0-3 to enable the corresponding mode \n"

+				"Enter values in the non-0-3 range to get pattern description \n");

+		return count;

+	}

+

+	///Judgment model

+	if (mode_type < 0 || mode_type > 3) {

+		printk(KERN_DEBUG "Please enter the number range 0-3\n"

+				"0: Set the slave mode \n"

+				"1: Set the main mode \n"

+				"2: indicates setting SQI value view mode \n"

+				"3: Set the VCT value view mode \n"

+				"After the mode is set, the corresponding value can be obtained\n");

+		return ret ? ret : count;

+	}

+

+	///Set the Ethernet slave mode

+	if (mode_type == 0) {

+		mmd = 0x1;

+		reg = 0x834;

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		val = mdiobus_read(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e);

+

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, val & (~BIT(14)));

+	}

+	///Set the Ethernet master mode

+	else if (mode_type == 1) {

+		mmd = 0x1;

+		reg = 0x834;

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		val = mdiobus_read(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e);

+

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, val | BIT(14));

+	}

+	return count;

+}

+

+ssize_t gmac_master_or_slave_show(struct device *dev, struct device_attribute *attr, char *buf)

+{

+	struct platform_device *pdev	= to_platform_device(dev);

+	struct net_device 	*ndev		= platform_get_drvdata(pdev);

+	struct zx29_gmac_dev *priv = (struct zx29_gmac_dev *)netdev_priv(ndev);

+	int mmd = 0;

+	int reg = 0;

+	int val = 0;

+	int len = 0;

+	int ret;

+

+	///Read the network master/slave

+	if (mode_type == 0 || mode_type == 1) {

+		mmd = 0x1;

+		reg = 0x834;

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		val = mdiobus_read(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e) & BIT(14);

+		if(val)

+			memcpy(buf, "Master\n",7);

+		else

+			memcpy(buf, "Slave\n", 6);

+

+		printk(KERN_DEBUG "mode_type %d - gmac_master_or_slave is %s\n", mode_type, buf);

+

+	}

+	///Obtain the cable quality SQI value

+	else if(mode_type == 2){

+		mmd = 0x1;

+		reg = 0x8B10;

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		val = mdiobus_read(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e);

+		sprintf(buf, "0x%x\n", val);

+		sprintf(buf, "SQI : 0x%x\n", val);

+		printk(KERN_DEBUG "mode_type %d - SQI is 0x%x", mode_type, val);

+

+	}

+	///Obtain short circuit, open circuit and normal connection of VCT

+	else if(mode_type == 3){

+		///--TDR Enable

+		mmd = 0x1;

+		reg = 0x8B00;

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, BIT(14) | BIT(12));

+

+		///--Read VCT

+		mmd = 0x1;

+		reg = 0x8B02;

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		val = mdiobus_read(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e);

+		printk(KERN_DEBUG "Open status: %s - Short status: %s\n",

+		 (val & BIT(0)) ? "Open" : "Normal",  (val & BIT(1)) ? "Short" : "Normal");

+		sprintf(buf, "Open status: %s\nShort status: %s\n",

+		 (val & BIT(0)) ? "Open" : "Normal",  (val & BIT(1)) ? "Short" : "Normal");

+		reg = 0x8B01;

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		val = mdiobus_read(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e);

+		sprintf(buf, "%sDistance status: 0x%x\n", buf, val);

+		printk(KERN_DEBUG "mode_type %d - Distance status is 0x%x\n", mode_type, val);

+

+		///--TDR Disable

+		mmd = 0x1;

+		reg = 0x8B00;

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, reg);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d, 0x4000 | mmd);

+		mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e, 0);

+

+	}

+	///Get model help information

+	else{

+		sprintf(buf, "Please enter the number range 0-3\n"

+				"0: Set the slave mode \n"

+				"1: Set the main mode \n"

+				"2: indicates setting SQI value view mode \n"

+				"3: Set the VCT value view mode \n"

+				"After the mode is set, the corresponding value can be obtained\n");

+		printk(KERN_DEBUG "Please enter the number range 0-3\n"

+				"0: Set the slave mode \n"

+				"1: Set the main mode \n"

+				"2: indicates setting SQI value view mode \n"

+				"3: Set the VCT value view mode \n"

+				"After the mode is set, the corresponding value can be obtained\n");

+	}

+	return strlen(buf);

+

+}

+

+/*zw.wang add for switching the primary/secondary mode of gmac on 20240118 end */

+

 static DEVICE_ATTR(gmac_test, 0664, show_fun, store_fun);
 static DEVICE_ATTR(mdio_test, 0664, mdio_show, mdio_store);

 static DEVICE_ATTR(free_mdio, 0664, free_mdio_show, free_mdio_store);

 static DEVICE_ATTR(debug_on, 0664, debug_on_show, debug_on_store);

 static DEVICE_ATTR(gmac_power, 0664, gmac_power_show, gmac_power_store);//jb.qi add for gamc power down on 20231116

+static DEVICE_ATTR(gmac_master_or_slave, 0664, gmac_master_or_slave_show, gmac_master_or_slave_store);//zw.wang add for switching the primary/secondary mode of gmac on 20240118

 

 static int zx29_gmac_probe(struct platform_device *pdev)

 {

@@ -1423,6 +1586,7 @@
 	device_create_file(&pdev->dev, &dev_attr_free_mdio);

 	device_create_file(&pdev->dev, &dev_attr_debug_on);

     device_create_file(&pdev->dev, &dev_attr_gmac_power);//jb.qi add for gamc power down on 20231116

+	device_create_file(&pdev->dev, &dev_attr_gmac_master_or_slave);//zw.wang add for switching the primary/secondary mode of gmac on 20240118

 

 	prv = netdev_priv(ndev);

 	memset(prv, 0, sizeof(*prv));

@@ -1668,6 +1832,7 @@
 	    device_remove_file(&pdev->dev, &dev_attr_free_mdio);

 	    device_remove_file(&pdev->dev, &dev_attr_debug_on);

         device_remove_file(&pdev->dev, &dev_attr_gmac_power);//jb.qi add for gamc power down on 20231116

+		device_remove_file(&pdev->dev, &dev_attr_gmac_master_or_slave);//zw.wang add for switching the primary/secondary mode of gmac on 20240118

 	}

 	return 0;

 }