fei82557end.c

来自「cpc-1631的BSP包for VxWorks操作系统」· C语言 代码 · 共 1,742 行 · 第 1/5 页

C
1,742
字号
    FEI_LONG_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))

#define CFD_POINT_RD(base, offset, value, type)                         \
    {                                                                   \
    volatile UINT32 temp;                                               \
    FEI_LONG_RD ((UINT32 *) ((UINT32) (base) + (offset)),(temp));       \
    value = (type)temp;                                                 \
    }

/* this is a special case, as the device will read as an address */

#define CFD_NEXT_RD(base, value)					\
    CFD_LONG_RD ((UINT32) (base), CFD_SW_NEXT_OFFSET, (value))

/* receive frame descriptors read macros */

#define RFD_BYTE_RD(base, offset, value)				\
    FEI_BYTE_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))

#define RFD_WORD_RD(base, offset, value)				\
    FEI_WORD_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))

#define RFD_LONG_RD(base, offset, value)				\
    FEI_LONG_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))

/* receive buffer descriptors read macros */

#define RBD_BYTE_RD(base, offset, value)                                \
    FEI_BYTE_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))

#define RBD_WORD_RD(base, offset, value)                                \
    FEI_WORD_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))

#define RBD_LONG_RD(base, offset, value)                                \
    FEI_LONG_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))

/* various command frame descriptors macros */

#define CFD_PKT_ADDR(cfdBase)						\
    ((UINT32 *) ((UINT32) cfdBase + CFD_PKT_OFFSET))

#define RFD_PKT_ADDR(cfdBase)						\
    ((UINT32 *) ((UINT32) cfdBase + RFD_PKT_OFFSET))

#define CFD_IA_ADDR(cfdBase)						\
    ((UINT32 *) ((UINT32) (cfdBase) + CFD_IA_OFFSET))

#define CFD_MC_ADDR(cfdBase)						\
    ((UINT32 *) ((UINT32) (cfdBase) + CFD_MC_OFFSET))

#define CFD_CONFIG_WR(address, value)					\
    FEI_BYTE_WR ((UINT32 *) ((UINT32) (address)),          		\
	     (value))

#define I82557_INT_ENABLE(value)					\
    {									\
    UINT8 temp;								\
    CACHE_PIPE_FLUSH();                                                 \
    CSR_BYTE_RD (CSR_INT_OFFSET, temp);				\
    CSR_BYTE_WR (CSR_INT_OFFSET, (temp & ~value));		\
    }	

#define I82557_INT_DISABLE(value)					\
    {									\
    UINT8 temp;								\
    CACHE_PIPE_FLUSH();                                                 \
    CSR_BYTE_RD (CSR_INT_OFFSET, temp);				\
    CSR_BYTE_WR (CSR_INT_OFFSET, (temp | value));		\
    }	

/* extern */

IMPORT POOL_FUNC *     _pEndNetPoolFuncTbl; 
IMPORT int ffsMsb ();

FUNCPTR feiEndIntConnect = (FUNCPTR) intConnect;
FUNCPTR feiEndIntDisconnect = (FUNCPTR) NULL;

/* locals */

/* The definition of the driver control structure */

typedef struct drv_ctrl
    {
    END_OBJ        	endObj;		/* base class */
    int		   	unit;		/* unit number */
    FUNCPTR             pSendRtn;
    int	    		nRFDs;		/* number of RFDs on DMA ring  */
    int	    		nRBDs;		/* number of RBDs on DMA ring  */
    int	    		nCFDs;		/* how many CFDs to create */
    char *              pRfdBase;       /* RFD allocation base */
    char *              pRbdBase;       /* RBD allocation base */
    char *              pCfdBase;       /* CFD allocation base */
    char *		pClusterBase;	/* cluster pool base */
    int			nClusters;	/* number of clusters to create */
    int                 clToRfdRatio;   /* Ratio of clusters to RFDs */
    ULONG		clMemSize;	/* cluster pool size */
    char *		pMclBlkMemArea;	/* clBlk mBlk memory area pointer */
    volatile CSR_ID	pCSR;		/* pointer to CSR base */
    volatile CFD_ID	pFreeCFD;	/* current free CFD */
    volatile CFD_ID	pUsedCFD;	/* first used CFD */
    volatile RFD_ID     pRFD;		/* current Receive Frame Descriptor */
    volatile RBD_ID	pRBD;		/* current Receive Buffer Descriptor */
    RFD_TAG *           rfdTags;        /* Array of RFD_TAGs */
    RBD_TAG *           rbdTags;        /* Array of RBD_TAGs */
    int                 rbdIndex;       /* current RX index  */
    int                 rfdIndex;       /* current RX index  */
    RBD_TAG *           eLRbdTag;       /* RBD that currently has EL bit set */
    RBD_TAG *           startRbdTag;    /* RBD that RU was last started at */
    INT8		flags;		/* driver state */
    BOOL		attached;	/* interface has been attached */
    volatile BOOL	rxHandle;	/* rx handler scheduled */
    BOOL		txHandle;	/* tx handler scheduled */
    BOOL		txStall;	/* tx handler stalled - no CFDs */
    UINT                maxRxFrames;	/* max frames to Receive in one job */
    BOOL		rxJobQued;	/* fei82557RecvHandler() queing flag */
    CACHE_FUNCS		cacheFuncs;	/* cache descriptor */
    CACHE_FUNCS		cacheDmaFuncs;	/* cache descriptor */
    CACHE_FUNCS		cacheUserFuncs;	/* cache descriptor */
    FEI_BOARD_INFO  	board;		/* board specific info */
    CL_POOL_ID  	pClPoolId;	/* cluster pool identifier */
    int			offset;		/* Alignment offset */
    UINT                deviceId;	/* PCI device ID */
    END_ERR             lastError;      /* Last error passed to muxError */
    UINT                errorNoBufs;    /* cluster exhaustion */
    WDOG_ID             txRetryWDId;    /* Tx restart watchdog */
    UINT16  		event;		/* storage for interrupt events */ 
    } DRV_CTRL;

#ifdef DRV_DEBUG557 

void feiPoolShow
    (
    int unit
    )
    {
    DRV_CTRL *pDrvCtrl = (DRV_CTRL *)endFindByName ("fei", unit);

    netPoolShow (pDrvCtrl->endObj.pNetPool);

    }

#endif  /* DRV_DEBUG557 */

/* Function declarations not in any header files */

IMPORT STATUS    sys557Init (int unit, FEI_BOARD_INFO *pBoard);

/* forward function declarations */

LOCAL int	fei82557ClkRate = 0;

LOCAL STATUS    fei82557InitParse (DRV_CTRL *pDrvCtrl, char *initString);
LOCAL STATUS    fei82557InitMem (DRV_CTRL *pDrvCtrl);
LOCAL STATUS    fei82557Encap (DRV_CTRL *pDrvCtrl, CFD_ID pCFD,
                        M_BLK *pMblkHead);
LOCAL STATUS    fei82557Send (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);
LOCAL STATUS    fei82557GatherSend (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);
LOCAL STATUS    fei82557CopySend (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);

LOCAL UINT16	fei82557Action (DRV_CTRL *pDrvCtrl, UINT16 action);
LOCAL STATUS    fei82557PhyInit (DRV_CTRL *pDrvCtrl);
LOCAL STATUS	fei82557Stop (DRV_CTRL *pDrvCtrl);
LOCAL STATUS 	fei82557Reset (DRV_CTRL *pDrvCtrl);
LOCAL STATUS    fei82557SCBCommand (DRV_CTRL *pDrvCtrl, UINT8 cmd, 
			       BOOL addrValid, UINT32 *addr);
LOCAL STATUS    fei82557Diag (DRV_CTRL *pDrvCtrl);
LOCAL STATUS    fei82557IASetup (DRV_CTRL *pDrvCtrl);
LOCAL STATUS    fei82557Config (DRV_CTRL *pDrvCtrl);
LOCAL void	fei82557MCastListForm (DRV_CTRL *pDrvCtrl, CFD_ID pCFD);
LOCAL void	fei82557ConfigForm (DRV_CTRL *pDrvCtrl, CFD_ID pCFD);
LOCAL int	fei82557MDIPhyLinkSet (DRV_CTRL *pDrvCtrl, int phyAddr);
LOCAL STATUS    fei82557NOP (DRV_CTRL *pDrvCtrl);
LOCAL void      fei82557CFDFree ( DRV_CTRL *pDrvCtrl);
LOCAL void	fei82557FDUpdate (DRV_CTRL *pDrvCtrl, UINT8 fdList);
LOCAL STATUS	fei82557MDIPhyConfig (DRV_CTRL *pDrvCtrl, int phyAddr);
LOCAL void	fei82557Int (DRV_CTRL *pDrvCtrl);
LOCAL void      fei82557NoResource(DRV_CTRL *pDrvCtrl);
LOCAL void      fei82557MuxTxRestart( END_OBJ *pEndObj);
LOCAL void      fei82557RecvHandler (DRV_CTRL *pDrvCtrl);
LOCAL STATUS    fei82557Restart (DRV_CTRL *  pDrvCtrl);
LOCAL int	fei82557MDIRead (DRV_CTRL *pDrvCtrl, int regAddr,
			    int phyAddr, UINT16 *retVal);
