[][Add mt7531 cl45 phy access capability to switch command]

[Description]
Add mt7531 cl45 phy access capability to switch command via ioctl.

[Release-log]
N/A

Change-Id: I7c9b0c01acbc11b471adff6e29f6e2f6b2767d78
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/4590345
diff --git a/feed/switch/src/switch_fun.c b/feed/switch/src/switch_fun.c
index aefb927..92f0e12 100755
--- a/feed/switch/src/switch_fun.c
+++ b/feed/switch/src/switch_fun.c
@@ -122,7 +122,7 @@
 		ret = mii_mgr_cl22_read_ioctl(port_num, reg, value);
 
 	if (ret < 0) {
-		printf("Phy read fail\n");
+		printf("Phy cl22 read fail\n");
 		exit_free();
 		exit(0);
 	}
@@ -145,7 +145,7 @@
 		ret = mii_mgr_cl22_write_ioctl(port_num, reg, value);
 
 	if (ret < 0) {
-		printf("Phy write fail\n");
+		printf("Phy cl22 write fail\n");
 		exit_free();
 		exit(0);
 	}
@@ -168,7 +168,7 @@
 		ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value);
 
 	if (ret < 0) {
-		printf("Phy read fail\n");
+		printf("Phy cl45 read fail\n");
 		exit_free();
 		exit(0);
 	}
@@ -191,7 +191,7 @@
 		ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value);
 
 	if (ret < 0) {
-		printf("Phy write fail\n");
+		printf("Phy cl45 write fail\n");
 		exit_free();
 		exit(0);
 	}
diff --git a/feed/switch/src/switch_ioctl.c b/feed/switch/src/switch_ioctl.c
index 094bfc7..32d46c9 100644
--- a/feed/switch/src/switch_ioctl.c
+++ b/feed/switch/src/switch_ioctl.c
@@ -138,11 +138,14 @@
 
 	/*Change to indirect access mode*/
 	/*if you need to use direct access mode, please change back manually by reset bit5*/
-	reg_read(0x7804, &reg_value);
-	if (((reg_value >> 5) & 0x1) == 0) {
-		reg_value |= 1 << 5;
-		reg_write(0x7804, reg_value);
-		printf("Change to indirect access mode:0x%x\n", reg_value);
+	if (chip_name == 0x7530) {
+		reg_read(0x7804, &reg_value);
+		if (((reg_value >> 5) & 0x1) == 0) {
+			reg_value |= 1 << 5;
+			reg_write(0x7804, reg_value);
+			printf("Change to indirect access mode:0x%x\n",
+			       reg_value);
+		}
 	}
 	reg_value = 0x80090000 | (port_num << 20) | (reg << 25);
 	reg_write(0x701c, reg_value);
@@ -161,7 +164,7 @@
 			break;
 		}
 	}
-	printf(" PHY Indirect Access Control(0x701c) register read value =0x%x  \n", reg_value);
+	//printf(" PHY Indirect Access Control(0x701c) register read value =0x%x  \n", reg_value);
 	*value = reg_value;
 
 	return 0;
@@ -176,11 +179,14 @@
 	loop_cnt = 0;
 	/*Change to indirect access mode*/
 	/*if you need to use direct access mode, please change back manually by reset bit5*/
-	reg_read(0x7804, &reg_value);
-	if (((reg_value >> 5) & 0x1) == 0) {
-		reg_value |= 1 << 5;
-		reg_write(0x7804, reg_value);
-		printf("Change to indirect access mode:0x%x\n", reg_value);
+	if (chip_name == 0x7530) {
+		reg_read(0x7804, &reg_value);
+		if (((reg_value >> 5) & 0x1) == 0) {
+			reg_value |= 1 << 5;
+			reg_write(0x7804, reg_value);
+			printf("Change to indirect access mode:0x%x\n",
+			       reg_value);
+		}
 	}
 
 	reg_value = 0x80050000 | (port_num << 20) | (reg << 25) | value;
@@ -199,13 +205,13 @@
 		}
 	}
 
