📄 ks8695end.c
字号:
#endif /* disable IER if any */ uReg = KS8695_READ_REG(REG_INT_ENABLE); switch (DI.usDMAId) {#ifdef KS8695 case DMA_HPNA: uReg &= ~INT_HPNA_MASK; break;#endif case DMA_LAN: uReg &= ~INT_LAN_MASK; break; default: case DMA_WAN: uReg &= ~INT_WAN_MASK; break; } KS8695_WRITE_REG(REG_INT_ENABLE, uReg); /* reset corresponding register and wait for completion */ KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, DMA_SOFTRESET); do {#ifndef NO_TASK_DELAY taskDelay(1);#else delayEx(100000);#endif uReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset); if (!(uReg & DMA_SOFTRESET)) break; } while (--nTimeOut); if (nTimeOut < 1) { printf("%s: timeout error\n", __FUNCTION__); return ERROR; } /* clear statistic counters */ swResetSNMPInfo(pDrvCtrl); return OK;}/* * macConfigure * This function is used to set MAC control register based on configurable * option settings. * * Argument(s) * pDrvCtrl pointer to END_DEVICE structure. * * Return(s) * NONE */void macConfigure(PEND_DEVICE pDrvCtrl){ UINT uRxReg, uTxReg;#ifdef DEBUG_THIS /*printf("%s\n", __FUNCTION__);*/#endif /* read TX mode register */ uTxReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset); /* clear PBL bits first */ uTxReg &= ~DMA_PBLTMASK; /* 29:24 */ if (DI.byTxPBL) uTxReg |= ((UINT32)DI.byTxPBL << DMA_PBLTSHIFT); if (DI.bTxChecksum) { uTxReg |= (DMA_IPCHECKSUM | DMA_TCPCHECKSUM | DMA_UDPCHECKSUM); } else { uTxReg &= ~(DMA_IPCHECKSUM | DMA_TCPCHECKSUM | DMA_UDPCHECKSUM); } if (DI.bTxFlowCtrl) { uTxReg |= DMA_FLOWCTRL; } else { uTxReg &= ~DMA_FLOWCTRL; } uTxReg |= (DMA_PADDING | DMA_CRC); /* write TX mode register */ KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uTxReg); /* read RX mode register */ uRxReg = KS8695_READ_REG(REG_RXCTRL + DI.nOffset); /* clear PBL bits first */ uRxReg &= ~DMA_PBLTMASK; /* 29:24 */ if (DI.byRxPBL) uRxReg |= ((UINT32)DI.byRxPBL << DMA_PBLTSHIFT); /* checksum */ if (DI.bRxChecksum) { uRxReg |= (DMA_IPCHECKSUM | DMA_TCPCHECKSUM | DMA_UDPCHECKSUM); } else { uRxReg &= ~(DMA_IPCHECKSUM | DMA_TCPCHECKSUM | DMA_UDPCHECKSUM); } /* flow control */ if (DI.bRxFlowCtrl) { uRxReg |= DMA_FLOWCTRL; } else { uRxReg &= ~DMA_FLOWCTRL; } /* set unicast only, and let ks8695_set_multi function to set the rest */ uRxReg |= DMA_UNICAST; /* write RX mode register */ KS8695_WRITE_REG(REG_RXCTRL + DI.nOffset, uRxReg);#ifdef DEBUG_THIS /*printf("%s: uTx=0x%08x, uRx=0x%08x\n", __FUNCTION__, uTxReg, uRxReg);*/#endif}/* * macSetStationAddress * This function sets MAC address to given type (WAN, LAN or HPHA) * * Argument(s) * pDrvCtrl pointer to END_DEVICE struct * pMacAddress pointer to a byte array to hold MAC address (at least 6 bytes long) * * Return(s) * NONE. */void macSetStationAddress(PEND_DEVICE pDrvCtrl, uint8_t *pMacAddress){ UINT32 uLow, uHigh;#ifdef DEBUG_THIS /*printf("%s\n", __FUNCTION__);*/#endif uLow = ((UINT32)pMacAddress[2] << 24); uLow += ((UINT32)pMacAddress[3] << 16); uLow += ((UINT32)pMacAddress[4] << 8); uLow += pMacAddress[5]; uHigh = ((UINT32)pMacAddress[0] << 8) + pMacAddress[1]; KS8695_WRITE_REG(REG_STATION_LOW + DI.nOffset, uLow); KS8695_WRITE_REG(REG_STATION_HIGH + DI.nOffset, uHigh);}/* * swConfigurePort * This function is used to configure a give port for LAN. * * Argument(s) * pDrvCtrl pointer to END_DEVICE struct * uPort port to start * * Return(s) * NONE. */void swConfigurePort(PEND_DEVICE pDrvCtrl, UINT uPort){ UINT uReg, uOff; BOOLEAN bPort5 = FALSE; if (uPort >= SW_MAX_LAN_PORTS) { if (SW_MAX_LAN_PORTS == uPort) { /* port 5 */ bPort5 = TRUE; } else { /* out of range */ printf("%s: port %d to configure out of range\n", __FUNCTION__, uPort); return; } }#ifdef KS8695 uOff = KS8695_SWITCH_PORT1 + uPort * 4;#else if (bPort5) uOff = KS8695_SEP5C1; else uOff = KS8695_SEP1C1 + uPort * 0x0c;#endif uReg = 0; uReg |= (UINT)DPI[uPort].usTag << 16; if (!bPort5) { /* connection media type */ /*uReg &= ~(SW_PORT_DISABLE_AUTONEG | SW_PORT_100BASE | SW_PORT_FULLDUPLEX);*/ if (SW_PHY_AUTO != DI.usCType[uPort]) { uReg |= SW_PORT_DISABLE_AUTONEG; if (SW_PHY_100BASE_TX == DI.usCType[uPort] || SW_PHY_100BASE_TX_FD == DI.usCType[uPort]) { uReg |= SW_PORT_100BASE; } if (SW_PHY_10BASE_T_FD == DI.usCType[uPort] || SW_PHY_100BASE_TX_FD == DI.usCType[uPort]) { uReg |= SW_PORT_FULLDUPLEX; } } } else { /* Rx direct mode */ if (DI.bRxDirectMode) { uReg |= SW_PORT_RX_DIRECT_MODE; } /* Tx Pre-tag mode */ if (DI.bTxRreTagMode) { uReg |= SW_PORT_TX_PRETAG_MODE; } } /* cross talk bit mask */ uReg |= ((UINT)(DPI[uPort].byCrossTalkMask & 0x1f)) << 8; /* spanning tree */ if (SW_SPANNINGTREE_ALL == DPI[uPort].bySpanningTree) { uReg |= SW_PORT_TX_SPANNINGTREE | SW_PORT_RX_SPANNINGTREE; } else { if (SW_SPANNINGTREE_TX == DPI[uPort].bySpanningTree) { uReg |= SW_PORT_TX_SPANNINGTREE; } if (SW_SPANNINGTREE_RX == DPI[uPort].bySpanningTree) { uReg |= SW_PORT_RX_SPANNINGTREE; } } if (DPI[uPort].byDisableSpanningTreeLearn) { uReg |= SW_PORT_NO_SPANNINGTREE; } /* ingress broadcast storm protection */ if (DPI[uPort].byStormProtection) { uReg |= SW_PORT_STORM_PROCTION; } /* ingress priority */ if (DPI[uPort].byIngressPriority) { uReg |= SW_PORT_HI_PRIORITY; } if (DPI[uPort].byIngressPriorityTOS) { uReg |= SW_PORT_TOS_ENABLE; } if (DPI[uPort].byIngressPriority802_1P) { uReg |= SW_PORT_8021Q_ENABLE; } /* egress priority */ if (DPI[uPort].byEgressPriority) { uReg |= SW_PORT_PRIOTIRY_ENABLE; } KS8695_WRITE_REG(uOff, uReg); /* need 20 cpu clock delay for switch related registers */ SW_WRITE_DELAY();#ifdef DEBUG_THIS printf("%s: uOff=0x%08x, reg=0x%08x\n", __FUNCTION__, uOff, uReg);#endif}/* * swReadSNMPReg * This function is used to read SNMP registers * * Argument(s) * pDrvCtrl pointer to END_DEVICE structure. * uIndex index of SNMP register to read * * Return(s) * value read */LOCAL UINT32 swReadSNMPReg(PEND_DEVICE pDrvCtrl, UINT uIndex){#ifdef KS8695 UINT uValue, uTimeout = 0; if (uIndex >= 512) uIndex = 511; KS8695_WRITE_REG(KS8695_MANAGE_COUNTER, uIndex); SW_WRITE_DELAY(); do { uValue = KS8695_READ_REG(KS8695_MANAGE_DATA); if (uValue & SW_SNMP_DATA_VALID) { if (uValue & SW_SNMP_DATA_OVERFLOW) { KS8695_WRITE_REG(KS8695_MANAGE_DATA, SW_SNMP_DATA_OVERFLOW); } /* clear status bits */ uValue &= 0x3fffffff; return uValue; } SW_WRITE_DELAY(); } while (uTimeout++ < 1000); if (uValue & SW_SNMP_DATA_OVERFLOW) { KS8695_WRITE_REG(KS8695_MANAGE_DATA, SW_SNMP_DATA_OVERFLOW); }#else UINT32 reg, value, timeout = 0; reg = KS8695_SEIAC_READ | KS8695_SEIAC_TAB_MIB | (KS8695_SEIAC_INDEX_MASK & uIndex); do { KS8695_WRITE_REG(KS8695_SEIAC, reg); SW_WRITE_DELAY(); value = KS8695_READ_REG(KS8695_SEIADL); if (value & SW_SNMP_DATA_VALID) { if (value & SW_SNMP_DATA_OVERFLOW) { reg = KS8695_SEIAC_WRITE | KS8695_SEIAC_TAB_MIB | (KS8695_SEIAC_INDEX_MASK & uIndex); KS8695_WRITE_REG(KS8695_SEIAC, reg); SW_WRITE_DELAY(); } /* clear status bits */ value &= 0x3fffffff; return value; } } while (timeout++ < 1000);#endif printf("%s: timeout\n", __FUNCTION__); return 0;}/* * swConfigure * This function is used to config switch engine. It is assume that * the BIST is performed already (by boot loader). * * Argument(s) * pDrvCtrl pointer to END_DEVICE structure. * * Return(s) * NONE */void swConfigure(PEND_DEVICE pDrvCtrl){ UINT uReg, i;#ifdef DEBUG_THIS printf("%s\n", __FUNCTION__);#endif if (DMA_LAN == DI.usDMAId) { /* read switch control 0 register */ uReg = KS8695_READ_REG(REG_SWITCH_CTRL0); /* flow control for LAN ports */ if (DI.bPort5FlowCtrl) { /* flow control for port 5 */ uReg |= SW_CTRL0_ENABLE_PORT5; } else { uReg &= ~SW_CTRL0_ENABLE_PORT5; }#ifdef KS8695 if (DI.bPortsFlowCtrl) { /* four flow control for each LAN port */ uReg |= SW_CTRL0_ENABLE_PORTS; } else { uReg &= ~SW_CTRL0_ENABLE_PORTS; }#else#if 0 /* RLQ, need to verify */ for (i = 0; i < SW_MAX_LAN_PORTS; i++) { forceFlowControl(pDrvCtrl, i, DI.bPortsFlowCtrl); //if (!DI.bPortsFlowCtrl) // backPressureEnable(pDrvCtrl, i, DI.bPortsFlowCtrl); backPressureEnable(pDrvCtrl, i, TRUE); }#endif#endif /*RLQ, 11/20/2002, requested by Hock, backpressure will fix packet * drop problem in half duplex mode */ uReg |= 0x00000020; /* bit 5 */ /* set flow control fairness mode based on LAN flow control settings, should use */ /* read switch control 0 register */ KS8695_WRITE_REG(REG_SWITCH_CTRL0, uReg); /* need 20 cpu clock delay for switch related registers */ SW_WRITE_DELAY(); /* configure LAN port 1-4 and Port 5 */ for (i = 0; i <= SW_MAX_LAN_PORTS; i++) swConfigurePort(pDrvCtrl, i); } else { printf("%s: type (%x) not supported\n", __FUNCTION__, DI.usDMAId); }}/* * macConfigureFlow * This function is used to set mac flow control as a workaround for WAN port. * option settings. * * Argument(s) * pDrvCtrl pointer to END_DEVICE structure. * bFlowCtrl flow control to set * * Return(s) * NONE */void macConfigureFlow(PEND_DEVICE pDrvCtrl, uint8_t bFlowCtrl){ UINT uRxReg, uTxReg; BOOLEAN bTxStarted, bRxStarted;#ifdef DEBUG_THIS printf("%s: flowctrl = %d\n", __FUNCTION__, bFlowCtrl);#endif /* need to stop mac engines if started */ bTxStarted = DI.bTxStarted; bRxStarted = DI.bRxStarted; if (bRxStarted) macStartRx(pDrvCtrl, FALSE); if (bTxStarted) macStartTx(pDrvCtrl, FALSE); /* read TX mode register */ uTxReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset); if (bFlowCtrl) { uTxReg |= DMA_FLOWCTRL; } else { uTxReg &= ~DMA_FLOWCTRL; } /* write TX mode register */ KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uTxReg); /* read RX mode register */ uRxReg = KS8695_READ_REG(REG_RXCTRL + DI.nOffset); if (bFlowCtrl) { uRxReg |= DMA_FLOWCTRL; } else { uRxReg &= ~DMA_FLOWCTRL; } /* write RX mode register */ KS8695_WRITE_REG(REG_RXCTRL + DI.nOffset, uRxReg); if (bRxStarted) macStartRx(pDrvCtrl, TRUE); if (bTxStarted) macStartTx(pDrvCtrl, TRUE);}/* * macSetLoopback * This function is used to set MAC lookback mode (for debugging purpose) * * Argument(s) * pDrvCtrl pointer to END_DEVICE structure. * * Return(s) * NONE */void macSetLoopback(PEND_DEVICE pDrvCtrl, BOOLEAN bLoopback){ UINT uTxReg; BOOLEAN bTxStarted, bRxStarted; bTxStarted = DI.bTxStarted; bRxStarted = DI.bRxStarted; if (bRxStarted) macStartRx(pDrvCtrl, FALSE); if (bTxStarted) macStartTx(pDrvCtrl, FALSE); /* read TX mode register */ uTxReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset); if (bLoopback) { uTxReg |= DMA_LOOPBACK; } else { uTxReg &= ~DMA_LOOPBACK; } /* write TX mode register */ KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uTxReg); if (bRxStarted) macStartRx(pDrvCtrl, TRUE); if (bTxStarted) macStartTx(pDrvCtrl, TRUE);}/* * macStartRx * This routine will start/stop RX machine.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -