[qca-ssdk]: fix apply command run faild issue.

support switch between sfp and copper for port 5, including of
phydriver and phy address when changing interface mode.

Change-Id: I5c1f2cf06f86723179511468bf603740edfcfa6c
Signed-off-by: Liu Zhongjian <zhongjia@codeaurora.org>
diff --git a/include/hsl/phy/hsl_phy.h b/include/hsl/phy/hsl_phy.h
index 8b579cf..244b578 100755
--- a/include/hsl/phy/hsl_phy.h
+++ b/include/hsl/phy/hsl_phy.h
@@ -295,6 +295,7 @@
 
 typedef struct {
 	a_uint32_t phy_address[SW_MAX_NR_PORT];
+	a_uint32_t phy_address_from_dts[SW_MAX_NR_PORT];
 	a_uint32_t phy_type[SW_MAX_NR_PORT];
 	a_bool_t phy_c45[SW_MAX_NR_PORT];
 	a_bool_t phy_combo[SW_MAX_NR_PORT];
@@ -342,7 +343,7 @@
 
 void qca_ssdk_port_bmp_init(a_uint32_t dev_id);
 
-void qca_ssdk_phy_address_set(a_uint32_t dev_id, a_uint32_t i,
+void hsl_phy_address_init(a_uint32_t dev_id, a_uint32_t i,
 				a_uint32_t value);
 
 a_uint32_t
@@ -380,6 +381,17 @@
 
 sw_error_t ssdk_phy_driver_cleanup(void);
 
+sw_error_t
+hsl_phydriver_update(a_uint32_t dev_id, a_uint32_t port_id,
+	a_uint32_t mode);
+
+void
+qca_ssdk_phy_address_set(a_uint32_t dev_id, a_uint32_t port_id,
+	a_uint32_t phy_addr);
+
+a_uint32_t
+qca_ssdk_phy_address_from_dts_get(a_uint32_t dev_id, a_uint32_t port_id);
+
 #ifdef __cplusplus
 }
 #endif				/* __cplusplus */
diff --git a/src/adpt/hppe/adpt_hppe_portctrl.c b/src/adpt/hppe/adpt_hppe_portctrl.c
index ecd791c..951a50c 100755
--- a/src/adpt/hppe/adpt_hppe_portctrl.c
+++ b/src/adpt/hppe/adpt_hppe_portctrl.c
@@ -888,7 +888,7 @@
 	mru_mtu_ctrl_tbl.bf.mtu_cmd = (a_uint32_t)ctrl->action;
 	hppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &mru_mtu_ctrl_tbl);
 
-	if ((port_id >= 0) && (port_id <= 7))
+	if ((port_id >= SSDK_PHYSICAL_PORT0) && (port_id <= SSDK_PHYSICAL_PORT7))
 	{
 		hppe_mc_mtu_ctrl_tbl_mtu_set(dev_id, port_id, ctrl->mtu_size);
 		hppe_mc_mtu_ctrl_tbl_mtu_cmd_set(dev_id, port_id, (a_uint32_t)ctrl->action);
@@ -2339,8 +2339,8 @@
 				else
 					return SW_OK;
 			}
- 			switch(port_id)
- 			{
+			switch(port_id)
+			{
 				case SSDK_PHYSICAL_PORT1:
 					*mode0 = PORT_WRAPPER_SGMII_CHANNEL0;
 					break;
@@ -2411,17 +2411,16 @@
 	ADPT_DEV_ID_CHECK(dev_id);
 
 	if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY))
-	  {
+	{
 		return SW_BAD_PARAM;
-	  }
-
+	}
 	SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id));
 	if (NULL == phy_drv->phy_interface_mode_set)
 		return SW_NOT_SUPPORTED;
 
 	rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id);
 	SW_RTN_ON_ERROR (rv);
-
+	SSDK_DEBUG("port_id:%x, phy_id:%x, mode:%x\n", port_id, phy_id, mode);
 	rv = phy_drv->phy_interface_mode_set (dev_id, phy_id,mode);
 
 	return rv;
@@ -2442,6 +2441,54 @@
 
 	return rv;
 }