-	printf(" PHY Indirect Access Control(0x701c) register write value =0x%x  \n", reg_value);
+	//printf(" PHY Indirect Access Control(0x701c) register write value =0x%x  \n", reg_value);
 
 	return 0;
 }
 
-int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
-			    unsigned int reg, unsigned int *value)
+int mii_mgr_cl45_read_indirect(unsigned int port_num, unsigned int dev,
+			       unsigned int reg, unsigned int *value)
 {
 	int sk, method, ret;
 	struct ifreq ifr;
@@ -255,8 +261,8 @@
 	return ret;
 }
 
-int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
-			     unsigned int reg, unsigned int value)
+int mii_mgr_cl45_write_indirect(unsigned int port_num, unsigned int dev,
+				unsigned int reg, unsigned int value)
 {
 	int sk, method, ret;
 	struct ifreq ifr;
@@ -303,6 +309,129 @@
 	return ret;
 }
 
+int mii_mgr_cl45_read(unsigned int port_num, unsigned int dev,
+		      unsigned int reg, unsigned int *value)
+{
+	unsigned int reg_value;
+	int loop_cnt;
+	int op_busy;
+	int ret = 0;
+
+	loop_cnt = 0;
+
+	reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy) {
+			break;
+		} else if (loop_cnt < 10) {
+			loop_cnt++;
+		} else {
+			printf("MDIO cl45 set dev opeartion timeout\n");
+			reg_value = 0;
+			ret = -1; 
+			goto out;
+		}
+	}
+
+	reg_value = 0x800c0000 | (port_num << 20) | (dev << 25);
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy) {
+			reg_value = reg_value & 0xFFFF;
+			break;
+		} else if (loop_cnt < 10) {
+			loop_cnt++;
+		} else {
+			printf("MDIO cl45 read reg opeartion timeout\n");
+			reg_value = 0;
+			ret = -1; 
+			break;
+		}
+	}
+out:
+	//printf(" PHY Indirect Access Control(0x701c) register read value =0x%x  \n", reg_value);
+	*value = reg_value;
+
+	return ret;
+}
+
+int mii_mgr_cl45_write(unsigned int port_num, unsigned int dev,
+		       unsigned int reg, unsigned int value)
+{
+	unsigned int reg_value;
+	int loop_cnt;
+	int op_busy;
+	int ret = 0;
+
+	loop_cnt = 0;
+
+	reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy)
+			break;
+		else if (loop_cnt < 10)
+			loop_cnt++;
+		else {
+			printf("MDIO cl45 set dev opeartion timeout\n");
+			ret = -1; 
+			goto out;
+		}
+	}
+
+	reg_value = 0x80040000 | (port_num << 20) | (dev << 25) | value;
+	reg_write(0x701c, reg_value);
+	while (1)
+	{
+		reg_read(0x701c, &reg_value);
+		op_busy = reg_value & (1 << 31);
+		if (!op_busy)
+			break;
+		else if (loop_cnt < 10)
+			loop_cnt++;
+		else {
+			printf("MDIO cl45 write reg opeartion timeout\n");
+			ret = -1; 
+			break;
+		}
+	}
+out:
+	//printf(" PHY Indirect Access Control(0x701c) register write value =0x%x  \n", reg_value);
+	return ret;
+}
+
+int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
+			    unsigned int reg, unsigned int *value)
+{
+	if (chip_name == 0x7531)
+		return mii_mgr_cl45_read(port_num, dev, reg, value);
+	else if (chip_name == 0x7530)
+		return mii_mgr_cl45_read_indirect(port_num, dev, reg, value);
+	else
+		return -1;
+}
+
+int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
+			     unsigned int reg, unsigned int value)
+{
+	if (chip_name == 0x7531)
+		return mii_mgr_cl45_write(port_num, dev, reg, value);
+	else if (chip_name == 0x7530)
+		return mii_mgr_cl45_write_indirect(port_num, dev, reg, value);
+	else
+		return -1;
+}
+
 int dump_gphy(void)
 {
 	int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};