LOCAL int	fei82557MDIWrite (DRV_CTRL *pDrvCtrl, int regAddr,
			    int phyAddr, UINT16 writeData);
/* debug routines, not normally compiled */
      STATUS    fei82557ErrCounterDump (DRV_CTRL *pDrvCtrl, UINT32 *memAddr);
      STATUS    fei82557DumpPrint (int unit);
LOCAL void	fei82557TxRestart (END_OBJ *pEndObj);
/* END Specific interfaces. */

END_OBJ *	fei82557EndLoad (char *initString);    
LOCAL STATUS    fei82557Start (DRV_CTRL *pDrvCtrl);
LOCAL STATUS	fei82557Unload (DRV_CTRL *pDrvCtrl);
LOCAL STATUS    fei82557Stop (DRV_CTRL *pDrvCtrl);
LOCAL int       fei82557Ioctl (DRV_CTRL *pDrvCtrl, UINT32 cmd, caddr_t data);
LOCAL STATUS    fei82557Send (DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);
LOCAL STATUS    fei82557MCastAddrAdd (DRV_CTRL *pDrvCtrl, char* pAddress);
LOCAL STATUS    fei82557MCastAddrDel (DRV_CTRL *pDrvCtrl, char* pAddress);
LOCAL STATUS    fei82557MCastAddrGet (DRV_CTRL *pDrvCtrl,
                                        MULTI_TABLE *pTable);
LOCAL STATUS    fei82557PollSend (DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);
LOCAL STATUS    fei82557PollReceive (DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);
LOCAL STATUS    fei82557PollStart (DRV_CTRL *pDrvCtrl);
LOCAL STATUS    fei82557PollStop (DRV_CTRL *pDrvCtrl);


/* 
 * Define the device function table.  This is static across all driver
 * instances.
 */

LOCAL NET_FUNCS netFuncs = 
    {
    (FUNCPTR)fei82557Start,		/* start func. */		 
    (FUNCPTR)fei82557Stop,		/* stop func. */
    (FUNCPTR)fei82557Unload,		/* unload func. */		
    (FUNCPTR)fei82557Ioctl,		/* ioctl func. */		 
    (FUNCPTR)fei82557Send,      	/* send func. */		  
    (FUNCPTR)fei82557MCastAddrAdd,    	/* multicast add func. */	 
    (FUNCPTR)fei82557MCastAddrDel,    	/* multicast delete func. */      
    (FUNCPTR)fei82557MCastAddrGet,    	/* multicast get fun. */	  
    (FUNCPTR)fei82557PollSend,    	/* polling send func. */	  
    (FUNCPTR)fei82557PollReceive,    	/* polling receive func. */
    endEtherAddressForm,   	/* put address info into a NET_BUFFER. */
    endEtherPacketDataGet, 	/* get pointer to data in NET_BUFFER. */
    endEtherPacketAddrGet  	/* Get packet addresses. */
    };		

/*******************************************************************************
*
* fei82557EndLoad - initialize the driver and device
*
* This routine initializes both, driver and device to an operational state
* using device specific parameters specified by <initString>.
*
* The parameter string, <initString>, is an ordered list of parameters each
* separated by a colon. The format of <initString> is,
* "<unit>:<memBase>:<memSize>:<nCFDs>:<nRFDs>:<flags>:<offset>:<deviceId>:
*  <maxRxFrames>:<clToRfdRatio>:<nClusters>"
*
*
* The 82557 shares a region of memory with the driver.  The caller of this
* routine can specify the address of this memory region, or can specify that
* the driver must obtain this memory region from the system resources.
*
* A default number of transmit/receive frames of 32 and 128 respectively and 
* can be selected by passing zero in the parameters <nTfds> and <nRfds>. In 
* other cases, the number of frames selected should be greater than two.
*
* All optional parameters can be set to their default value by specifing 
* NONE (-1) as their value. 
*
* The <memBase> parameter is used to inform the driver about the shared
* memory region.  If this parameter is set to the constant "NONE," then this
* routine will attempt to allocate the shared memory from the system.  Any
* other value for this parameter is interpreted by this routine as the address
* of the shared memory region to be used. The <memSize> parameter is used
* to check that this region is large enough with respect to the provided
* values of both transmit/receive frames.
*
* If the caller provides the shared memory region, then the driver assumes
* that this region is non-cached. 
*
* If the caller indicates that this routine must allocate the shared memory
* region, then this routine will use memalign() to allocate some cache aligned 
* memory. 
*
* The <memSize> parameter specifies the size of the pre-allocated memory
* region. If memory base is specified as NONE (-1), the driver ignores this
* parameter. Otherwise, the driver checks the size of the provided memory
* region is adequate with respect to the given number of RFDs, RBDs, CFDs, and
* clusters specified. The number of clusters required will be at least equal 
* to (nRFDs * 2) + nCFDs. Otherwise the End Load routine will return ERROR. 
* The number of clusters can be specified by either passing a value in the 
* nCluster parameter, in which case the nCluster value must be at least 
* nRFDs * 2, or by setting the cluster to RFD ratio (clToRfdRatio) to a number 
* equal or greater than 2.
* 
* 
* The <nTfds> parameter specifies the number of transmit descriptor/buffers 
* to be allocated. If this parameter is less than two, a default of 64 is used.
*
* The <nRfds> parameter specifies the number of receive descriptors to be
* allocated. If this parameter is less than two or NONE (-1) a default of 
* 128 is used.
* 
* The <flags> parameter specifies the user flags may control the run-time 
* characteristics of the Ethernet chip. Not implemented.
* 
* The <offset> parameter is used to align IP header on word boundary for CPUs 
* that need long word aligned access to the IP packet (this will normally be 
* zero or two). This parameter is optional, the default value is zero.
*
* The <deviceId> parameter is used to indicate the specific type of device 
* being used, the 82557 or subsequent.  This is used to determine if features 
* which were introduced after the 82557 can be used. The default is the 82557. 
* If this is set to any value other than ZERO (0), NONE (-1), or 
* FEI82557_DEVICE_ID (0x1229) it is assumed that the device will support 
* features not in the 82557.
*
* The <maxRxFrames> parameter limits the number of frames the receive handler 
* will service in one pass. It is intended to prevent the tNetTask from 
* monoploizing the CPU and starving applications. This parameter is optional, 
* the default value is nRFDs * 2.
* 
* The <clToRfdRatio> parameter sets the number of clusters as a ratio of nRFDs. 
* The minimum setting for this parameter is 2. This parameter is optional, the
* default value is 5.
* 
* The <nClusters> parameter sets the number of clusters to allocate. This value 
* must be  at least nRFD * 2.  If this value is set then the <clToRfdRatio> is 
* ignored. This parameter is optional, the default is nRFDs * clToRfdRatio.
* 
* RETURNS: an END object pointer, or NULL on error.
*
* SEE ALSO: ifLib,
* .I "Intel 82557 User's Manual"
*/

END_OBJ* fei82557EndLoad
    (
    char *initString      /* parameter string */
    )
    {
    DRV_CTRL *	pDrvCtrl;       /* pointer to DRV_CTRL structure */
    UCHAR   	enetAddr[6];	/* ethernet address */
    UINT32	speed;
    UINT32	scbStatus;
    char        bucket[2];

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

    if (initString == NULL)
	return (NULL);

    if (initString[0] == 0)
	{
	bcopy ((char *)DEV_NAME, (void *)initString, DEV_NAME_LEN);
	return (0);
	}

    /* allocate the device structure */

    pDrvCtrl = (DRV_CTRL *) calloc (sizeof (DRV_CTRL), 1);

    if (pDrvCtrl == NULL)
	return (NULL);

⌨️ 快捷键说明

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