+
+static sw_error_t
+_adpt_hppe_port_phyaddr_update(a_uint32_t dev_id, a_uint32_t port_id,
+	a_uint32_t mode)
+{
+	sw_error_t rv = SW_OK;
+	a_uint32_t phy_addr = 0, mode0 = PORT_WRAPPER_MAX;
+
+	if(port_id != SSDK_PHYSICAL_PORT5)
+	{
+		return rv;
+	}
+	if(mode == PORT_WRAPPER_10GBASE_R)
+	{
+		phy_addr = qca_ssdk_phy_address_from_dts_get(dev_id, port_id);
+		qca_ssdk_phy_address_set(dev_id, port_id, phy_addr);
+		SSDK_DEBUG("port %x phy_addr is %x\n", port_id, phy_addr);
+	}
+	else
+	{
+		mode0 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0);
+		if((mode0 == PORT_WRAPPER_PSGMII || mode0 == PORT_WRAPPER_PSGMII_FIBER) &&
+			mode == PORT_WRAPPER_MAX)
+		{
+			rv = hsl_port_prop_get_phyid (dev_id, SSDK_PHYSICAL_PORT4, &phy_addr);
+			SW_RTN_ON_ERROR (rv);
+			phy_addr++;
+			qca_ssdk_phy_address_set(dev_id, port_id, phy_addr);
+			SSDK_DEBUG("port %x phy_addr is %x\n", port_id, phy_addr);
+		}
+	}
+
+	return rv;
+}
+
+static sw_error_t
+_adpt_hppe_sfp_copper_phydriver_switch(a_uint32_t dev_id, a_uint32_t port_id,
+	a_uint32_t mode)
+{
+	sw_error_t rv = SW_OK;
+
+	rv = _adpt_hppe_port_phyaddr_update(dev_id, port_id, mode);
+	SW_RTN_ON_ERROR(rv);
+	rv = hsl_phydriver_update(dev_id, port_id, mode);
+
+	return rv;
+}
+
 static sw_error_t
 _adpt_hppe_port_phy_config(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode)
 {
@@ -2450,18 +2497,23 @@
 	switch(mode)
 	{
 		case PORT_WRAPPER_PSGMII:
+			/*interface mode changed form psgmii+usxgmii to psgmii+10gbase-r+usxgmii, cannot
+			use port 5 to configure malibu*/
 			rv = _adpt_hppe_port_interface_mode_phy_config(dev_id,
-				SSDK_PHYSICAL_PORT5, PHY_PSGMII_BASET);
+				SSDK_PHYSICAL_PORT4, PHY_PSGMII_BASET);
 			break;
 		case PORT_WRAPPER_PSGMII_FIBER:
 			rv = _adpt_hppe_port_interface_mode_phy_config(dev_id,
-				SSDK_PHYSICAL_PORT5, PHY_PSGMII_FIBER);
+				SSDK_PHYSICAL_PORT4, PHY_PSGMII_FIBER);
 			break;
 		case PORT_WRAPPER_SGMII_CHANNEL4:
-		case PORT_WRAPPER_QSGMII:
 			rv = _adpt_hppe_port_interface_mode_phy_config(dev_id,
 				SSDK_PHYSICAL_PORT5, PHY_SGMII_BASET);
 			break;
+		case PORT_WRAPPER_QSGMII:
+			rv = _adpt_hppe_port_interface_mode_phy_config(dev_id,
+				SSDK_PHYSICAL_PORT4, PHY_SGMII_BASET);
+			break;
 		case PORT_WRAPPER_SGMII_CHANNEL0:
 			if(index == SSDK_UNIPHY_INSTANCE1)
 			{
@@ -2621,6 +2673,9 @@
 		}
 	}
 	/*config phy*/
