📄 ks8695end.c
字号:
* * Inputs: * pDrvCtrl pointer to END_DEVICE data structure. * bStart TRUE if start Rx machine, FALSE if stop it * * Returns: * NONE */void macStartRx(PEND_DEVICE pDrvCtrl, BOOLEAN bStart){ UINT32 uReg;#ifdef NO_RX /*RLQ,TEMP*/ return;#endif uReg = KS8695_READ_REG(REG_RXCTRL + DI.nOffset); if (bStart) { /* start RX machine */ uReg |= DMA_START; DI.bRxStarted = TRUE; } else { /* Stop RX machine */ uReg &= ~DMA_START; DI.bRxStarted = FALSE; } KS8695_WRITE_REG(REG_RXCTRL + DI.nOffset, uReg); /* if there descriptors available for rx, tick off Rx engine */ if (bStart) { if (DI.RxDescEmpty < DI.nRxDescTotal) { KS8695_WRITE_REG(REG_RXSTART + DI.nOffset, 1); } } else { /* clear corresponding ISR bits after stopped */ KS8695_WRITE_REG(REG_INT_STATUS, DI.uIntMask); CACHE_PIPE_FLUSH(); }}/* * macStartTx * This routine will start/stop TX machine. * * Inputs: * pDrvCtrl pionter to END_DEVICE data structure. * bStart TRUE if start Tx machine, FALSE if stop it * * Returns: * NONE */void macStartTx(PEND_DEVICE pDrvCtrl, BOOLEAN bStart){ UINT32 uReg; uReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset); if (bStart) { /* start TX machine */ uReg |= DMA_START; KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uReg); DI.bTxStarted = TRUE; } else { /* Stop TX machine */ uReg &= ~DMA_START; KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uReg); DI.bTxStarted = FALSE; CACHE_PIPE_FLUSH();#ifndef NO_TASK_DELAY taskDelay(2);#else delayEx(200000);#endif /* clear corresponding ISR bits after stopped */ /*KS8695_WRITE_REG(REG_INT_STATUS, DI.uIntMask);*/ }}/* * macStopAll * This function is use to stop both Tx/Rx. * * Argument(s) * pDrvCtrl pionter to END_DEVICE data structure. * * Return(s) * NONE */LOCAL void macStopAll(PEND_DEVICE pDrvCtrl){ /* stop Rx and Tx */ macStartRx(pDrvCtrl, FALSE); macStartTx(pDrvCtrl, FALSE); /* disable interrupt!!! */ macEnableInterrupt(pDrvCtrl, FALSE);}/* Interrupt Bit definitions */#define IB_WAN_LINK 31#define IB_WAN_RX_STOPPED 25#ifdef KS8695#define IB_HPNA_TX 23#define IB_HPNA_RX_STOPPED 18#endif#define IB_LAN_TX 17#define IB_LAN_RX_STOPPED 12#define IRQ_WAN_LEVEL 12#define IRQ_LAN_LEVEL 10#ifdef KS8695#define IRQ_HPNA_LEVEL 8#endif/* move to source file later */LOCAL INTCFG stDMAIntCfg[32] = { { 0, -1 }, /* -1 don't touch, it's not ours */ { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, /* bit 11 */ { 0, 0x0b }, /* bit 12, LAN */ { 0, 0x0b }, { 0, 0x0a }, { 0, 0x0a }, { 0, 0x0f }, { 0, 0x0f },#ifdef KS8695 { 0, IRQ_HPNA_LEVEL }, /* bit 18, HPNA */ { 0, IRQ_HPNA_LEVEL }, { 0, IRQ_HPNA_LEVEL }, { 0, IRQ_HPNA_LEVEL }, { 0, IRQ_HPNA_LEVEL }, { 0, IRQ_HPNA_LEVEL },#else { 0, -1 }, /* bit 18, KS8695P doesn't have HPNA port */ { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 }, { 0, -1 },#endif { 0, -1 }, /* bit 24 */ { 0, 0x0b }, /* bit 25, WAN */ { 0, 0x0b }, { 0, 0x0a }, { 0, 0x0a }, { 0, 0x0f }, { 0, 0x0f }, { 0, IRQ_WAN_LEVEL } /* WAN link */};/* * macConfigureInterrupt * This routine is used to configure interrupt priority * * Inputs: * pDrvCtrl pionter to END_DEVICE data structure. * * Returns: * NONE */void macConfigureInterrupt(PEND_DEVICE pDrvCtrl){ int i; UINT uIMR, uIPR = 0;#ifdef DEBUG_THIS /*printf("%s\n", __FUNCTION__);*/#endif /* use linkSem */ semTake(DI.linkSem, WAIT_FOREVER); uIMR = KS8695_READ_REG(REG_INT_CONTL); switch (DI.usDMAId) { case DMA_LAN: for (i = IB_LAN_RX_STOPPED; i <= IB_LAN_TX; i++) { if (stDMAIntCfg[i].bFIQ) { uIMR |= (1L << i); DI.bUseFIQ = TRUE; } else { uIMR &= ~(1L << i); uIPR |= ((UINT)(stDMAIntCfg[i].byPriority) & 0xf) << (i - IB_LAN_RX_STOPPED + 1) * 4; } } KS8695_WRITE_REG(REG_INT_LAN_PRIORITY, uIPR); break;#ifdef KS8695 case DMA_HPNA: for (i = IB_HPNA_RX_STOPPED; i <= IB_HPNA_TX; i++) { if (stDMAIntCfg[i].bFIQ) { uIMR |= (1L << i); DI.bUseFIQ = TRUE; } else { uIMR &= ~(1L << i); uIPR |= ((UINT)(stDMAIntCfg[i].byPriority) & 0xf) << (i - IB_HPNA_RX_STOPPED + 1) * 4; } } KS8695_WRITE_REG(KS8695_INT_HPNA_PRIORITY, uIPR); break;#endif case DMA_WAN: default: for (i = IB_WAN_RX_STOPPED; i <= IB_WAN_LINK; i++) { if (stDMAIntCfg[i].bFIQ) { uIMR |= (1L << i); DI.bUseFIQ = TRUE; } else { uIMR &= ~(1L << i); uIPR |= ((UINT)(stDMAIntCfg[i].byPriority) & 0xf) << (i - IB_WAN_RX_STOPPED + 1) * 4; } } KS8695_WRITE_REG(REG_INT_WAN_PRIORITY, uIPR); break; } KS8695_WRITE_REG(REG_INT_CONTL, uIMR); /* use linkSem */ semGive(DI.linkSem);}/* * macEnableInterrupt * This routine is used to enable/disable interrupt related to MAC only * * Inputs: * pDrvCtrl pionter to END_DEVICE data structure. * bEnable enable/disable interrupt * * Returns: * NONE */void macEnableInterrupt(PEND_DEVICE pDrvCtrl, BOOLEAN bEnable){ UINT uIER; semTake(DI.intSem, WAIT_FOREVER); uIER = KS8695_READ_REG(REG_INT_ENABLE); switch (DI.usDMAId) { case DMA_LAN:#ifdef KS8695 case DMA_HPNA:#endif if (bEnable) uIER |= DI.uIntMask; else uIER &= ~DI.uIntMask; break; case DMA_WAN: if (bEnable) uIER |= (DI.uIntMask | DI.uLinkIntMask); else uIER &= ~(DI.uIntMask | DI.uLinkIntMask); break; default: printf("unsupported option\n"); break; } KS8695_WRITE_REG(REG_INT_ENABLE, uIER); semGive(DI.intSem); /*ks8695_power_saving(bEnable);*/}/* * swSetMacAddress * This function is use to set switch engine Mac address. * * Argument(s) * pDrvCtrl pionter to END_DEVICE data structure. * pMac pointer to mac address buffer (should be at least 6 bytes) * * Return(s) * NONE */void swSetMacAddress(PEND_DEVICE pDrvCtrl, UCHAR *pMac){ UINT32 uLowAddress, uHighAddress;#ifdef DEBUG_THIS printf("%s\n", __FUNCTION__);#endif memcpy(&DI.stSwitchMac, pMac, MAC_ADDRESS_LEN); uLowAddress = (*(pMac + 5) | (*(pMac + 4) << 8) | (*(pMac + 3) << 16)| *(pMac + 3) << 24); uHighAddress = (*(pMac + 1) | *pMac << 8); KS8695_WRITE_REG(REG_SWITCH_MAC_LOW, uLowAddress); /* need 20 cpu clock delay for switch related registers */ SW_WRITE_DELAY(); KS8695_WRITE_REG(REG_SWITCH_MAC_HIGH, uHighAddress); /* need 20 cpu clock delay for switch related registers */ SW_WRITE_DELAY();}/* * swResetSNMPInfo * This function is use to get SNMP counters information * * Argument(s) * pDrvCtrl pionter to END_DEVICE data structure. * * Return(s) * NONE */void swResetSNMPInfo(PEND_DEVICE pDrvCtrl){ memset((void *)&pDrvCtrl->stats, 0, sizeof(pDrvCtrl->stats));}/* * swCreateLookUpTable * This function is use to create loopup table. * * Argument(s) * pDrvCtrl pionter to END_DEVICE data structure. * * Return(s) * NONE */void swCreateLookUpTable(PEND_DEVICE pDrvCtrl){ unsigned int mac = 0, index = 0, tmp = 0, portmap = 0;#ifdef DEBUG_THIS printf("%s\n", __FUNCTION__);#endif mac = 0x01020304; portmap = 0x10000;#ifdef KS8695 for (index=0; index<5; index++) { KS8695_WRITE_REG(KS8695_SWITCH_LUE_HIGH, 0x200000 + (portmap << index)); SW_WRITE_DELAY(); KS8695_WRITE_REG(KS8695_SWITCH_LUE_LOW, mac++); SW_WRITE_DELAY(); KS8695_WRITE_REG(KS8695_SWITCH_LUE_CTRL, index); SW_WRITE_DELAY(); do { tmp = KS8695_READ_REG(KS8695_SWITCH_LUE_CTRL) & 0x1000; } while (tmp); }#else index = index; /* no complain pls */ /* the user can program other MAC addresses for LOCAL table */ tmp = 0x0002; /* e.g. this is the MAC high and low addr for the notebook I am using for test */ mac = 0xa55d1590; KS8695_WRITE_REG(KS8695_SEIAC, KS8695_SEIAC_WRITE | KS8695_SEIAC_TAB_STATIC | (KS8695_SEIAC_INDEX_MASK & index)); SW_WRITE_DELAY(); KS8695_WRITE_REG(KS8695_SEIADH1, 0x200000 + (portmap << index) + tmp); SW_WRITE_DELAY(); KS8695_WRITE_REG(KS8695_SEIADL, mac); SW_WRITE_DELAY();#endif}/* * swConfigTagRemoval * This function is use to configure tag removal for ingress to given port. * * Argument(s) * pDrvCtrl pionter to END_DEVICE data structure. * uPort port for the tag to insert * bRemoval enable/disable removal * * Return(s) * NONE */void swConfigTagRemoval(PEND_DEVICE pDrvCtrl, UINT uPort, UINT bRemoval){ UINT32 uReg; uReg = KS8695_READ_REG(REG_SWITCH_ADVANCED); if (bRemoval) { uReg |= (1L << (22 + uPort)); } else { uReg &= ~(1L << (22 + uPort)); } KS8695_WRITE_REG(REG_SWITCH_ADVANCED, uReg); /* need 20 cpu clock delay for switch related registers */ SW_WRITE_DELAY();}/* * swConfigTagInsertion * This function is use to configure tag insertion for engress to given port. * * Argument(s) * pDrvCtrl pionter to END_DEVICE data structure. * uPort port for the tag to insert * bInsert enable/disable insertion * * Return(s) * NONE */void swConfigTagInsertion(PEND_DEVICE pDrvCtrl, UINT uPort, UINT bInsert){ UINT32 uReg; uReg = KS8695_READ_REG(REG_SWITCH_ADVANCED); if (bInsert) { uReg |= (1L << (17 + uPort)); } else { uReg &= ~(1L << (17 + uPort)); } KS8695_WRITE_REG(REG_SWITCH_ADVANCED, uReg); /* need 20 cpu clock delay for switch related registers */ SW_WRITE_DELAY();}/* * swEnableSwitch * This function is used to enable/disable switch * * Argument(s) * pDrvCtrl pointer to END_DEVICE struct * enable enable/disable switch * * Return(s) * NONE. */void swEnableSwitch(PEND_DEVICE pDrvCtrl, UINT enable){ UINT uReg; uReg = KS8695_READ_REG(REG_SWITCH_CTRL0); if (enable) { uReg |= SW_CTRL0_SWITCH_ENABLE; } else { uReg &= ~SW_CTRL0_SWITCH_ENABLE; } KS8695_WRITE_REG(REG_SWITCH_CTRL0, uReg); /* need 20 cpu clock delay for switch related registers */ SW_WRITE_DELAY();}/* * ks8695_ChipInit * This function is used to do chip initialization. * * Argument(s) * pDrvCtrl pointer to EN D_DEVICE structure. * bResetPhy flag indicates whether to reset PHY as well * * Return(s) * OK if success * ERROR otherwise */LOCAL STATUS ks8695_ChipInit(PEND_DEVICE pDrvCtrl, UINT8 bResetPhy){ UINT bStatus; UINT i;#ifdef DEBUG_THIS /*printf("%s\n", __FUNCTION__);*/#endif if (bResetPhy) { /* phy related initialization */ i = 0; swPhyReset(pDrvCtrl, i); swAutoNegoAdvertisement(pDrvCtrl, i); if (DMA_LAN == DI.usDMAId) { for (i = 1; i < SW_MAX_LAN_PORTS; i++) { swPhyReset(pDrvCtrl, i); swAutoNegoAd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -