/******************************************************************************* * mvEthSpeedDuplexSet - * * DESCRIPTION: * Sets port speed to Auto Negotiation / 1000 / 100 / 10 Mbps. * Sets port duplex to Auto Negotiation / Full / Half Duplex. * * INPUT: * int portNo - port number * MV_ETH_PORT_SPEED speed - port speed * MV_ETH_PORT_DUPLEX duplex - port duplex mode * * RETURN: *******************************************************************************/ MV_STATUS mvEthSpeedDuplexSet(int portNo, MV_ETH_PORT_SPEED speed, MV_ETH_PORT_DUPLEX duplex) { MV_U32 regVal; /* Check validity */ if ((speed == MV_ETH_SPEED_1000) && (duplex == MV_ETH_DUPLEX_HALF)) return MV_BAD_PARAM; regVal = MV_REG_READ(ETH_GMAC_AN_CTRL_REG(portNo)); switch (speed) { case MV_ETH_SPEED_AN: regVal |= ETH_ENABLE_SPEED_AUTO_NEG_MASK; /* the other bits don't matter in this case */ break; case MV_ETH_SPEED_1000: regVal &= ~ETH_ENABLE_SPEED_AUTO_NEG_MASK; regVal |= ETH_SET_GMII_SPEED_1000_MASK; regVal &= ~ETH_SET_MII_SPEED_100_MASK; /* the 100/10 bit doesn't matter in this case */ break; case MV_ETH_SPEED_100: regVal &= ~ETH_ENABLE_SPEED_AUTO_NEG_MASK; regVal &= ~ETH_SET_GMII_SPEED_1000_MASK; regVal |= ETH_SET_MII_SPEED_100_MASK; break; case MV_ETH_SPEED_10: regVal &= ~ETH_ENABLE_SPEED_AUTO_NEG_MASK; regVal &= ~ETH_SET_GMII_SPEED_1000_MASK; regVal &= ~ETH_SET_MII_SPEED_100_MASK; break; default: mvOsPrintf("Unexpected Speed value %d\n", speed); return MV_BAD_PARAM; } switch (duplex) { case MV_ETH_DUPLEX_AN: regVal |= ETH_ENABLE_DUPLEX_AUTO_NEG_MASK; /* the other bits don't matter in this case */ break; case MV_ETH_DUPLEX_HALF: regVal &= ~ETH_ENABLE_DUPLEX_AUTO_NEG_MASK; regVal &= ~ETH_SET_FULL_DUPLEX_MASK; break; case MV_ETH_DUPLEX_FULL: regVal &= ~ETH_ENABLE_DUPLEX_AUTO_NEG_MASK; regVal |= ETH_SET_FULL_DUPLEX_MASK; break; default: mvOsPrintf("Unexpected Duplex value %d\n", duplex); return MV_BAD_PARAM; } mvPp2WrReg(ETH_GMAC_AN_CTRL_REG(portNo), regVal); return MV_OK; }
/******************************************************************************* * mvEthSpeedDuplexGet - * * DESCRIPTION: * Gets port speed * Gets port duplex * * INPUT: * int portNo - port number * OUTPUT: * MV_ETH_PORT_SPEED *speed - port speed * MV_ETH_PORT_DUPLEX *duplex - port duplex mode * * RETURN: *******************************************************************************/ MV_STATUS mvEthSpeedDuplexGet(int portNo, MV_ETH_PORT_SPEED *speed, MV_ETH_PORT_DUPLEX *duplex) { MV_U32 regVal; /* Check validity */ if (!speed || !duplex) return MV_BAD_PARAM; regVal = MV_REG_READ(ETH_GMAC_AN_CTRL_REG(portNo)); if (regVal & ETH_ENABLE_SPEED_AUTO_NEG_MASK) *speed = MV_ETH_SPEED_AN; else if (regVal & ETH_SET_GMII_SPEED_1000_MASK) *speed = MV_ETH_SPEED_1000; else if (regVal & ETH_SET_MII_SPEED_100_MASK) *speed = MV_ETH_SPEED_100; else *speed = MV_ETH_SPEED_10; if (regVal & ETH_ENABLE_DUPLEX_AUTO_NEG_MASK) *duplex = MV_ETH_DUPLEX_AN; else if (regVal & ETH_SET_FULL_DUPLEX_MASK) *duplex = MV_ETH_DUPLEX_FULL; else *duplex = MV_ETH_DUPLEX_HALF; return MV_OK; }
/******************************************************************************* * mvEthFlowCtrlSet - Set Flow Control of the port. * * DESCRIPTION: * This function configures the port's Flow Control properties. * * INPUT: * int port - Port number * MV_ETH_PORT_FC flowControl - Flow control of the port. * * RETURN: MV_STATUS * MV_OK - Success * MV_OUT_OF_RANGE - Failed. Port is out of valid range * MV_BAD_VALUE - Value flowControl parameters is not valid * *******************************************************************************/ MV_STATUS mvEthFlowCtrlSet(int port, MV_ETH_PORT_FC flowControl) { MV_U32 regVal; regVal = MV_REG_READ(ETH_GMAC_AN_CTRL_REG(port)); switch (flowControl) { case MV_ETH_FC_AN_NO: regVal |= ETH_ENABLE_FLOW_CONTROL_AUTO_NEG_MASK; regVal &= ~ETH_FLOW_CONTROL_ADVERTISE_MASK; regVal &= ~ETH_FLOW_CONTROL_ASYMETRIC_MASK; break; case MV_ETH_FC_AN_SYM: regVal |= ETH_ENABLE_FLOW_CONTROL_AUTO_NEG_MASK; regVal |= ETH_FLOW_CONTROL_ADVERTISE_MASK; regVal &= ~ETH_FLOW_CONTROL_ASYMETRIC_MASK; break; case MV_ETH_FC_AN_ASYM: regVal |= ETH_ENABLE_FLOW_CONTROL_AUTO_NEG_MASK; regVal |= ETH_FLOW_CONTROL_ADVERTISE_MASK; regVal |= ETH_FLOW_CONTROL_ASYMETRIC_MASK; break; case MV_ETH_FC_DISABLE: regVal &= ~ETH_ENABLE_FLOW_CONTROL_AUTO_NEG_MASK; regVal &= ~ETH_SET_FLOW_CONTROL_MASK; break; case MV_ETH_FC_ENABLE: regVal &= ~ETH_ENABLE_FLOW_CONTROL_AUTO_NEG_MASK; regVal |= ETH_SET_FLOW_CONTROL_MASK; break; default: mvOsPrintf("ethDrv: Unexpected FlowControl value %d\n", flowControl); return MV_BAD_VALUE; } mvPp2WrReg(ETH_GMAC_AN_CTRL_REG(port), regVal); return MV_OK; }
static void mvEthComplexPortInBandAnEnable(MV_U32 port, MV_BOOL enable) { MV_U32 reg; reg = MV_REG_READ(ETH_GMAC_AN_CTRL_REG(port)); /* Enable AnBandAnEn */ reg &= ~MV_ETH_IN_BAND_AN_EN_MASK; reg |= (0x1 << MV_ETH_IN_BAND_AN_EN_OFFSET); /* Disable AnDuplex, AnSpeedEn, AnFcEn */ if (enable == MV_FALSE) { reg &= ~MV_ETH_SPEED_AUTO_NEG_MASK; reg |= (0x0 << MV_ETH_SPEED_AUTO_NEG_OFFSET); reg &= ~MV_ETH_FLOW_CTRL_AUTO_NEG_MASK; reg |= (0x0 << MV_ETH_FLOW_CTRL_AUTO_NEG_OFFSET); reg &= ~MV_ETH_DUPLEX_AUTO_NEG_MASK; reg |= (0x0 << MV_ETH_DUPLEX_AUTO_NEG_OFFSET); } MV_REG_WRITE(ETH_GMAC_AN_CTRL_REG(port), reg); }
/******************************************************************************* * mvEthForceLinkModeSet - * * DESCRIPTION: * Sets "Force Link Pass" and "Do Not Force Link Fail" bits. * Note: This function should only be called when the port is disabled. * * INPUT: * int portNo - port number * MV_BOOL force_link_pass - Force Link Pass * MV_BOOL force_link_fail - Force Link Failure * 0, 0 - normal state: detect link via PHY and connector * 1, 1 - prohibited state. * * RETURN: *******************************************************************************/ MV_STATUS mvEthForceLinkModeSet(int portNo, MV_BOOL force_link_up, MV_BOOL force_link_down) { MV_U32 regVal; /* Can't force link pass and link fail at the same time */ if ((force_link_up) && (force_link_down)) return MV_BAD_PARAM; regVal = MV_REG_READ(ETH_GMAC_AN_CTRL_REG(portNo)); if (force_link_up) regVal |= ETH_FORCE_LINK_PASS_MASK; else regVal &= ~ETH_FORCE_LINK_PASS_MASK; if (force_link_down) regVal |= ETH_FORCE_LINK_FAIL_MASK; else regVal &= ~ETH_FORCE_LINK_FAIL_MASK; mvPp2WrReg(ETH_GMAC_AN_CTRL_REG(portNo), regVal); return MV_OK; }
/******************************************************************************* * mvEthFlowCtrlGet - Get Flow Control configuration of the port. * * DESCRIPTION: * This function returns the port's Flow Control properties. * * INPUT: * int port - Port number * * OUTPUT: * MV_ETH_PORT_FC *flowCntrl - Flow control of the port. * * RETURN: MV_STATUS * MV_OK - Success * MV_OUT_OF_RANGE - Failed. Port is out of valid range * *******************************************************************************/ MV_STATUS mvEthFlowCtrlGet(int port, MV_ETH_PORT_FC *pFlowCntrl) { MV_U32 regVal; regVal = MV_REG_READ(ETH_GMAC_AN_CTRL_REG(port)); if (regVal & ETH_ENABLE_FLOW_CONTROL_AUTO_NEG_MASK) { /* Auto negotiation is enabled */ if (regVal & ETH_FLOW_CONTROL_ADVERTISE_MASK) { if (regVal & ETH_FLOW_CONTROL_ASYMETRIC_MASK) *pFlowCntrl = MV_ETH_FC_AN_ASYM; else *pFlowCntrl = MV_ETH_FC_AN_SYM; } else *pFlowCntrl = MV_ETH_FC_AN_NO; } else { /* Auto negotiation is disabled */ if (regVal & ETH_SET_FLOW_CONTROL_MASK) *pFlowCntrl = MV_ETH_FC_ENABLE; else *pFlowCntrl = MV_ETH_FC_DISABLE; } return MV_OK; }