+	rv = _adpt_hppe_sfp_copper_phydriver_switch(dev_id, SSDK_PHYSICAL_PORT5, mode1);
+	SW_RTN_ON_ERROR(rv);
+
 	rv = _adpt_hppe_port_phy_config(dev_id, SSDK_UNIPHY_INSTANCE0, mode0);
 	if(rv)
 	{
diff --git a/src/hsl/phy/hsl_phy.c b/src/hsl/phy/hsl_phy.c
index a6e3f27..11a3ba1 100755
--- a/src/hsl/phy/hsl_phy.c
+++ b/src/hsl/phy/hsl_phy.c
@@ -14,6 +14,7 @@
 
 #include "sw.h"
 #include "hsl_phy.h"
+#include "hsl.h"
 #if defined(ISIS) ||defined(ISISC) ||defined(GARUDA)
 #include <f1_phy.h>
 #endif
@@ -154,6 +155,83 @@
 	return phy_id;
 }
 
+phy_type_t hsl_phytype_get_by_phyid(a_uint32_t dev_id, a_uint32_t phy_id)
+{
+	phy_type_t phytype = MAX_PHY_CHIP;
+
+	switch (phy_id)
+	{
+		case F1V1_PHY:
+		case F1V2_PHY:
+		case F1V3_PHY:
+		case F1V4_PHY:
+			phytype = F1_PHY_CHIP;
+			break;
+		case F2V1_PHY:
+			phytype = F2_PHY_CHIP;
+			break;
+		case MALIBU2PORT_PHY:
+		case MALIBU5PORT_PHY:
+			phytype = MALIBU_PHY_CHIP;
+			break;
+		case AQUANTIA_PHY_107:
+		case AQUANTIA_PHY_108:
+		case AQUANTIA_PHY_109:
+		case AQUANTIA_PHY_111:
+		case AQUANTIA_PHY_111B0:
+		case AQUANTIA_PHY_112:
+			phytype = AQUANTIA_PHY_CHIP;
+			break;
+		case QCA8030_PHY:
+		case QCA8033_PHY:
+		case QCA8035_PHY:
+			phytype = QCA803X_PHY_CHIP;
+			break;
+		case SFP_PHY:
+			phytype = SFP_PHY_CHIP;
+			break;
+		default:
+			phytype = MAX_PHY_CHIP;
+	}
+
+	return phytype;
+}
+
+sw_error_t hsl_phydriver_update(a_uint32_t dev_id, a_uint32_t port_id,
+	a_uint32_t mode)
+{
+	a_uint32_t phy_id;
+	phy_type_t phytype;
+	ssdk_init_cfg cfg;
+
+	cfg.chip_type = CHIP_HPPE;
+	if(port_id == SSDK_PHYSICAL_PORT5)
+	{
+		cfg.mac_mode1 = mode;
+	}
+	else if(port_id == SSDK_PHYSICAL_PORT6)
+	{
+		cfg.mac_mode2 = mode;
+	}
+	else
+	{
+		return SW_NOT_SUPPORTED;
+	}
+	cfg.reg_func.mdio_get = reduce_hsl_phy_get;
+
+	phy_id = hsl_phyid_get(dev_id, port_id, &cfg);
+	phytype = hsl_phytype_get_by_phyid(dev_id, phy_id);
+	SSDK_DEBUG("port_id is %x, phy_id is %x, phy_type is:%x\n",
+		port_id, phy_id, phytype);
+	if (MAX_PHY_CHIP != phytype)
+	{
+		phy_info[dev_id]->phy_type[port_id] = phytype;
+		ssdk_phy_driver[phytype].port_bmp[dev_id] |= (0x1 << port_id);
+	}
+
+	return SW_OK;
+}
+
 int ssdk_phy_driver_init(a_uint32_t dev_id, ssdk_init_cfg *cfg)
 {
 
@@ -166,42 +244,9 @@
 		if (port_bmp[dev_id] & (0x1 << i))
 		{
 			phy_id = hsl_phyid_get(dev_id, i, cfg);
-			switch (phy_id) {
-				case F1V1_PHY:
-				case F1V2_PHY:
-				case F1V3_PHY:
-				case F1V4_PHY:
-					phytype = F1_PHY_CHIP;
-					break;
-				case F2V1_PHY:
-					phytype = F2_PHY_CHIP;
-					break;
-				case MALIBU2PORT_PHY:
-				case MALIBU5PORT_PHY:
-					phytype = MALIBU_PHY_CHIP;
-					break;
-				case AQUANTIA_PHY_107:
-				case AQUANTIA_PHY_108:
-				case AQUANTIA_PHY_109:
-				case AQUANTIA_PHY_111:
-				case AQUANTIA_PHY_111B0:
-				case AQUANTIA_PHY_112:
-					phytype = AQUANTIA_PHY_CHIP;
-					break;
-				case QCA8030_PHY:
-				case QCA8033_PHY:
-				case QCA8035_PHY:
-					phytype = QCA803X_PHY_CHIP;
-					break;
-				case SFP_PHY:
-					phytype = SFP_PHY_CHIP;
-					break;
-				default:
-					phytype = MAX_PHY_CHIP;
-					SSDK_INFO("dev_id = %d, phy_adress = %d, phy_id = 0x%x phy type doesn't match\n",
-							dev_id, phy_info[dev_id]->phy_address[i], phy_id);
-			}
-
+			phytype = hsl_phytype_get_by_phyid(dev_id, phy_id);
+			SSDK_INFO("dev_id = %d, phy_adress = %d, phy_id = 0x%x phy type doesn't match\n",
+						dev_id, phy_info[dev_id]->phy_address[i], phy_id);
 			if (MAX_PHY_CHIP != phytype) {
 				phy_info[dev_id]->phy_type[i] = phytype;
 				ssdk_phy_driver[phytype].port_bmp[dev_id] |= (0x1 << i);
@@ -244,10 +289,11 @@
 	return;
 }
 
-void qca_ssdk_phy_address_set(a_uint32_t dev_id, a_uint32_t i,
+void hsl_phy_address_init(a_uint32_t dev_id, a_uint32_t i,
 			a_uint32_t value)
 {
 	phy_info[dev_id]->phy_address[i] = value;
+	phy_info[dev_id]->phy_address_from_dts[i] = value;
 
 	return;
 }
@@ -272,6 +318,23 @@
 	return ssdk_phy_driver[phy_type].port_bmp[dev_id];
 }
 
+void
+qca_ssdk_phy_address_set(a_uint32_t dev_id, a_uint32_t port_id,
+	a_uint32_t phy_addr)
+{
+	 phy_info[dev_id]->phy_address[port_id] = phy_addr;
+
+	return;
+}
+
+a_uint32_t
+qca_ssdk_phy_address_from_dts_get(a_uint32_t dev_id,
+	a_uint32_t port_id)
+{
+	 return phy_info[dev_id]->phy_address_from_dts[port_id];
+}
+
+
 a_uint32_t
 qca_ssdk_port_to_phy_addr(a_uint32_t dev_id, a_uint32_t port_id)
 {
diff --git a/src/init/ssdk_init.c b/src/init/ssdk_init.c
index eee1080..c02815f 100755
--- a/src/init/ssdk_init.c
+++ b/src/init/ssdk_init.c
@@ -2604,7 +2604,7 @@
 
 		hsl_port_phy_combo_capability_set(dev_id, port_id, phy_combo);
 		hsl_port_phy_c45_capability_set(dev_id, port_id, phy_c45);
-		qca_ssdk_phy_address_set(dev_id, port_id, phy_addr);
+		hsl_phy_address_init(dev_id, port_id, phy_addr);
 	}
 
 	return rv;
@@ -2631,15 +2631,17 @@
 		SSDK_INFO("mdio DT exist!\n");
 		for_each_available_child_of_node(mdio_node, child) {
 			phy_addr = of_get_property(child, "reg", &len);
-			if (phy_addr)
-				qca_ssdk_phy_address_set(dev_id, i, be32_to_cpup(phy_addr));
-
+			if (phy_addr) {
+				hsl_phy_address_init(dev_id, i, be32_to_cpup(phy_addr));
+			}
 			c45_phy = of_get_property(child, "compatible", &len);
-			if (c45_phy)
+			if (c45_phy) {
 				hsl_port_phy_c45_capability_set(dev_id, i, A_TRUE);
+			}
 			i++;
-			if (i >= SW_MAX_NR_PORT)
+			if (i >= SW_MAX_NR_PORT) {
 				break;
+			}
 		}
 	}
 	return;