コード例 #1
0
ファイル: mv_eth_tool.c プロジェクト: jameshilliard/prism
/******************************************************************************
* 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;
}
コード例 #2
0
ファイル: mv_eth_tool.c プロジェクト: jameshilliard/prism
/******************************************************************************
* mv_eth_tool_set_settings
* Description:
*	ethtool set standard port settings
* INPUT:
*	netdev		Network device structure pointer
*	cmd		command (settings)
* OUTPUT
*	None
* RETURN:
*	0 for success
*
*******************************************************************************/
int mv_eth_tool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct eth_port *priv = MV_ETH_PRIV(dev);
	int _speed, _duplex, _autoneg, _advertise, err;

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

	_duplex  = priv->duplex_cfg;
	_speed   = priv->speed_cfg;
	_autoneg = priv->autoneg_cfg;
	_advertise = priv->advertise_cfg;

	priv->duplex_cfg = cmd->duplex;
	priv->speed_cfg = cmd->speed;
	priv->autoneg_cfg = cmd->autoneg;
	priv->advertise_cfg = cmd->advertising;
	err = mv_eth_tool_restore_settings(dev);

	if (err) {
		priv->duplex_cfg = _duplex;
		priv->speed_cfg = _speed;
		priv->autoneg_cfg = _autoneg;
		priv->advertise_cfg = _advertise;
	}
	return err;
}
/******************************************************************************
* 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;
}
コード例 #4
0
/*******************************************************************************
* mvEthMibCountersClear - Clear all MIB counters
*
* DESCRIPTION:
*       This function clears all MIB counters
*
* INPUT:
*       port      - Ethernet Port number.
*
* RETURN:   void
*
*******************************************************************************/
void mvEthMibCountersClear(int port)
{
	int i;
	MV_U32 dummy;

#if defined(CONFIG_MV_PON) && !defined(MV_PON_MIB_SUPPORT)
	if (MV_PON_PORT(port))
		return;
#endif /* CONFIG_MV_PON && !MV_PON_MIB_SUPPORT */

	/* Perform dummy reads from MIB counters */
	for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION; i += 4)
		dummy = MV_REG_READ((ETH_MIB_COUNTERS_BASE(port) + i));
}
コード例 #5
0
MV_STATUS mvEthLinkStatus(int port, MV_ETH_PORT_STATUS *pStatus)
{
	MV_U32 regVal;

	if (MV_PON_PORT(port)) {
		pStatus->linkup = MV_TRUE;
		pStatus->speed = MV_ETH_SPEED_1000;
		pStatus->duplex = MV_ETH_DUPLEX_FULL;
		pStatus->rxFc = MV_ETH_FC_DISABLE;
		pStatus->txFc = MV_ETH_FC_DISABLE;
		return MV_OK;
	}

	regVal = MV_REG_READ(ETH_GMAC_STATUS_REG(port));

	if (regVal & ETH_GMAC_SPEED_1000_MASK)
		pStatus->speed = MV_ETH_SPEED_1000;
	else if (regVal & ETH_GMAC_SPEED_100_MASK)
		pStatus->speed = MV_ETH_SPEED_100;
	else
		pStatus->speed = MV_ETH_SPEED_10;

	if (regVal & ETH_GMAC_LINK_UP_MASK)
		pStatus->linkup = MV_TRUE;
	else
		pStatus->linkup = MV_FALSE;

	if (regVal & ETH_GMAC_FULL_DUPLEX_MASK)
		pStatus->duplex = MV_ETH_DUPLEX_FULL;
	else
		pStatus->duplex = MV_ETH_DUPLEX_HALF;

	if (regVal & ETH_TX_FLOW_CTRL_ACTIVE_MASK)
		pStatus->txFc = MV_ETH_FC_ACTIVE;
	else if (regVal & ETH_TX_FLOW_CTRL_ENABLE_MASK)
		pStatus->txFc = MV_ETH_FC_ENABLE;
	else
		pStatus->txFc = MV_ETH_FC_DISABLE;

	if (regVal & ETH_RX_FLOW_CTRL_ACTIVE_MASK)
		pStatus->rxFc = MV_ETH_FC_ACTIVE;
	else if (regVal & ETH_RX_FLOW_CTRL_ENABLE_MASK)
		pStatus->rxFc = MV_ETH_FC_ENABLE;
	else
		pStatus->rxFc = MV_ETH_FC_DISABLE;

	return MV_OK;
}
コード例 #6
0
ファイル: mv_eth_tool.c プロジェクト: jameshilliard/prism
/******************************************************************************
* mv_eth_tool_nway_reset
* Description:
*	ethtool restart auto negotiation
* INPUT:
*	netdev		Network device structure pointer
* OUTPUT
*	None
* RETURN:
*	0 on success
*
*******************************************************************************/
int mv_eth_tool_nway_reset(struct net_device *netdev)
{
	struct eth_port *priv = MV_ETH_PRIV(netdev);
	MV_U32	        phy_addr;

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

	phy_addr = mvBoardPhyAddrGet(priv->port);
	if (mvEthPhyRestartAN(phy_addr, MV_ETH_TOOL_AN_TIMEOUT) != MV_OK)
		return -EINVAL;

	return 0;
}
コード例 #7
0
/*******************************************************************************
* mvNetaMaxRxSizeSet -
*
* DESCRIPTION:
*       Change maximum receive size of the port. This configuration will take place
*       imidiately.
*
* INPUT:
*
* RETURN:
*******************************************************************************/
void mvEthMaxRxSizeSet(int port, int maxRxSize)
{
    MV_U32		regVal;

	if (!MV_PON_PORT(port)) {

		regVal =  MV_REG_READ(ETH_GMAC_CTRL_0_REG(port));
		regVal &= ~ETH_GMAC_MAX_RX_SIZE_MASK;
		regVal |= (((maxRxSize - MV_ETH_MH_SIZE) / 2) << ETH_GMAC_MAX_RX_SIZE_OFFS);
		mvPp2WrReg(ETH_GMAC_CTRL_0_REG(port), regVal);
/*
		mvOsPrintf("%s: port=%d, maxRxSize=%d, regAddr=0x%x, regVal=0x%x\n",
			__func__, port, maxRxSize, ETH_GMAC_CTRL_0_REG(port), regVal);
*/
	}
}
コード例 #8
0
/* Print MIB counters of the Ethernet port */
void mvEthMibCountersShow(int port)
{
	if (MV_PON_PORT(port)) {
		mvOsPrintf("%s: not supported for PON port\n", __func__);
		return;
	}

/*TODO: check port
	if (mvNetaTxpCheck(port))
		return;
*/
	mvOsPrintf("\nMIBs: port=%d\n", port);

	mvOsPrintf("\n[Rx]\n");
	mvEthMibPrint(port, ETH_MIB_GOOD_FRAMES_RECEIVED, "GOOD_FRAMES_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_BAD_FRAMES_RECEIVED, "BAD_FRAMES_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_BROADCAST_FRAMES_RECEIVED, "BROADCAST_FRAMES_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_MULTICAST_FRAMES_RECEIVED, "MULTICAST_FRAMES_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW, "GOOD_OCTETS_RECEIVED");
	mvOsPrintf("\n[Rx Errors]\n");
	mvEthMibPrint(port, ETH_MIB_BAD_OCTETS_RECEIVED, "BAD_OCTETS_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_UNDERSIZE_RECEIVED, "UNDERSIZE_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_FRAGMENTS_RECEIVED, "FRAGMENTS_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_OVERSIZE_RECEIVED, "OVERSIZE_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_JABBER_RECEIVED, "JABBER_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_MAC_RECEIVE_ERROR, "MAC_RECEIVE_ERROR");
	mvEthMibPrint(port, ETH_MIB_BAD_CRC_EVENT, "BAD_CRC_EVENT");
	mvOsPrintf("\n[Tx]\n");
	mvEthMibPrint(port, ETH_MIB_GOOD_FRAMES_SENT, "GOOD_FRAMES_SENT");
	mvEthMibPrint(port, ETH_MIB_BROADCAST_FRAMES_SENT, "BROADCAST_FRAMES_SENT");
	mvEthMibPrint(port, ETH_MIB_MULTICAST_FRAMES_SENT, "MULTICAST_FRAMES_SENT");
	mvEthMibPrint(port, ETH_MIB_GOOD_OCTETS_SENT_LOW, "GOOD_OCTETS_SENT");
	mvOsPrintf("\n[Tx Errors]\n");
	mvEthMibPrint(port, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, "INTERNAL_MAC_TRANSMIT_ERR");
	mvEthMibPrint(port, ETH_MIB_EXCESSIVE_COLLISION, "EXCESSIVE_COLLISION");
	mvEthMibPrint(port, ETH_MIB_COLLISION, "COLLISION");
	mvEthMibPrint(port, ETH_MIB_LATE_COLLISION, "LATE_COLLISION");
	mvOsPrintf("\n[FC control]\n");
	mvEthMibPrint(port, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, "UNREC_MAC_CONTROL_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_GOOD_FC_RECEIVED, "GOOD_FC_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_BAD_FC_RECEIVED, "BAD_FC_RECEIVED");
	mvEthMibPrint(port, ETH_MIB_FC_SENT, "FC_SENT");
	mvOsPrintf("\n");
}
コード例 #9
0
ファイル: mv_eth_tool.c プロジェクト: jameshilliard/prism
/******************************************************************************
* mv_eth_tool_get_link
* Description:
*	ethtool get link status
* INPUT:
*	netdev		Network device structure pointer
* OUTPUT
*	None
* RETURN:
*	0 if link is down, 1 if link is up
*
*******************************************************************************/
u32 mv_eth_tool_get_link(struct net_device *netdev)
{
	struct eth_port     *pp = MV_ETH_PRIV(netdev);
	struct eth_netdev   *dev_priv = MV_DEV_PRIV(netdev);

	if (pp == NULL) {
		printk(KERN_ERR "interface %s is not supported\n", netdev->name);
		return -EOPNOTSUPP;
	}

	if (isSwitch(pp)) {
		if (dev_priv == NULL)
			return -EOPNOTSUPP;
		return (dev_priv->link_map != 0);
	}
#ifdef CONFIG_MV_PON
	if (MV_PON_PORT(pp->port))
		return mv_pon_link_status();
#endif /* CONFIG_MV_PON */

	return mvNetaLinkIsUp(pp->port);
}
コード例 #10
0
ファイル: mv_eth_tool.c プロジェクト: jameshilliard/prism
/******************************************************************************
* 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;
}
コード例 #11
0
ファイル: mv_eth_tool.c プロジェクト: jameshilliard/prism
/******************************************************************************
* mv_eth_tool_get_regs
* Description:
*	ethtool get registers array
* INPUT:
*	netdev		Network device structure pointer
*	regs		registers information
* OUTPUT
*	p		registers array
* RETURN:
*	None
*
*******************************************************************************/
void mv_eth_tool_get_regs(struct net_device *netdev,
			  struct ethtool_regs *regs, void *p)
{
	struct eth_port	*priv = MV_ETH_PRIV(netdev);
	uint32_t 	*regs_buff = p;

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

	memset(p, 0, MV_ETH_TOOL_REGS_LEN * sizeof(uint32_t));

	regs->version = mvCtrlModelRevGet();

	/* ETH port registers */
	regs_buff[0]  = MV_REG_READ(ETH_PORT_STATUS_REG(priv->port));
	regs_buff[1]  = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(priv->port));
	regs_buff[2]  = MV_REG_READ(ETH_PORT_CONFIG_REG(priv->port));
	regs_buff[3]  = MV_REG_READ(ETH_PORT_CONFIG_EXTEND_REG(priv->port));
	regs_buff[4]  = MV_REG_READ(ETH_SDMA_CONFIG_REG(priv->port));
/*	regs_buff[5]  = MV_REG_READ(ETH_TX_FIFO_URGENT_THRESH_REG(priv->port)); */
	regs_buff[6]  = MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(priv->port));
	/* regs_buff[7]  = MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(priv->port)); */
	regs_buff[8]  = MV_REG_READ(ETH_INTR_CAUSE_REG(priv->port));
	regs_buff[9]  = MV_REG_READ(ETH_INTR_CAUSE_EXT_REG(priv->port));
	regs_buff[10] = MV_REG_READ(ETH_INTR_MASK_REG(priv->port));
	regs_buff[11] = MV_REG_READ(ETH_INTR_MASK_EXT_REG(priv->port));
	/* ETH Unit registers */
	regs_buff[16] = MV_REG_READ(ETH_PHY_ADDR_REG(priv->port));
	regs_buff[17] = MV_REG_READ(ETH_UNIT_INTR_CAUSE_REG(priv->port));
	regs_buff[18] = MV_REG_READ(ETH_UNIT_INTR_MASK_REG(priv->port));
	regs_buff[19] = MV_REG_READ(ETH_UNIT_ERROR_ADDR_REG(priv->port));
	regs_buff[20] = MV_REG_READ(ETH_UNIT_INT_ADDR_ERROR_REG(priv->port));

}