MV_STATUS mvPp2PlcrHwTxqThreshSet(int txq, int idx) { mvPp2WrReg(MV_PP2_PLCR_EDROP_TXQ_REG, txq); mvPp2WrReg(MV_PP2_PLCR_EDROP_TXQ_TR_REG, idx); return MV_OK; }
MV_STATUS mvPp2PlcrHwBucketSizeSet(int plcr, int commit, int excess) { MV_U32 regVal; mvPp2WrReg(MV_PP2_PLCR_TABLE_INDEX_REG, plcr); regVal = MV_PP2_PLCR_EXCESS_SIZE_MASK(excess) | MV_PP2_PLCR_COMMIT_SIZE_MASK(commit); mvPp2WrReg(MV_PP2_PLCR_BUCKET_SIZE_REG, regVal); return MV_OK; }
MV_STATUS mvPp2PlcrHwTokenValue(int plcr, int value) { MV_U32 regVal; mvPp2WrReg(MV_PP2_PLCR_TABLE_INDEX_REG, plcr); regVal = mvPp2RdReg(MV_PP2_PLCR_TOKEN_CFG_REG); regVal &= ~MV_PP2_PLCR_TOKEN_VALUE_ALL_MASK; regVal |= MV_PP2_PLCR_TOKEN_VALUE_MASK(value); mvPp2WrReg(MV_PP2_PLCR_TOKEN_CFG_REG, regVal); return MV_OK; }
MV_STATUS mvPp2PlcrHwColorModeSet(int plcr, int enable) { MV_U32 regVal; mvPp2WrReg(MV_PP2_PLCR_TABLE_INDEX_REG, plcr); regVal = mvPp2RdReg(MV_PP2_PLCR_TOKEN_CFG_REG); if (enable) regVal |= MV_PP2_PLCR_COLOR_MODE_MASK; else regVal &= ~MV_PP2_PLCR_COLOR_MODE_MASK; mvPp2WrReg(MV_PP2_PLCR_TOKEN_CFG_REG, regVal); return MV_OK; }
static void mvPp2PlcrHwDump(int plcr) { int units, type, tokens; MV_U32 regVal; mvPp2WrReg(MV_PP2_PLCR_TABLE_INDEX_REG, plcr); mvOsPrintf("%3d: ", plcr); regVal = mvPp2RdReg(MV_PP2_PLCR_ENABLE_REG); mvOsPrintf("%4s", MV_BIT_CHECK(regVal, plcr) ? "Yes" : "No"); regVal = mvPp2RdReg(MV_PP2_PLCR_BASE_PERIOD_REG); mvOsPrintf(" %6d", regVal & MV_PP2_PLCR_BASE_PERIOD_ALL_MASK); regVal = mvPp2RdReg(MV_PP2_PLCR_TOKEN_CFG_REG); units = regVal & MV_PP2_PLCR_TOKEN_UNIT_MASK; type = (regVal & MV_PP2_PLCR_TOKEN_TYPE_ALL_MASK) >> MV_PP2_PLCR_TOKEN_TYPE_OFFS; tokens = (regVal & MV_PP2_PLCR_TOKEN_VALUE_ALL_MASK) >> MV_PP2_PLCR_TOKEN_VALUE_OFFS; mvOsPrintf(" %5s %2d %5d", units ? "pkts" : "bytes", type, tokens); regVal = mvPp2RdReg(MV_PP2_PLCR_BUCKET_SIZE_REG); mvOsPrintf(" %04x %04x", (regVal & MV_PP2_PLCR_COMMIT_SIZE_ALL_MASK) >> MV_PP2_PLCR_COMMIT_SIZE_OFFS, (regVal & MV_PP2_PLCR_EXCESS_SIZE_ALL_MASK) >> MV_PP2_PLCR_EXCESS_SIZE_OFFS); regVal = mvPp2RdReg(MV_PP2_PLCR_COMMIT_TOKENS_REG); mvOsPrintf(" %08x", regVal); regVal = mvPp2RdReg(MV_PP2_PLCR_EXCESS_TOKENS_REG); mvOsPrintf(" %08x", regVal); mvOsPrintf("\n"); }
/******************************************************************************* * mvPp2WinInit * * DESCRIPTION: * This function initialize ETH window decode unit. It set the default * address decode windows of the unit. * * INPUT: * addWinMap: An array holding the address decoding information for the * system. * * OUTPUT: * None. * * RETURN: * MV_ERROR if setting fail. *******************************************************************************/ MV_STATUS mvPp2WinInit(MV_U32 dummy/*backward compability*/, MV_UNIT_WIN_INFO *addrWinMap) { MV_U32 winNum, winPrioIndex = 0, regVal = 0; MV_UNIT_WIN_INFO *addrDecWin; /* Initiate Ethernet address decode */ /* First disable all address decode windows */ for (winNum = 0; winNum < ETH_MAX_DECODE_WIN; winNum++) regVal |= MV_BIT_MASK(winNum); mvPp2WrReg(ETH_BASE_ADDR_ENABLE_REG, regVal); /* Go through all windows in user table until table terminator */ for (winNum = 0; ((ethAddrDecPrioTab[winPrioIndex] != TBL_TERM) && (winNum < ETH_MAX_DECODE_WIN));) { addrDecWin = &addrWinMap[ethAddrDecPrioTab[winPrioIndex]]; if (addrDecWin->enable == MV_TRUE) { if (MV_OK != mvPp2WinWrite(0, winNum, addrDecWin)) { mvOsPrintf("mvPp2WinInit failed: winNum=%d (%d, %d)\n", winNum, winPrioIndex, ethAddrDecPrioTab[winPrioIndex]); return MV_ERROR; } winNum++; } winPrioIndex++; } return MV_OK; }
/*********************************************************** * mv_eth_bm_init -- * * initialize BM pool to bu used by all ports * ***********************************************************/ static int mv_eth_bm_init(MV_VOID) { MV_STATUS status; unsigned char *pool_addr, *pool_addr_phys; mvBmInit(); pool_addr = mvOsIoUncachedMalloc(NULL, (sizeof(MV_U32) * EGIGA_BM_SIZE) + MV_BM_POOL_PTR_ALIGN, (MV_ULONG *)&pool_addr_phys, NULL); if (!pool_addr) { printf("Can't alloc %d bytes for pool #%d\n", sizeof(MV_U32) * EGIGA_BM_SIZE, EGIGA_BM_POOL); return -1; } if (MV_IS_NOT_ALIGN((MV_ULONG)pool_addr_phys, MV_BM_POOL_PTR_ALIGN)) pool_addr_phys = (unsigned char *)MV_ALIGN_UP((MV_ULONG)pool_addr_phys, MV_BM_POOL_PTR_ALIGN); status = mvBmPoolInit(EGIGA_BM_POOL, (MV_U32 *)pool_addr, (MV_ULONG)pool_addr_phys, EGIGA_BM_SIZE); if (status != MV_OK) { printf("Can't init #%d BM pool. status=%d\n", EGIGA_BM_POOL, status); return -1; } #ifdef CONFIG_MV_ETH_PP2_1 /* Disable BM priority */ mvPp2WrReg(MV_BM_PRIO_CTRL_REG, 0); #endif mvBmPoolControl(EGIGA_BM_POOL, MV_START); mvPp2BmPoolBufSizeSet(EGIGA_BM_POOL, RX_BUFFER_SIZE); return 0; }
void mvPp2WolRegs(void) { int i, reg; mvOsPrintf("\n[WoL registers]\n"); mvPp2PrintReg(MV_PP2_WOL_MODE_REG, "MV_PP2_WOL_MODE_REG"); mvPp2PrintReg(MV_PP2_WOL_MAC_HIGH_REG, "MV_PP2_WOL_MAC_HIGH_REG"); mvPp2PrintReg(MV_PP2_WOL_MAC_LOW_REG, "MV_PP2_WOL_MAC_LOW_REG"); mvPp2PrintReg(MV_PP2_WOL_ARP_IP0_REG, "MV_PP2_WOL_ARP_IP0_REG"); mvPp2PrintReg(MV_PP2_WOL_ARP_IP1_REG, "MV_PP2_WOL_ARP_IP1_REG"); mvPp2PrintReg(MV_PP2_WOL_WAKEUP_EN_REG, "MV_PP2_WOL_WAKEUP_EN_REG"); mvPp2PrintReg(MV_PP2_WOL_INTR_CAUSE_REG, "MV_PP2_WOL_INTR_CAUSE_REG"); mvPp2PrintReg(MV_PP2_WOL_INTR_MASK_REG, "MV_PP2_WOL_INTR_MASK_REG"); mvPp2PrintReg(MV_PP2_WOL_PTRN_SIZE_REG, "MV_PP2_WOL_PTRN_SIZE_REG"); for (i = 0; i < MV_PP2_WOL_PTRN_NUM; i++) { mvOsPrintf("\nWoL Wakeup Frame pattern #%d\n", i); mvPp2WrReg(MV_PP2_WOL_PTRN_IDX_REG, i); for (reg = 0; reg < MV_PP2_WOL_PTRN_REGS; reg++) { mvPp2RegPrintNonZero2(MV_PP2_WOL_PTRN_DATA_REG(reg), "MV_PP2_WOL_PTRN_DATA_REG", reg); mvPp2RegPrintNonZero2(MV_PP2_WOL_PTRN_MASK_REG(reg), "MV_PP2_WOL_PTRN_MASK_REG", reg); } } }
void mvEthPortDisable(int port) { MV_U32 regVal; regVal = MV_REG_READ(ETH_GMAC_CTRL_0_REG(port)); regVal &= ~(ETH_GMAC_PORT_EN_MASK); mvPp2WrReg(ETH_GMAC_CTRL_0_REG(port), regVal); }
/******************************************************************************* * 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; }
MV_STATUS mvPp2WolSleep(int port) { MV_U32 regVal; if (mvPp2PortCheck(port)) return MV_BAD_PARAM; /* Clear cause register and unmask enabled WoL events */ mvPp2WrReg(MV_PP2_WOL_INTR_CAUSE_REG, 0); regVal = mvPp2RdReg(MV_PP2_WOL_WAKEUP_EN_REG); mvPp2WrReg(MV_PP2_WOL_INTR_MASK_REG, regVal); regVal = mvPp2RdReg(MV_PP2_WOL_MODE_REG); if (regVal & MV_PP2_WOL_IS_SLEEP_MASK) { mvOsPrintf("WoL is already activated on port #%d\n", (regVal >> MV_PP2_WOL_SLEEP_PORT_OFFS) & MV_PP2_WOL_SLEEP_PORT_MAX); return MV_BUSY; }
MV_STATUS mvPp2PlcrHwTokenConfig(int plcr, int unit, int type) { MV_U32 regVal; mvPp2WrReg(MV_PP2_PLCR_TABLE_INDEX_REG, plcr); regVal = mvPp2RdReg(MV_PP2_PLCR_TOKEN_CFG_REG); if (unit) regVal |= MV_PP2_PLCR_TOKEN_UNIT_MASK; else regVal &= ~MV_PP2_PLCR_TOKEN_UNIT_MASK; regVal &= ~MV_PP2_PLCR_TOKEN_TYPE_ALL_MASK; regVal |= MV_PP2_PLCR_TOKEN_TYPE_MASK(type); mvPp2WrReg(MV_PP2_PLCR_TOKEN_CFG_REG, regVal); return MV_OK; }
void mvPp2PlcrHwRegs(void) { int i; MV_U32 regVal; mvOsPrintf("\n[PLCR registers: %d policers]\n", MV_PP2_PLCR_NUM); mvEthRegPrint(MV_PP2_PLCR_ENABLE_REG, "MV_PP2_PLCR_ENABLE_REG"); mvEthRegPrint(MV_PP2_PLCR_BASE_PERIOD_REG, "MV_PP2_PLCR_BASE_PERIOD_REG"); mvEthRegPrint(MV_PP2_PLCR_MIN_PKT_LEN_REG, "MV_PP2_PLCR_MIN_PKT_LEN_REG"); mvEthRegPrint(MV_PP2_PLCR_EDROP_EN_REG, "MV_PP2_PLCR_EDROP_EN_REG"); for (i = 0; i < MV_PP2_PLCR_NUM; i++) { mvOsPrintf("\n[Policer %d registers]\n", i); mvPp2WrReg(MV_PP2_PLCR_TABLE_INDEX_REG, i); mvEthRegPrint(MV_PP2_PLCR_COMMIT_TOKENS_REG, "MV_PP2_PLCR_COMMIT_TOKENS_REG"); mvEthRegPrint(MV_PP2_PLCR_EXCESS_TOKENS_REG, "MV_PP2_PLCR_EXCESS_TOKENS_REG"); mvEthRegPrint(MV_PP2_PLCR_BUCKET_SIZE_REG, "MV_PP2_PLCR_BUCKET_SIZE_REG"); mvEthRegPrint(MV_PP2_PLCR_TOKEN_CFG_REG, "MV_PP2_PLCR_TOKEN_CFG_REG"); } mvOsPrintf("\nEarly Drop Thresholds for SW and HW forwarding\n"); for (i = 0; i < MV_PP2_PLCR_EDROP_THRESH_NUM; i += 2) { mvEthRegPrint2(MV_PP2_PLCR_EDROP_CPU_TR_REG(i), "MV_PP2_PLCR_EDROP_CPU_TR_REG", i); mvEthRegPrint2(MV_PP2_PLCR_EDROP_HWF_TR_REG(i), "MV_PP2_PLCR_EDROP_HWF_TR_REG", i); } mvOsPrintf("\nPer RXQ: Non zero early drop thresholds\n"); for (i = 0; i < MV_ETH_RXQ_TOTAL_NUM; i++) { mvPp2WrReg(MV_PP2_PLCR_EDROP_RXQ_REG, i); regVal = mvPp2RdReg(MV_PP2_PLCR_EDROP_RXQ_TR_REG); if (regVal != 0) mvOsPrintf(" %-32s: 0x%x = 0x%08x\n", "MV_PP2_PLCR_EDROP_RXQ_TR_REG", MV_PP2_PLCR_EDROP_RXQ_TR_REG, regVal); } mvOsPrintf("\nPer TXQ: Non zero Early Drop Thresholds\n"); for (i = 0; i < MV_PP2_TXQ_TOTAL_NUM; i++) { mvPp2WrReg(MV_PP2_PLCR_EDROP_TXQ_REG, i); regVal = mvPp2RdReg(MV_PP2_PLCR_EDROP_TXQ_TR_REG); if (regVal != 0) mvOsPrintf(" %-32s: 0x%x = 0x%08x\n", "MV_PP2_PLCR_EDROP_TXQ_TR_REG", MV_PP2_PLCR_EDROP_TXQ_TR_REG, regVal); } }
MV_STATUS mvPp2PlcrHwBasePeriodSet(int period) { MV_U32 regVal; regVal = mvPp2RdReg(MV_PP2_PLCR_BASE_PERIOD_REG); regVal &= ~MV_PP2_PLCR_BASE_PERIOD_ALL_MASK; regVal |= MV_PP2_PLCR_BASE_PERIOD_MASK(period); mvPp2WrReg(MV_PP2_PLCR_BASE_PERIOD_REG, regVal); return MV_OK; }
MV_STATUS mvPp2PlcrHwMinPktLen(int bytes) { MV_U32 regVal; regVal = mvPp2RdReg(MV_PP2_PLCR_MIN_PKT_LEN_REG); regVal &= ~MV_PP2_PLCR_MIN_PKT_LEN_ALL_MASK; regVal |= MV_PP2_PLCR_MIN_PKT_LEN_MASK(bytes); mvPp2WrReg(MV_PP2_PLCR_MIN_PKT_LEN_REG, regVal); return MV_OK; }
MV_STATUS mvPp2PlcrHwHwfThreshSet(int idx, int threshold) { MV_U32 regVal; regVal = mvPp2RdReg(MV_PP2_PLCR_EDROP_HWF_TR_REG(idx)); regVal &= ~MV_PP2_PLCR_EDROP_TR_ALL_MASK(idx); regVal |= MV_PP2_PLCR_EDROP_TR_MASK(idx, threshold); mvPp2WrReg(MV_PP2_PLCR_EDROP_HWF_TR_REG(idx), regVal); return MV_OK; }
static void mvEthPortSgmiiSet(int port, int enable) { MV_U32 regVal; regVal = MV_REG_READ(ETH_GMAC_CTRL_2_REG(port)); if (enable) regVal |= ETH_GMAC_PCS_ENABLE_MASK; else regVal &= ~ETH_GMAC_PCS_ENABLE_MASK; mvPp2WrReg(ETH_GMAC_CTRL_2_REG(port), regVal); }
void mvEthPhyAddrSet(int port, int phyAddr) { unsigned int regData; regData = MV_REG_READ(ETH_PHY_ADDR_REG); regData &= ~ETH_PHY_ADDR_MASK(port); regData |= (phyAddr << ETH_PHY_ADDR_OFFS(port)); mvPp2WrReg(ETH_PHY_ADDR_REG, regData); return; }
MV_STATUS mvPp2PlcrHwBaseRateGenEnable(int enable) { MV_U32 regVal; regVal = mvPp2RdReg(MV_PP2_PLCR_BASE_PERIOD_REG); if (enable) regVal |= MV_PP2_PLCR_ADD_TOKENS_EN_MASK; else regVal &= ~MV_PP2_PLCR_ADD_TOKENS_EN_MASK; mvPp2WrReg(MV_PP2_PLCR_BASE_PERIOD_REG, regVal); return MV_OK; }
MV_STATUS mvPp2PlcrHwEnable(int plcr, int enable) { MV_U32 regVal; regVal = mvPp2RdReg(MV_PP2_PLCR_ENABLE_REG); if (enable) regVal |= MV_PP2_PLCR_EN_MASK(plcr); else regVal &= ~MV_PP2_PLCR_EN_MASK(plcr); mvPp2WrReg(MV_PP2_PLCR_ENABLE_REG, regVal); return MV_OK; }
void mvEthPortPowerUp(int port, MV_BOOL isSgmii, MV_BOOL isRgmii) { MV_U32 regVal; mvEthPortSgmiiSet(port, isSgmii); mvEthPortRgmiiSet(port, isRgmii); /* Cancel Port Reset */ regVal = MV_REG_READ(ETH_GMAC_CTRL_2_REG(port)); regVal &= (~ETH_GMAC_PORT_RESET_MASK); mvPp2WrReg(ETH_GMAC_CTRL_2_REG(port), regVal); while ((MV_REG_READ(ETH_GMAC_CTRL_2_REG(port)) & ETH_GMAC_PORT_RESET_MASK) != 0) continue; }
MV_STATUS mvPp2PlcrHwEarlyDropSet(int enable) { MV_U32 regVal; regVal = mvPp2RdReg(MV_PP2_PLCR_EDROP_EN_REG); if (enable) regVal |= MV_PP2_PLCR_EDROP_EN_MASK; else regVal &= ~MV_PP2_PLCR_EDROP_EN_MASK; mvPp2WrReg(MV_PP2_PLCR_EDROP_EN_REG, regVal); return MV_OK; }
/******************************************************************************* * 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); */ } }
void mvEthPortLbSet(int port, int isGmii, int isPcsEn) { MV_U32 regVal; regVal = MV_REG_READ(ETH_GMAC_CTRL_1_REG(port)); if (isGmii) regVal |= ETH_GMAC_GMII_LB_EN_MASK; else regVal &= ~ETH_GMAC_GMII_LB_EN_MASK; if (isPcsEn) regVal |= ETH_GMAC_PCS_LB_EN_MASK; else regVal &= ~ETH_GMAC_PCS_LB_EN_MASK; mvPp2WrReg(ETH_GMAC_CTRL_1_REG(port), regVal); }
/******************************************************************************* * 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; }
/******************************************************************************* * 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; }
/******************************************************************************* * mvPp2WinWrite * * DESCRIPTION: * This function writes the address decoding registers according to the * given window configuration. * * INPUT: * unit - The Ethernet unit number to configure. * winNum - ETH target address decode window number. * pAddrDecWin - ETH target window data structure. * * OUTPUT: * None. * * RETURN: * MV_OK on success, * MV_BAD_PARAM if winNum is invalid. * MV_ERROR otherwise. * *******************************************************************************/ MV_STATUS mvPp2WinWrite(MV_U32 dummy/*backward compability*/, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin) { MV_U32 size, alignment; MV_U32 baseReg, sizeReg; /* Parameter checking */ if (winNum >= ETH_MAX_DECODE_WIN) { mvOsPrintf("mvPp2WinSet: ERR. Invalid win num %d\n", winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if (MV_TRUE == ethWinOverlapDetect(winNum, &pAddrDecWin->addrWin)) { mvOsPrintf("mvPp2WinWrite: ERR. Window %d overlap\n", winNum); return MV_ERROR; } /* check if address is aligned to the size */ if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size)) { mvOsPrintf("mvPp2WinSet: Error setting Ethernet window %d.\n" "Address 0x%08x is unaligned to size 0x%x.\n", winNum, pAddrDecWin->addrWin.baseLow, (MV_U32)pAddrDecWin->addrWin.size); return MV_ERROR; } size = pAddrDecWin->addrWin.size; if (!MV_IS_POWER_OF_2(size)) { mvOsPrintf("mvPp2WinWrite: Error setting AUDIO window %d. " "Window size is not a power to 2.", winNum); return MV_BAD_PARAM; } baseReg = (pAddrDecWin->addrWin.baseLow & ETH_WIN_BASE_MASK); sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(winNum)); /* set size */ alignment = 1 << ETH_WIN_SIZE_OFFS; sizeReg &= ~ETH_WIN_SIZE_MASK; sizeReg |= (((size / alignment) - 1) << ETH_WIN_SIZE_OFFS); /* set attributes */ baseReg &= ~ETH_WIN_ATTR_MASK; baseReg |= pAddrDecWin->attrib << ETH_WIN_ATTR_OFFS; /* set target ID */ baseReg &= ~ETH_WIN_TARGET_MASK; baseReg |= pAddrDecWin->targetId << ETH_WIN_TARGET_OFFS; /* for the safe side we disable the window before writing the new values */ mvPp2WinEnable(0, winNum, MV_FALSE); mvPp2WrReg(ETH_WIN_BASE_REG(winNum), baseReg); /* Write to address decode Size Register */ mvPp2WrReg(ETH_WIN_SIZE_REG(winNum), sizeReg); /* Enable address decode target window */ if (pAddrDecWin->enable == MV_TRUE) mvPp2WinEnable(0, winNum, MV_TRUE); return MV_OK; }