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

📄 smsc911x.c

📁 smsc911x.c smsc911x driver based vxworks network com 9700 stb cware dirver
💻 C
📖 第 1 页 / 共 5 页
字号:
 */

/* Ethernet ISR link */
static isrLink_t sysEndIsrLink =
{
    (void*)smsc911xInt,    /* rtn */
    0,                  /* arg */
    NULL                /* next */
};

/* register access routine */

void Lan_SetRegDW( DWORD dwBase, DWORD dwOffset, DWORD dwVal)
{
	DWORD tmpvalue ;
	tmpvalue = ((dwVal & 0xFF000000)>>24) | ((dwVal & 0xFF0000)>>8) | ((dwVal & 0xFF00)<<8) | ((dwVal & 0xFF)<<24 ) ; 
	(*(DWORD *)(dwBase + dwOffset)) = tmpvalue;
}

DWORD Lan_GetRegDW(DWORD dwBase, DWORD dwOffset)
{
	DWORD tmpvalue ;
	tmpvalue = (DWORD)(*(DWORD *)(dwBase + dwOffset));
	tmpvalue = ((tmpvalue& 0xFF000000)>>24) | ((tmpvalue& 0xFF0000)>>8) |((tmpvalue& 0xFF00)<<8) | ((tmpvalue& 0xFF)<<24 ) ; 
	return tmpvalue;
}

VOID     Lan_ClrBitsDW(DWORD dwBase, DWORD dwOffset ,DWORD dwBits) 
{
	DWORD dwData ;
	dwData = Lan_GetRegDW( dwBase, dwOffset) ;
	dwData &= ~dwBits ;
	Lan_SetRegDW( dwBase, dwOffset, dwData ) ;
}

VOID     Lan_SetBitsDW(DWORD dwBase, DWORD dwOffset,  DWORD dwBits) 
{
	DWORD dwData ;
	dwData = Lan_GetRegDW( dwBase, dwOffset) ;
	dwData |= dwBits ;
	Lan_SetRegDW( dwBase, dwOffset, dwData ) ;
}

BOOLEAN MacNotBusy(DWORD dwBase)
{
	int i=0;

	/* Assuming MacPhyAccessLock has already been acquired */

	/* wait for MAC not busy, w/ timeout */
	for(i=0;i<40;i++)
	{
		if((Lan_GetRegDW(dwBase,MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY_)==(0UL)) {
			return TRUE;
		}
	}
	SMSC_WARNING("timeout waiting for MAC not BUSY. MAC_CSR_CMD = 0x%08lX",
		Lan_GetRegDW(dwBase, MAC_CSR_CMD));
	return FALSE;
}

DWORD Mac_GetRegDW(DWORD dwBase,DWORD dwRegOffset)
{
	DWORD result=0xFFFFFFFFUL;
	DWORD dwTemp=0;
	SMSC_ASSERT(dwBase!=0);
	
	/*Assuming MacPhyAccessLock has already been acquired */

	/* wait until not busy */
	if (Lan_GetRegDW(dwBase,MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY_)
	{
		SMSC_WARNING("Mac_GetRegDW() failed, MAC already busy at entry");
		goto DONE;
	}

	/* send the MAC Cmd w/ offset */
	Lan_SetRegDW(dwBase, MAC_CSR_CMD,
		((dwRegOffset & 0x000000FFUL) | MAC_CSR_CMD_CSR_BUSY_ | MAC_CSR_CMD_R_NOT_W_));

	dwTemp=Lan_GetRegDW(dwBase,BYTE_TEST); /* to flush previous write */
	dwTemp=dwTemp;

	/* wait for the read to happen, w/ timeout */
	if (!MacNotBusy(dwBase))
	{
		SMSC_WARNING("Mac_GetRegDW() failed, waiting for MAC not busy after read\r\n");
		goto DONE;
	} else {
		/* finally, return the read data */
		result=Lan_GetRegDW(dwBase,MAC_CSR_DATA);
	}
DONE:
	return result;
}

/*Sets a Mac register */
void Mac_SetRegDW(DWORD dwBase , DWORD dwRegOffset, DWORD dwVal)
{
	DWORD dwTemp=0;
	
	SMSC_ASSERT(dwBase!=0);
	
	/*Assuming MacPhyAccessLock has already been acquired */

	if (Lan_GetRegDW(dwBase, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY_)
	{
		SMSC_WARNING("Mac_SetRegDW() failed, MAC already busy at entry\r\n");
		goto DONE;
	}

	/* send the data to write */
	Lan_SetRegDW(dwBase,MAC_CSR_DATA,dwVal);

	/* do the actual write */
	Lan_SetRegDW(dwBase , MAC_CSR_CMD,((dwRegOffset & 0x000000FFUL) | MAC_CSR_CMD_CSR_BUSY_));
	dwTemp=Lan_GetRegDW(dwBase,BYTE_TEST); /*force flush of previous write*/
	dwTemp=dwTemp;

	/* wait for the write to complete, w/ timeout */
	if (!MacNotBusy(dwBase))
	{
		SMSC_WARNING("Mac_SetRegDW() failed, waiting for MAC not busy after write");
	}
DONE:
	return;
}

WORD Phy_GetRegW( PPRIVATE_DATA privateData, DWORD dwRegIndex)
{
	DWORD dwAddr=0;
	int i=0;
	WORD result=0xFFFFU;
	DWORD dwBase ;

	SMSC_ASSERT(privateData!= NULL);

	dwBase = privateData->dwLanBase ;

	/* confirm MII not busy */
	if ((Mac_GetRegDW(dwBase, MII_ACC) & MII_ACC_MII_BUSY_) != 0UL)
	{
		SMSC_WARNING("MII is busy in Phy_GetRegW???\r\n");
		result=0;
		goto DONE;
	}

	/* set the address, index & direction (read from PHY) */
	dwAddr = (((privateData->dwPhyAddress) & 0x1FUL)<<11) | ((dwRegIndex & 0x1FUL)<<6);
	Mac_SetRegDW(dwBase, MII_ACC, dwAddr);

	/* wait for read to complete w/ timeout */
 	for(i=0;i<100;i++) {
		/* see if MII is finished yet */
		if ((Mac_GetRegDW(dwBase, MII_ACC) & MII_ACC_MII_BUSY_) == 0UL)
		{
			/* get the read data from the MAC & return i */
			result=((WORD)Mac_GetRegDW(dwBase, MII_DATA));
			goto DONE;
		}
	}
	SMSC_WARNING("timeout waiting for MII write to finish\r\n");

DONE:
	return result;
}

/*Sets a phy register */
void Phy_SetRegW( PPRIVATE_DATA privateData, DWORD dwRegIndex,WORD wVal)
{
	DWORD dwAddr=0;
	DWORD dwBase ; 
	int i=0;

	SMSC_ASSERT(privateData!=NULL);

	dwBase = privateData->dwLanBase ;

	/* confirm MII not busy */
	if ((Mac_GetRegDW(dwBase, MII_ACC) & MII_ACC_MII_BUSY_) != 0UL)
	{
		SMSC_WARNING("MII is busy in Phy_SetRegW???\r\n");
		goto DONE;
	}

	/* put the data to write in the MAC */
	Mac_SetRegDW(dwBase, MII_DATA, (DWORD)wVal);

	/* set the address, index & direction (write to PHY) */
	dwAddr = (((privateData->dwPhyAddress) & 0x1FUL)<<11) | ((dwRegIndex & 0x1FUL)<<6) | MII_ACC_MII_WRITE_;
	Mac_SetRegDW(dwBase, MII_ACC, dwAddr);

	/* wait for write to complete w/ timeout */
	for(i=0;i<100;i++) {
		/* see if MII is finished yet */
		if ((Mac_GetRegDW(dwBase, MII_ACC) & MII_ACC_MII_BUSY_) == 0UL)
		{
			goto DONE;
		}
	}
	SMSC_WARNING("timeout waiting for MII write to finish\r\n");
DONE:
	return;
}


/******************************************************************************
*
* lan91C111Load - initialize the driver and device
*
* This routine initializes the driver and the device to the operational state.
* All of the device-specific parameters are passed in <initString>, which
* expects a string of the following format:
*
* This routine can be called in two modes. If it is called with an empty but
* allocated string, it places the name of this device (that is, "ln") into
* the <initString> and returns 0.
*
* If the string is allocated and not empty, the routine attempts to load
* the driver using the values specified in the string.
*
* RETURNS: An END object pointer, or NULL on error, or 0 and the name of the
* device if the <initString> was NULL.
*/

END_OBJ* smsc911xLoad
(
		char* initString,		/* string to be parse by the driver */
		void* args
)
{
	SMSC911XEND_DEVICE		*pDrvCtrl;
	PPRIVATE_DATA privateData ;
	DWORD dwIntCfg ;	
	DWORD dwHigh16=0;
	DWORD dwLow32=0;
	DWORD dwBase ;


	SMSC_TRACE("+smsc911xLoad\r\n");
	

	if (initString == NULL)
	{
		SMSC_TRACE( "initString is NULL\r\n-smsc911xLoad\r\n") ;
		return (NULL);
	}

	if (initString[0] == NULL)
	{
		bcopy((char *)SMSC911X_DEV_NAME, initString, SMSC911X_DEV_NAME_LEN);
		SMSC_TRACE( "initString[0] is NULL\r\n-smsc911xLoad\r\n") ;
		return (0);
	}

	/* allocate the device structure */
	pDrvCtrl = (SMSC911XEND_DEVICE *)calloc (sizeof (SMSC911XEND_DEVICE), 1);

	if (pDrvCtrl == NULL)
		goto errorExit;

	/* parse the init string, filling in the device structure */

	if (smsc911xInitParse (pDrvCtrl, initString) == ERROR)
		goto errorExit;

	/* identify the chip */
	if ( smsc911xIdentify(pDrvCtrl) == ERROR )
	{
			goto errorExit;
	}
		/* init the memory */
	if (smsc911xMemInit (pDrvCtrl) == ERROR) {
		SMSC_TRACE(" Memroy initialize failed\r\n") ;
		goto errorExit ;
	}

	privateData = & pDrvCtrl->private_data ;
	dwIntCfg=(((DWORD)22UL)<<24);
	dwBase = privateData->dwLanBase ;

	/* init the Lan */
	if(!Lan_Initialize(privateData,dwIntCfg)) {
		SMSC_TRACE(" Lan initialized failed\r\n") ;
		goto errorExit;
	}

	/* init the irq */
	sysEndIsrLink.arg = (UINT) pDrvCtrl;	

    	if (sysIntAttach(pDrvCtrl->ilevel, &sysEndIsrLink, TRUE) == ERROR)
    	{
		SMSC_TRACE("system request failed!\r\n");
		goto errorExit;
    	}

	SMSC_TRACE("system Interrupt connected\r\n");

	Mac_Initialize(privateData);

	if (Lan_GetRegDW(dwBase, E2P_CMD) & E2P_CMD_MAC_ADDR_LOADED_)
	{
		/* mac address alreay load from e2prom */
		dwHigh16=Mac_GetRegDW(dwBase,ADDRH);
		dwLow32=Mac_GetRegDW(dwBase,ADDRL);
		SMSC_TRACE("Mac Address is read from LAN911x as 0x%04lX%08lX\r\n", dwHigh16,dwLow32);
		/* save address */
		pDrvCtrl->ucStationAddress[0] = LOBYTE(LOWORD(dwLow32));
		pDrvCtrl->ucStationAddress[1] = HIBYTE(LOWORD(dwLow32));
		pDrvCtrl->ucStationAddress[2] = LOBYTE(HIWORD(dwLow32));
		pDrvCtrl->ucStationAddress[3] = HIBYTE(HIWORD(dwLow32));
		pDrvCtrl->ucStationAddress[4] = LOBYTE(LOWORD(dwHigh16)); 
		pDrvCtrl->ucStationAddress[5] = HIBYTE(LOWORD(dwHigh16));
	}	
	else 
	{
		dwHigh16=0x00000070UL;
		dwLow32=0x110F9015UL;  /*7006*/
		Mac_SetRegDW(dwBase,ADDRH,dwHigh16);
		Mac_SetRegDW(dwBase,ADDRL,dwLow32);
		SMSC_TRACE("Mac Address is set by default to 0x%04lX%08lX\r\n",dwHigh16,dwLow32);
		/* Save the MAC address. */
		pDrvCtrl->ucStationAddress[0] = (BYTE)0x15;  /*   0x10  parker    */
		pDrvCtrl->ucStationAddress[1] = (BYTE)0x90;
		pDrvCtrl->ucStationAddress[2] = (BYTE)0x0F;
		pDrvCtrl->ucStationAddress[3] = (BYTE)0x11;
		pDrvCtrl->ucStationAddress[4] = (BYTE)0x70; 
		pDrvCtrl->ucStationAddress[5] = (BYTE)0x00;  /*   0x00  parker    */
	}
	
	if(!Phy_Initialize( privateData, 	pDrvCtrl->PhyAddress))
	{
		SMSC_WARNING("Failed to initialize Phy\r\n");
		goto errorExit;
	}

	Tx_Initialize(privateData);
	Rx_Initialize(privateData);

	/* initialize the END of the structure */
	
	if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, SMSC911X_DEV_NAME,
			pDrvCtrl->unit, &smsc911xFuncTable,
			"SMSC LAN91C111 Network Driver") == ERROR || 
			END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd,
			  &pDrvCtrl->ucStationAddress[0], 6, ETHERMTU,
			  100000000) == ERROR )
		goto errorExit;
	SMSC_TRACE("endObj=%x,pDrvCtrl=%x,%s,unit=%d,bootDev=%s\r\n",pDrvCtrl->endObj,pDrvCtrl,SMSC911X_DEV_NAME,pDrvCtrl->unit,sysBootParams.bootDev);
	/* set the flags to indicate readiness */

	END_OBJ_READY (&pDrvCtrl->endObj,
		IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST
		| IFF_MULTICAST | IFF_SIMPLEX |IFF_DEBUG);



	SMSC_TRACE(" -Smsc911xLoad Success.\r\n") ;

	return (&pDrvCtrl->endObj);

	errorExit:
	if (pDrvCtrl != NULL)
		free ((char *)pDrvCtrl);

	SMSC_TRACE(" -Smsc911xLoad failed.\r\n") ;

	return NULL;
}

/*******************************************************************************
* smsc911xInitParse - parse the initialization string
*
* Parse the input string.  Fill in values in the driver control structure.
* The initialization string format is:
* "<unit>:<IOBase>:<interruptVector>:<interruptLevel>:<offset>:<configValue>
*
* RETURNS: OK, or ERROR if any arguments are invalid.
*/

STATUS smsc911xInitParse
(
		SMSC911XEND_DEVICE * pDrvCtrl,
		char * initString
)
{
	SMSC_TRACE("+smsc911xInitParse\r\n") ;
    /* Parse the init string, initialize device structure */
    if (sscanf(initString, "%x:%x:%x:%x:%x:%x",
                &(pDrvCtrl->unit),
                &(pDrvCtrl->IOBase),
                &(pDrvCtrl->ivec),
                &(pDrvCtrl->ilevel),
                &(pDrvCtrl->offset),
                &(pDrvCtrl->InitConfigVal)
	) != 6
					/* the number of parameters */ )
    {
		SMSC_TRACE(" Init string parsing failed!\r\n-smsc911xInitParser\r\n");
		return (ERROR);
    }

	
	pDrvCtrl->IOBase = MEDUSA_BASE;
	pDrvCtrl->ilevel = BSP_IPL_MEDUSA;
	pDrvCtrl->offset = 2 ;
	pDrvCtrl->unit = 0;
	pDrvCtrl->private_data.dwLanBase = pDrvCtrl->IOBase ;
	pDrvCtrl->fRxDMAMode=FALSE;
	pDrvCtrl->fTxDMAMode=FALSE;
	pDrvCtrl->PhyAddress=0xFFFFFFFF; /* internal PHY*/

	SMSC_TRACE("-smsc911xInitParse\r\n") ;
	return OK;
}

/*******************************************************************************
* smsc911xMemInit - initialize memory for the chip
*
* This routine is highly specific to the device.
*
* RETURNS: OK or ERROR.
*/

STATUS smsc911xMemInit
(
	SMSC911XEND_DEVICE * pDrvCtrl	/* device to be initialized */
)
{

	SMSC_TRACE("+smsc911xMemInit\r\n");

	pDrvCtrl->numFrames = 128;

	/* Allocate space for the NET_POOL */

	if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
		return (ERROR);

⌨️ 快捷键说明

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