⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ks8695end.c

📁 这是micrel公司宽带路由ARM9芯片的VXWORKS BSP 源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *  Returns:
 *      NONE
 */
void macStartRx(PEND_DEVICE pDrvCtrl, BOOLEAN bStart)
{
	UINT32 uReg;

	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;
		DRV_LOG(DRV_DEBUG_RX, "macStartRx, stopped\n", 1, 2, 3, 4, 5, 6);
	}
	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;

    DRV_LOG(DRV_DEBUG_LOAD, "macConfigureInterrupt\n", 1, 2, 3, 4, 5, 6);

	/* 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(REG_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:
		    DRV_LOG(DRV_DEBUG_ERROR, "macEnableInterrupt: unsupported option\n", 1, 2, 3, 4, 5, 6);
			break;
	}
	KS8695_WRITE_REG(REG_INT_ENABLE, uIER);

	semGive(DI.intSem);
#ifdef	USE_POWER_SAVING
	ks8695_power_saving(bEnable);
#endif
}

/*
 * 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;

    DRV_LOG(DRV_DEBUG_LOAD, "swSetMacAddress\n", 1, 2, 3, 4, 5, 6);

	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;

    DRV_LOG(DRV_DEBUG_LOAD, "swCreateLookUpTable\n", 1, 2, 3, 4, 5, 6);

	mac = 0x01020304;
	portmap = 0x10000;

#if defined(KS8695) || defined(KS8695X)
	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;

    DRV_LOG(DRV_DEBUG_LOAD, "ks8695_ChipInit\n", 1, 2, 3, 4, 5, 6);

	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);
				swAutoNeg

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -