/****************************************************************************** * mv_eth_tool_set_pauseparam * Description: * ethtool configure pause parameters * INPUT: * netdev Network device structure pointer * pause Pause paranmeters * OUTPUT * None * RETURN: * 0 on success * *******************************************************************************/ int mv_eth_tool_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { struct eth_port *priv = MV_ETH_PRIV(netdev); int port = priv->port; MV_U32 phy_addr; MV_STATUS status = MV_FAIL; #ifdef CONFIG_MV_ETH_SWITCH if (isSwitch(priv)) return -EPERM; #endif /* CONFIG_MV_ETH_SWITCH */ if (pause->rx_pause && pause->tx_pause) { /* Enable FC */ if (pause->autoneg) { /* autoneg enable */ status = mvNetaFlowCtrlSet(port, MV_ETH_FC_AN_SYM); } else { /* autoneg disable */ status = mvNetaFlowCtrlSet(port, MV_ETH_FC_ENABLE); } } else if (!pause->rx_pause && !pause->tx_pause) { /* Disable FC */ if (pause->autoneg) { /* autoneg enable */ status = mvNetaFlowCtrlSet(port, MV_ETH_FC_AN_NO); } else { /* autoneg disable */ status = mvNetaFlowCtrlSet(port, MV_ETH_FC_DISABLE); } } /* Only symmetric change for RX and TX flow control is allowed */ if (status == MV_OK) { phy_addr = mvBoardPhyAddrGet(priv->port); status = mvEthPhyRestartAN(phy_addr, MV_ETH_TOOL_AN_TIMEOUT); } if (status != MV_OK) return -EINVAL; return 0; }
/****************************************************************************** * mv_eth_tool_set_pauseparam * Description: * ethtool configure pause parameters * INPUT: * netdev Network device structure pointer * pause Pause paranmeters * OUTPUT * None * RETURN: * 0 on success * *******************************************************************************/ int mv_eth_tool_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { struct eth_port *priv = MV_ETH_PRIV(netdev); int port = priv->port; MV_U32 phy_addr; MV_STATUS status = MV_FAIL; 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; } if (pause->rx_pause && pause->tx_pause) { /* Enable FC */ if (pause->autoneg) { /* autoneg enable */ status = mvNetaFlowCtrlSet(port, MV_ETH_FC_AN_SYM); } else { /* autoneg disable */ status = mvNetaFlowCtrlSet(port, MV_ETH_FC_ENABLE); } } else if (!pause->rx_pause && !pause->tx_pause) { /* Disable FC */ if (pause->autoneg) { /* autoneg enable */ status = mvNetaFlowCtrlSet(port, MV_ETH_FC_AN_NO); } else { /* autoneg disable */ status = mvNetaFlowCtrlSet(port, MV_ETH_FC_DISABLE); } } /* Only symmetric change for RX and TX flow control is allowed */ if (status == MV_OK) { phy_addr = mvBoardPhyAddrGet(priv->port); status = mvEthPhyRestartAN(phy_addr, MV_ETH_TOOL_AN_TIMEOUT); } if (status != MV_OK) return -EINVAL; return 0; }