예제 #1
0
/******************************************************************************
* mv_eth_tool_restore_settings
* Description:
*	restore saved speed/dublex/an settings
* INPUT:
*	netdev		Network device structure pointer
* OUTPUT
*	None
* RETURN:
*	0 for success
*
*******************************************************************************/
int mv_eth_tool_restore_settings(struct net_device *netdev)
{
	struct eth_port 	*priv = MV_ETH_PRIV(netdev);
	int 				mv_phy_speed, mv_phy_duplex;
	MV_U32			    mv_phy_addr = mvBoardPhyAddrGet(priv->port);
	MV_ETH_PORT_SPEED	mv_mac_speed;
	MV_ETH_PORT_DUPLEX	mv_mac_duplex;
	int			err = -EINVAL;

	 if ((priv == NULL) || (isSwitch(priv)))
		 return -EOPNOTSUPP;

	switch (priv->speed_cfg) {
	case SPEED_10:
		mv_phy_speed  = 0;
		mv_mac_speed = MV_ETH_SPEED_10;
		break;
	case SPEED_100:
		mv_phy_speed  = 1;
		mv_mac_speed = MV_ETH_SPEED_100;
		break;
	case SPEED_1000:
		mv_phy_speed  = 2;
		mv_mac_speed = MV_ETH_SPEED_1000;
		break;
	default:
		return -EINVAL;
	}

	switch (priv->duplex_cfg) {
	case DUPLEX_HALF:
		mv_phy_duplex = 0;
		mv_mac_duplex = MV_ETH_DUPLEX_HALF;
		break;
	case DUPLEX_FULL:
		mv_phy_duplex = 1;
		mv_mac_duplex = MV_ETH_DUPLEX_FULL;
		break;
	default:
		return -EINVAL;
	}

	if (priv->autoneg_cfg == AUTONEG_ENABLE) {
		err = mvNetaSpeedDuplexSet(priv->port, MV_ETH_SPEED_AN, MV_ETH_DUPLEX_AN);
		if (!err)
			err = mvEthPhyAdvertiseSet(mv_phy_addr, priv->advertise_cfg);
		/* Restart AN on PHY enables it */
		if (!err) {

			err = mvEthPhyRestartAN(mv_phy_addr, MV_ETH_TOOL_AN_TIMEOUT);
			if (err == MV_TIMEOUT) {
				MV_ETH_PORT_STATUS ps;

				mvNetaLinkStatus(priv->port, &ps);

				if (!ps.linkup)
					err = 0;
			}
		}
	} else if (priv->autoneg_cfg == AUTONEG_DISABLE) {
		err = mvEthPhyDisableAN(mv_phy_addr, mv_phy_speed, mv_phy_duplex);
		if (!err)
			err = mvNetaSpeedDuplexSet(priv->port, mv_mac_speed, mv_mac_duplex);
	} else {
		err = -EINVAL;
	}
	return err;
}
예제 #2
0
/******************************************************************************
* mv_eth_tool_restore_settings
* Description:
*	restore saved speed/dublex/an settings
* INPUT:
*	netdev		Network device structure pointer
* OUTPUT
*	None
* RETURN:
*	0 for success
*
*******************************************************************************/
int mv_eth_tool_restore_settings(struct net_device *netdev)
{
	mv_eth_priv 		*priv = MV_ETH_PRIV(netdev);
	int 			mv_phy_speed, mv_phy_duplex;
	MV_U32			mv_phy_addr = priv->phy_id;
	MV_ETH_PORT_SPEED	mv_mac_speed;
	MV_ETH_PORT_DUPLEX	mv_mac_duplex;
	int			err = -EINVAL;

	switch (priv->speed_cfg) {
		case SPEED_10:
			mv_phy_speed  = 0;
			mv_mac_speed = MV_ETH_SPEED_10;
			break;
		case SPEED_100:
			mv_phy_speed  = 1;
			mv_mac_speed = MV_ETH_SPEED_100;
			break;
		case SPEED_1000:
			mv_phy_speed  = 2;
			mv_mac_speed = MV_ETH_SPEED_1000;
			break;
		default:
			return -EINVAL;
	}

	switch (priv->duplex_cfg) {
		case DUPLEX_HALF:
			mv_phy_duplex = 0;
			mv_mac_duplex = MV_ETH_DUPLEX_HALF;
			break;
		case DUPLEX_FULL:
			mv_phy_duplex = 1;
			mv_mac_duplex = MV_ETH_DUPLEX_FULL;
			break;
		default:
			return -EINVAL;
	}
	
	if (priv->autoneg_cfg == AUTONEG_ENABLE) {
		err = mvEthSpeedDuplexSet(priv->hal_priv,
					  MV_ETH_SPEED_AN, MV_ETH_DUPLEX_AN);

		/* Restart AN on PHY enables it */
		if (!err) {

			err = mvEthPhyRestartAN(mv_phy_addr, MV_ETH_TOOL_AN_TIMEOUT);
			if (err == MV_TIMEOUT) {
				MV_ETH_PORT_STATUS ps;
				mvEthStatusGet(priv->hal_priv, &ps);
				if (!ps.isLinkUp)
					err = 0;
			}
		}
	} else if (priv->autoneg_cfg == AUTONEG_DISABLE) {
		err = mvEthPhyDisableAN(mv_phy_addr, mv_phy_speed, mv_phy_duplex);
		if (!err) {
			err = mvEthSpeedDuplexSet(priv->hal_priv,
					mv_mac_speed, mv_mac_duplex);
		}
	} else {
		err = -EINVAL;
	}

	return err;
}