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

📄 ks8695end.c

📁 kedin bsp for vxWorks
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef	DEBUG_THIS	printf("%s: RxBufLen=%d, original len=%d\n", __FUNCTION__, DI.uRxBufferLen, (ETHERMTU + ENET_HEADER_SIZE + 2));#endif	/* please update link status within watchdog routine */	DI.bLinkChanged[0] = TRUE;	if (DMA_LAN == DI.usDMAId) {	/* if LAN driver, 3 more ports */		DI.bLinkChanged[1] = TRUE;		DI.bLinkChanged[2] = TRUE;		DI.bLinkChanged[3] = TRUE;	}	return OK;}/* * SetDefaults *	This function is used to set initial defaults before Parse routine. * * Argument(s) *	pDrvCtrl		pointer to END_DEVICE structure. * * Return(s) *	NONE. */LOCAL void SetDefaults(PEND_DEVICE pDrvCtrl){#ifdef	DEBUG_THIS	/*printf("%s\n", __FUNCTION__);*/#endif	/* Transmit Descriptor Count */	DI.nTxDescTotal = TXDESC_DEFAULT;		/* 128 | 32 | 32(d) */	/* Receive Descriptor Count */	DI.nRxDescTotal = RXDESC_DEFAULT;		/* 128 | 32 | 32(d) */	/* Transmit Checksum Offload Enable configuration */	DI.bTxChecksum = TXCHECKSUM_DEFAULT;	/* enabled */	/* Receive Checksum Offload Enable */	DI.bRxChecksum = RXCHECKSUM_DEFAULT;	/* enabled */	/* Flow Control */	DI.bRxFlowCtrl = FLOWCONTROL_DEFAULT;	/* enabled */	/* currently Tx control flow shares the setting of Rx control flow */	DI.bTxFlowCtrl = DI.bRxFlowCtrl;	/* Programmable Burst Length */	DI.byTxPBL = PBL_DEFAULT;				/* Tx PBL size */	DI.byRxPBL = PBL_DEFAULT;				/* Rx PBL size */	/* Perform PHY PowerDown Reset instead of soft reset, the Option function can 	   be overwritten by user later */	DI.bPowerDownReset = TRUE;#ifdef PACKET_DUMP	/* for debug only */	DI.uDebugDumpTxPkt = 0xff;	DI.uDebugDumpRxPkt = 0xff;#endif	pDrvCtrl->nWatchdogDelay = sysClkRateGet() * 5;		/* every 5 secs */}/* * CheckConfigurations *	This function checks all command line paramters for valid user *  input. If an invalid value is given, or if no user specified *  value exists, a default value is used. * * Argument(s) *	pDrvCtrl		pointer to END_DEVICE structure. * * Return(s) *	NONE. */LOCAL void CheckConfigurations(PEND_DEVICE pDrvCtrl){	int i;#ifdef	DEBUG_THIS	/*printf("%s: (unit=%d)\n", __FUNCTION__, pDrvCtrl->unit);*/#endif	/* Tx coalescing, currently can only be used if buffer unavailable bit is set */	DI.nTransmitCoalescing = (DI.nTxDescTotal >> 3);	/* User speed and/or duplex options */	DI.usCType[0] = SW_PHY_DEFAULT;	if (DMA_LAN == DI.usDMAId) {		/*TEMP, currently assume all other ports share same configuration with		  first one, will add more options for LAN ports later */		for (i = 1; i < SW_MAX_LAN_PORTS; i++) {			DI.usCType[i] = DI.usCType[0];		}		/* initialize some variables which do not have user configurable options */		for (i = 0; i <= SW_MAX_LAN_PORTS; i++) {			DPI[i].byCrossTalkMask = 0x1f;			DPI[i].bySpanningTree = SW_SPANNINGTREE_ALL;			DPI[i].byDisableSpanningTreeLearn = FALSE;		}		/* set default as direct mode for port 5, so no lookup table is checking */		DI.bRxDirectMode = FALSE;		DI.bTxRreTagMode = FALSE;		DI.bPort5FlowCtrl = DI.bRxFlowCtrl;		DI.bPortsFlowCtrl = DI.bRxFlowCtrl;	}}/* * gpioConfigure *	This function is use to configure GPIO pins required for extra LEDs *	as speed indicators. * * Argument(s) *  pDrvCtrl		pionter to END_DEVICE data structure. * * Return(s) *	NONE */void gpioConfigure(PEND_DEVICE pDrvCtrl){	UINT32	uReg;	uReg = KS8695_READ_REG(REG_GPIO_MODE);	switch (DI.usDMAId) {#ifdef	KS8695	case DMA_HPNA:		return;#endif	case DMA_LAN:		uReg |= 0xf0;	/* GPIO 4-7 for port 1 - 4, configure them as output */		break;	default:	case DMA_WAN:		uReg |= 0x08;	/* GPIO 3 for WAN port */		break;	}	KS8695_WRITE_REG(REG_GPIO_MODE, uReg);}/* * gpioSet *	This function is use to set/reset given GPIO pin corresponding to the port. * * Argument(s) *  pDrvCtrl	pionter to END_DEVICE data structure. *  uPort		port for the tag to insert *  bSet		enable/disable LED * * Return(s) *  NONE */void gpioSet(PEND_DEVICE pDrvCtrl, UINT uPort, UINT bSet){	UINT32	uReg;#ifdef	DEBUG_THIS	/*printf("%s: port %d, %s\n", __FUNCTION__, uPort, bSet ? "100" : "10");*/#endif	uReg = KS8695_READ_REG(REG_GPIO_DATA);	switch (DI.usDMAId) {#ifdef	KS8695	case DMA_HPNA:		return;#endif	case DMA_LAN:		if (bSet)			uReg &= ~(1 << (uPort + 4));	/* low for LED on */		else			uReg |= (1 << (uPort + 4));	/* high for LED off */		break;	default:	case DMA_WAN:		if (bSet)			uReg &= ~0x08;	/* low for LED on */		else			uReg |= 0x08;	/* high for LED off */		break;	}	KS8695_WRITE_REG(REG_GPIO_DATA, uReg);}/* * swGetPhyStatus *	This function is used to get the status of auto negotiation. * * Argument(s) *	pDrvCtrl	pointer to END_DEVICE structure. *  uPort		port to query * * Return(s) *	TRUE	if connected *	FALSE	otherwise */int swGetPhyStatus(PEND_DEVICE pDrvCtrl, UINT uPort){	UINT	uReg, uOff, uShift = 0;    DRV_LOG(DRV_DEBUG_LOG_PHY, "swGetPhyStatus\n", 1, 2, 3, 4, 5, 6);	switch (DI.usDMAId) {#ifdef	KS8695	case DMA_HPNA:		/* temp */		uReg = KS8695_READ_REG(REG_MISC_CONTROL);		DI.usLinkSpeed[uPort] = (uReg & 0x00000002) ? SPEED_100 : SPEED_10;		DI.bHalfDuplex[uPort] = (uReg & 0x00000001) ? FULL_DUPLEX : HALF_DUPLEX;		/* note that there is no register bit corresponding to HPNA's link status		   therefore don't report it */		DI.bLinkActive[uPort] = TRUE;		return TRUE;#endif	case DMA_WAN:		uOff = REG_WAN_CONTROL;		uShift = 16;		break;	default:	case DMA_LAN:		switch (uPort) {		case SW_PORT_4:			uOff = REG_SWITCH_AUTO1;			break;			break;		case SW_PORT_3:			uOff = REG_SWITCH_AUTO1;			break;			uShift = 16;			break;		case SW_PORT_2:			uOff = REG_SWITCH_AUTO0;			break;		case SW_PORT_1:		default:			uOff = REG_SWITCH_AUTO0;			uShift = 16;			break;		}	}	uReg = KS8695_READ_REG(uOff);	/* if not linked yet */	if (!(uReg & ((UINT)SW_AUTONEGO_STAT_LINK << uShift))) {		DI.bLinkActive[uPort] = FALSE;		DI.usLinkSpeed[uPort] = SPEED_UNKNOWN;		DI.bHalfDuplex[uPort] = 0;		gpioSet(pDrvCtrl, uPort, FALSE);		return FALSE;	}	DI.bLinkActive[uPort] = TRUE;	if (SW_PHY_AUTO == DI.usCType[uPort]) {		/* if auto nego complete */		if ((UINT)SW_AUTONEGO_COMPLETE << uShift) {			/* clear auto nego restart bit */			uReg &= ~((UINT)SW_AUTONEGO_RESTART << uShift);			KS8695_WRITE_REG(uOff, uReg);			SW_WRITE_DELAY();			DI.usLinkSpeed[uPort] = (uReg & ((UINT)SW_AUTONEGO_STAT_SPEED << uShift)) ? SPEED_100 : SPEED_10;			DI.bHalfDuplex[uPort] = (uReg & ((UINT)SW_AUTONEGO_STAT_DUPLEX << uShift)) ? FULL_DUPLEX : HALF_DUPLEX;			DI.bAutoNegoInProgress[uPort] = FALSE;						gpioSet(pDrvCtrl, uPort, SPEED_100 == DI.usLinkSpeed[uPort]);			/*RLQ, need to verify real duplex mode instead report it correct here */			/* duplex bit may not right if partner doesn't support all mode, do further detection */			if ((uReg & (SW_AUTONEGO_PART_100FD | SW_AUTONEGO_PART_100HD | SW_AUTONEGO_PART_10FD | SW_AUTONEGO_PART_10HD) << uShift)				!= (SW_AUTONEGO_PART_100FD | SW_AUTONEGO_PART_100HD | SW_AUTONEGO_PART_10FD | SW_AUTONEGO_PART_10HD)) {				if (SPEED_100 == DI.usLinkSpeed[uPort]) {					if ((uReg & (SW_AUTONEGO_PART_100FD << uShift))) {						DI.bHalfDuplexDetected[uPort] = FULL_DUPLEX;#ifndef	KS8695						forceFlowControl(pDrvCtrl, uPort, TRUE);						backPressureEnable(pDrvCtrl, uPort, FALSE);#endif					} else {						DI.bHalfDuplexDetected[uPort] = HALF_DUPLEX;#ifndef	KS8695						forceFlowControl(pDrvCtrl, uPort, FALSE);						backPressureEnable(pDrvCtrl, uPort, TRUE);#endif					}				}				else {					if ((uReg & (SW_AUTONEGO_PART_10FD << uShift))) {						DI.bHalfDuplexDetected[uPort] = FULL_DUPLEX;#ifndef	KS8695						forceFlowControl(pDrvCtrl, uPort, TRUE);						backPressureEnable(pDrvCtrl, uPort, FALSE);#endif					}					else {						DI.bHalfDuplexDetected[uPort] = HALF_DUPLEX;#ifndef	KS8695						forceFlowControl(pDrvCtrl, uPort, FALSE);						backPressureEnable(pDrvCtrl, uPort, TRUE);#endif					}				}			}			/* software workaround for flow control, need to know partner's flow control */			if (DMA_WAN == DI.usDMAId) {	/* currently do it to WAN only, there is no problem to LAN, will do HPNA later */				uint8_t	bFlowCtrl;				/* we need to check partner's control flow setting for the matching, if not, changes ours */				bFlowCtrl = ((SW_AUTONEGO_PART_PAUSE << uShift) & uReg) ? TRUE : FALSE;				if (bFlowCtrl != DI.bRxFlowCtrl) {	/* Tx same as Rx, so test Rx should be enough */					/* need to change ours accordingly, which will overwrite current one */					macConfigureFlow(pDrvCtrl, bFlowCtrl);				}			}#ifdef	DEBUG_THIS			printf("%s> Auto Nego completed\n", __FUNCTION__);#endif		}		else {#ifdef	DEBUG_THIS			/* auto nego in progress */			printf("%s> Auto Nego in progress...\n", __FUNCTION__);#endif			/* wait for next timer */			DI.bLinkActive[uPort] = FALSE;			DI.usLinkSpeed[uPort] = SPEED_UNKNOWN;			DI.bHalfDuplex[uPort] = 0;		}	}	else {#ifdef	DEBUG_THIS		printf("%s: media type=%d, port=%d\n", __FUNCTION__, DI.usCType[uPort], uPort);#endif		/* manually connection */		if (SW_PHY_10BASE_T_FD == DI.usCType[uPort] || SW_PHY_100BASE_TX_FD == DI.usCType[uPort]) {			DI.bHalfDuplex[uPort] = FULL_DUPLEX;#ifndef	KS8695			forceFlowControl(pDrvCtrl, uPort, TRUE);			backPressureEnable(pDrvCtrl, uPort, FALSE);#endif		}		else {			DI.bHalfDuplex[uPort] = HALF_DUPLEX;#ifndef	KS8695			forceFlowControl(pDrvCtrl, uPort, FALSE);			backPressureEnable(pDrvCtrl, uPort, TRUE);#endif		}		if (SW_PHY_100BASE_TX_FD == DI.usCType[uPort] || SW_PHY_100BASE_TX == DI.usCType[uPort]) {			DI.usLinkSpeed[uPort] = SPEED_100;			gpioSet(pDrvCtrl, uPort, TRUE);		}		else {			DI.usLinkSpeed[uPort] = SPEED_10;			gpioSet(pDrvCtrl, uPort, FALSE);		}		/* software workaround for flow control, need to know partner's flow control */		if (DMA_WAN == DI.usDMAId) {	/* currently do it to WAN only, there is no problem to LAN, will do HPNA later */			macConfigureFlow(pDrvCtrl, FULL_DUPLEX == DI.bHalfDuplex[uPort] ? TRUE : FALSE);		}	}	return TRUE;}/* * swDetectPhyConnection *	This function is used to start auto negotiation * * Argument(s) *  pDrvCtrl	pointer to END_DEVICE struct *  uPort		port to start * * Return(s) *	NONE. */LOCAL void swDetectPhyConnection(PEND_DEVICE pDrvCtrl, UINT uPort){	if (LINK_SELECTION_FORCED != DI.byDisableAutoNego[uPort] && !DI.bAutoNegoInProgress[uPort] && DI.bLinkChanged[uPort]) {		swAutoNegoStart(pDrvCtrl, uPort);		DI.bLinkChanged[uPort] = FALSE;		DI.bLinkActive[uPort] = FALSE;	}	swGetPhyStatus(pDrvCtrl, uPort);}/* * swPhyReset *	This function is used to reset phy chipset (powerdown or soft reset). * * Argument(s) *	pDrvCtrl	pointer to END_DEVICE structure. *  uPort		port to start * * Return(s) *	NONE */void swPhyReset(PEND_DEVICE pDrvCtrl, UINT uPort){	UINT	uReg, uShift = 0;	UINT	uPowerReg;	UINT	uReg1;#ifdef	DEBUG_THIS    /*printf("%s\n", __FUNCTION__);*/#endif	/* IEEE spec. of auto nego bit */	uReg1 = BIT(7);	switch (DI.usDMAId) {#ifdef	KS8695	case DMA_HPNA:		return;#endif	case DMA_WAN:		uPowerReg = REG_WAN_POWERMAGR;		break;	default:	case DMA_LAN:		switch (uPort) {		case SW_PORT_4:			uPowerReg = REG_LAN34_POWERMAGR;			break;		case SW_PORT_3:			uPowerReg = REG_LAN34_POWERMAGR;			uShift = 16;			break;		case SW_PORT_2:			uPowerReg = REG_LAN12_POWERMAGR;			break;		case SW_PORT_1:		default:			uPowerReg = REG_LAN12_POWERMAGR;			uShift = 16;			break;		}	}#ifdef	DEBUG_THIS    /*printf("%s: reg=0x%04x, shift=%d, val=0x%08x\n", __FUNCTION__, uPowerReg, uShift, KS8695_READ_REG(uPowerReg));*/#endif	if (DI.bPowerDownReset) {		uReg = KS8695_READ_REG(uPowerReg);		KS8695_WRITE_REG(uPowerReg, uReg | ((UINT)POWER_POWERDOWN << uShift));#ifndef	NO_TASK_DELAY		taskDelay(8);#else		delayEx(800000);#endif		uReg &= ~((UINT)POWER_POWERDOWN << uShift);		/* turn off IEEE auto nego */		uReg &= ~(uReg1 << uShift);		KS8695_WRITE_REG(uPowerReg, uReg);		/* need 20 cpu clock delay for switch related registers */		SW_WRITE_DELAY();	}	else {		uReg = KS8695_READ_REG(uPowerReg);		/* turn off IEEE auto nego */		uReg &= ~(uReg1 << uShift);		KS8695_WRITE_REG(uPowerReg, uReg);		/* need 20 cpu clock delay for switch related registers */		SW_WRITE_DELAY();	}}/* * macReset *	This function will execute a soft reset the chipset. * * Argument(s) *	pDrvCtrl		pointer to END_DEVICE structure. * * Return(s) *	OK		if success *	ERROR	otherwise */int macReset(PEND_DEVICE pDrvCtrl){	int nTimeOut = 200;	UINT32 uReg;#ifdef	DEBUG_THIS	/*printf("%s\n", __FUNCTION__);*/

⌨️ 快捷键说明

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