Beispiel #1
0
/******************************************************************************
* mv_eth_tool_get_pauseparam
* Description:
*	ethtool get pause parameters
* INPUT:
*	netdev		Network device structure pointer
* OUTPUT
*	pause		Pause paranmeters
* RETURN:
*	None
*
*******************************************************************************/
void mv_eth_tool_get_pauseparam(struct net_device *netdev,
				struct ethtool_pauseparam *pause)
{
	struct eth_port      *priv = MV_ETH_PRIV(netdev);
	int                  port = priv->port;
	MV_ETH_PORT_STATUS   portStatus;
	MV_ETH_PORT_FC       flowCtrl;

	if ((priv == NULL) || (isSwitch(priv)) || (MV_PON_PORT(priv->port))) {
		printk(KERN_ERR "%s is not supported on %s\n", __func__, netdev->name);
		return;
	}

	mvNetaFlowCtrlGet(port, &flowCtrl);
	if ((flowCtrl == MV_ETH_FC_AN_NO) || (flowCtrl == MV_ETH_FC_AN_SYM) || (flowCtrl == MV_ETH_FC_AN_ASYM))
		pause->autoneg = AUTONEG_ENABLE;
	else
		pause->autoneg = AUTONEG_DISABLE;

	mvNetaLinkStatus(port, &portStatus);
	if (portStatus.rxFc == MV_ETH_FC_DISABLE)
		pause->rx_pause = 0;
	else
		pause->rx_pause = 1;

	if (portStatus.txFc == MV_ETH_FC_DISABLE)
		pause->tx_pause = 0;
	else
		pause->tx_pause = 1;
}
Beispiel #2
0
/******************************************************************************
* mv_eth_tool_get_pauseparam
* Description:
*	ethtool get pause parameters
* INPUT:
*	netdev		Network device structure pointer
* OUTPUT
*	pause		Pause paranmeters
* RETURN:
*	None
*
*******************************************************************************/
void mv_eth_tool_get_pauseparam(struct net_device *netdev,
				struct ethtool_pauseparam *pause)
{
	struct eth_port 	*priv = MV_ETH_PRIV(netdev);
	int 			port = priv->port;
	MV_ETH_PORT_STATUS	portStatus;
	MV_ETH_PORT_FC 		flowCtrl;

#ifdef CONFIG_MV_ETH_SWITCH
	if (isSwitch(priv)) {
		printk("mv_eth_tool_get_pauseparam() is not supported on a switch port\n");
		return;
	}
#endif /* CONFIG_MV_ETH_SWITCH */

	mvNetaFlowCtrlGet(port, &flowCtrl);
	if ((flowCtrl == MV_ETH_FC_AN_NO) || (flowCtrl == MV_ETH_FC_AN_SYM) || (flowCtrl == MV_ETH_FC_AN_ASYM))
		pause->autoneg = AUTONEG_ENABLE;
	else
		pause->autoneg = AUTONEG_DISABLE;

	mvNetaLinkStatus(port, &portStatus);
	if (portStatus.rxFc == MV_ETH_FC_DISABLE)
		pause->rx_pause = 0;
	else
		pause->rx_pause = 1;

	if (portStatus.txFc == MV_ETH_FC_DISABLE)
		pause->tx_pause = 0;
	else
		pause->tx_pause = 1;
}
/******************************************************************************
* mv_eth_tool_get_settings
* Description:
*	ethtool get standard port settings
* INPUT:
*	netdev		Network device structure pointer
* OUTPUT
*	cmd		command (settings)
* RETURN:
*	0 for success
*
*******************************************************************************/
int mv_eth_tool_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
{
	struct eth_port 	*priv = MV_ETH_PRIV(netdev);
	MV_U32			mv_phy_addr;
	MV_ETH_PORT_SPEED 	speed;
	MV_ETH_PORT_DUPLEX 	duplex;
	MV_ETH_PORT_STATUS      status;

	if ((priv == NULL) || (isSwitch(priv)) || (MV_PON_PORT(priv->port))) {
		printk(KERN_ERR "%s is not supported on %s\n", __func__, netdev->name);
		return -EOPNOTSUPP;
	}

	cmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half
			| SUPPORTED_100baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII
			| SUPPORTED_1000baseT_Full);

	mv_phy_addr = mvBoardPhyAddrGet(priv->port);

	mvNetaLinkStatus(priv->port, &status);

	switch (status.speed) {
	case MV_ETH_SPEED_1000:
		cmd->speed = SPEED_1000;
		break;
	case MV_ETH_SPEED_100:
		cmd->speed = SPEED_100;
		break;
	case MV_ETH_SPEED_10:
		cmd->speed = SPEED_10;
		break;
	default:
		return -EINVAL;
	}

	if (status.duplex == MV_ETH_DUPLEX_FULL)
		cmd->duplex = 1;
	else
		cmd->duplex = 0;

	cmd->port = PORT_MII;
	cmd->phy_address = mv_phy_addr;
	cmd->transceiver = XCVR_INTERNAL;
	/* check if speed and duplex are AN */
	mvNetaSpeedDuplexGet(priv->port, &speed, &duplex);
	if (speed == MV_ETH_SPEED_AN && duplex == MV_ETH_DUPLEX_AN) {
		/* Note: lp_advertising not available in this kernel */
		cmd->advertising = 0;
		cmd->autoneg = AUTONEG_ENABLE;
		mvEthPhyAdvertiseGet(mv_phy_addr, (MV_U16 *)&(cmd->advertising));
	} else
		cmd->autoneg = AUTONEG_DISABLE;

	return 0;
}
Beispiel #4
0
/******************************************************************************
* mv_eth_tool_get_settings
* Description:
*	ethtool get standard port settings
* INPUT:
*	netdev		Network device structure pointer
* OUTPUT
*	cmd		command (settings)
* RETURN:
*	0 for success
*
*******************************************************************************/
int mv_eth_tool_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
{
	struct eth_port 	*priv = MV_ETH_PRIV(netdev);

	int		 retval;
#ifdef CONFIG_MV_ETH_SWITCH
	 if (isSwitch(priv))
		 return -EPERM;
#endif /* CONFIG_MV_ETH_SWITCH */

#ifdef CONFIG_MII
	retval = mii_ethtool_gset(&priv->mii, cmd);
	if (retval)
		return retval;
#endif /* CONFIG_MII */

	if (priv) {
		MV_ETH_PORT_STATUS  status;

		mvNetaLinkStatus(priv->port, &status);

		switch (status.speed) {
		case MV_ETH_SPEED_1000:
			cmd->speed = SPEED_1000;
			break;
		case MV_ETH_SPEED_100:
			cmd->speed = SPEED_100;
			break;
		case MV_ETH_SPEED_10:
			cmd->speed = SPEED_10;
			break;
		default:
			return -EINVAL;
		}

		if (status.duplex == MV_ETH_DUPLEX_FULL)
			cmd->duplex = 1;
		else
			cmd->duplex = 0;

		cmd->port = PORT_MII;
		cmd->phy_address = mvBoardPhyAddrGet(priv->port);
	}
	return 0;
}
Beispiel #5
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;
}