[][Add proprietary ioctl back to mii_mgr]

[Description]
Add proprietary ioctl back to mii_mgr.

[Release-log]
N/A

Change-Id: Iddf0a13fb11a49fb16620ccdbb2c58a1940d7c69
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/4538724
diff --git a/feed/mii_mgr/src/mii_mgr.c b/feed/mii_mgr/src/mii_mgr.c
index 34cf8d5..b4e6696 100644
--- a/feed/mii_mgr/src/mii_mgr.c
+++ b/feed/mii_mgr/src/mii_mgr.c
@@ -15,6 +15,8 @@
 #include <linux/mdio.h>
 #include <linux/sockios.h>
 
+#include "mii_mgr.h"
+
 void show_usage(void)
 {
 	printf("mii_mgr -g -i [ifname] -p [phy number] -r [register number]\n");
@@ -29,12 +31,32 @@
 	printf("Example: mii_mgr_cl45 -s -p 4 -d 0x6 -r 0x1 -v 0xff11\n\n");
 }
 
+static void fill_mii_ioctl(struct mii_ioctl_data *mii, uint16_t phy_id,
+			   uint16_t reg_num, uint16_t *val)
+{
+	mii->phy_id  = phy_id;
+	mii->reg_num = reg_num;
+	mii->val_in  = *val;
+	mii->val_out = 0;
+}
+
+
+static void fill_mtk_mii_ioctl(struct mtk_mii_ioctl_data *mtk_mii, uint16_t phy_id,
+			      uint16_t reg_num, unsigned int *val)
+{
+	mtk_mii->phy_id  = phy_id;
+	mtk_mii->reg_num = reg_num;
+	mtk_mii->val_in  = *val;
+	mtk_mii->val_out = 0;
+}
+
-static int __phy_op(char *ifname,uint16_t phy_id,uint16_t reg_num, uint16_t *val, int cmd)
+static int __phy_op(char *ifname, uint16_t phy_id, uint16_t reg_num, unsigned int *val, uint16_t cmd, int is_priv)
 {
         static int sd = -1;
 
         struct ifreq ifr;
-        struct mii_ioctl_data* mii = (struct mii_ioctl_data *)(&ifr.ifr_data);
+        struct mii_ioctl_data mii;
+	struct mtk_mii_ioctl_data mtk_mii;
         int err;
 
         if (sd < 0)
@@ -45,27 +67,37 @@
 
         strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
 
-        mii->phy_id  = phy_id;
-        mii->reg_num = reg_num;
-        mii->val_in  = *val;
-        mii->val_out = 0;
+	if (is_priv) {
+		fill_mtk_mii_ioctl(&mtk_mii, phy_id, reg_num, val);
+		ifr.ifr_data = (char *)&mtk_mii;
+	} else {
+		fill_mii_ioctl(&mii, phy_id, reg_num, (uint16_t *)val);
+		ifr.ifr_data = (char *)&mii;
+	}
 
         err = ioctl(sd, cmd, &ifr);
         if (err)
                 return -errno;
 
+	if ((cmd == MTKETH_MII_WRITE) || (cmd == MTKETH_MII_WRITE_CL45) ||
+	    (cmd == SIOCSMIIREG))
+		*val = (is_priv) ? mtk_mii.val_in : mii.val_in;
+	else
+		*val = (is_priv) ? mtk_mii.val_out : mii.val_out;
+
-        *val = mii->val_out;
         return 0;
 }
 
 int main(int argc, char *argv[])
 {
 	int opt;
-	char options[] = "gsi:p:d:r:v:?t";
+	char options[] = "gsui:p:d:r:v:?t";
 	int is_write = 0,is_cl45 = 0;
+	int is_priv = 1;
 	unsigned int port=0, dev=0,reg_num=0,val=0;
 	char ifname[IFNAMSIZ]="eth0";	
 	uint16_t phy_id=0;
+	uint16_t cmd;
 
 
 	if (argc < 6) {
@@ -81,6 +113,9 @@
 			case 's':
 				is_write=1;
 				break;
+			case 'u':
+				is_priv = 0;
+				break;
 			case 'i':
 				strncpy(ifname,optarg, 5);
 				break;	
@@ -110,7 +145,13 @@
 		phy_id = port;
 
 	if(is_write) { 
-		__phy_op(ifname,phy_id,reg_num,(uint16_t *)&val,SIOCSMIIREG);
+		if (is_priv)
+			cmd = (is_cl45) ? MTKETH_MII_WRITE_CL45 :
+					  MTKETH_MII_WRITE;
+		else
+			cmd = SIOCSMIIREG;
+
+		__phy_op(ifname,phy_id,reg_num, &val, cmd, is_priv);
 
 		if(is_cl45)
 			printf("Set: port%x dev%Xh_reg%Xh = 0x%04X\n",port, dev, reg_num, val);
@@ -118,7 +159,13 @@
 			printf("Set: phy[%x].reg[%x] = %04x\n",port, reg_num, val);
 	}	
 	else {
-		__phy_op(ifname,phy_id,reg_num,(uint16_t *)&val,SIOCGMIIREG);
+		if (is_priv)
+			cmd = (is_cl45) ? MTKETH_MII_READ_CL45 :
+					  MTKETH_MII_READ;
+		else
+			cmd = SIOCGMIIREG;
+
+		__phy_op(ifname,phy_id,reg_num, &val, cmd, is_priv);
 
 		if(is_cl45)
 			printf("Get: port%x dev%Xh_reg%Xh = 0x%04X\n",port, dev, reg_num, val);