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

📄 dm9000end.c

📁 DM9000A的VXWORKS下驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* dm9000End.c - dm9000 END  network interface driver */
/* Copyright Reserevd all by Davicom Semiconductor CO.,LTD */
/* version 1.0     				           */
#include "copyright_wrs.h"

#include "vxWorks.h"
#include "endLib.h"			/* Common END structures. */
#include "end.h"
#include "muxLib.h"
#include "m2Lib.h"
#include "etherLib.h"
#include "etherMultiLib.h"
#include "netLib.h"
#include "cacheLib.h"
#include "lstLib.h"			/* Needed to maintain protocol list. */
#include "iv.h"
#include "stdlib.h"
#include "sysLib.h"
#include "intLib.h"
#include "taskLib.h"

#include "drv/intrCtl/ppc860Intr.h"
#include "drv/multi/ppc860Siu.h"
#include "./dm9000end.h"


/* forward static functions */
static void     dmfe_reset_dm9000( END_DEVICE *dev );
static void     dmfe_config_dm9000( END_DEVICE *dev, int oo);
static int      dmfe_start_xmit( PKT *skb, END_DEVICE *dev);
static int      dmfe_packet_receive( PKT *skb, END_DEVICE *dev );
static int      dmfe_stop_dm9000(END_DEVICE *dev);
static void     identify_nic( END_DEVICE *dev );
static void     set_PHY_mode( END_DEVICE *dev );
static void     dm9000_hash_table(END_DEVICE *dev);
static void     program_dm9801( END_DEVICE *dev, UWORD HPNA_rev );
static void     program_dm9802(END_DEVICE *dev);
static UWORD    phy_read( END_DEVICE *dev, int reg );
static void     phy_write( END_DEVICE *dev, int reg, UWORD value);
unsigned long cal_CRC(unsigned char * Data, unsigned int Len, UCHAR flag);
void     udelay( int us );
static void     dm9000Reset(END_DEVICE *pDrvCtrl);
static void     dm9000Config(END_DEVICE *pDrvCtrl);
static void     dm9000Int(END_DEVICE *pDrvCtrl);
static void     dm9000HandleRcvInt(END_DEVICE *pDrvCtrl);
static STATUS   dm9000Recv(END_DEVICE *pDrvCtrl, char* pData);
static UINT     dm9000StatusRead(END_DEVICE *pDrvCtrl);
static void     dm9000needreset( END_DEVICE *pDrvCtrl );
END_OBJ *   sysEtherEndLoad (char* initString, void *pBSP);
static STATUS   dm9000Start(END_DEVICE* pDrvCtrl);
static STATUS   dm9000Stop(END_DEVICE* pDrvCtrl);
static int      dm9000Ioctl(END_DEVICE* pDrvCtrl, int cmd, caddr_t data);
static STATUS   dm9000Unload(END_DEVICE* pDrvCtrl);
static STATUS   dm9000Send(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
static STATUS   dm9000MCastAdd(END_DEVICE* pDrvCtrl, char* pAddress);
static STATUS   dm9000MCastDel(END_DEVICE* pDrvCtrl, char* pAddress);
static STATUS   dm9000MCastGet(END_DEVICE* pDrvCtrl, MULTI_TABLE* pTable);
static STATUS   dm9000PollStart(END_DEVICE* pDrvCtrl);
static STATUS   dm9000PollStop(END_DEVICE* pDrvCtrl);
static STATUS   dm9000PollSend(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
static STATUS   dm9000PollRcv(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
static void     dm9000AddrFilterSet(END_DEVICE *pDrvCtrl);
static STATUS   dm9000Parse( END_DEVICE * pDrvCtrl, char * initString );
static STATUS   dm9000MemInit( END_DEVICE * pDrvCtrl);
void dm9000Mode( END_DEVICE *pDrvCtrl, int mode, int reset );

STATUS	sysIntDisablePIC(int intLevel)
{
	intDisable( (int)IV_IRQ1 );
	return OK;
/*	intDisable(intLevel);*/
}

STATUS	sysIntEnablePIC(int intLevel)	/**/
{
	intEnable((int)IV_IRQ1);
	return OK;
}

unsigned char	DM9000_IN_ADDR()
{
	unsigned char x;
	x=*DM9000A_Addr_PORT;
	return x;
}

void	DM9000_OUT_ADDR(unsigned char addr)
{
	*DM9000A_Addr_PORT=addr;
}

unsigned char	DM9000_IN_BYTE()
{
	unsigned char x;
	x=*DM9000A_Data_PORT;
	return x;
}

void	DM9000_OUT_BYTE(unsigned char data)
{
	*DM9000A_Data_PORT=data;
}

unsigned short DM9000_IN_WORD()
{
	unsigned short x;
	x=*DM9000A_Data_PORT;
	return x;
}

void	DM9000_OUT_WORD(unsigned short data)
{
	*DM9000A_Data_PORT=data;
}

/*
 * This will only work if there is only a single unit, for multiple
 * unit device drivers these should be integrated into the END_DEVICE
 * structure.
 */
/* network mbuf configuration table */
M_CL_CONFIG dm9000MclBlkConfig = {0,  0,  NULL,  0};
M_CL_CONFIG Re0_dm9000MclBlkConfig = {0, 0, NULL, 0};
M_CL_CONFIG Re1_dm9000MclBlkConfig = {0, 0, NULL, 0};


/* network cluster pool configuration table */
CL_DESC dm9000ClDescTbl [] = {{END_BUFSIZ, 0, NULL, 0}};
CL_DESC Re0_dm9000ClDescTbl [] = {{END_BUFSIZ, 0, NULL, 0}};
CL_DESC Re1_dm9000ClDescTbl [] = {{END_BUFSIZ, 0, NULL, 0}};

int dm9000ClDescTblNumEnt = (NELEMENTS(dm9000ClDescTbl));

/* LOCALS */
static UCHAR  nfloor = 0;
unsigned long CrcTable[256] = {
   0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
   0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
   0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
   0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
   0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
   0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
   0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
   0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
   0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
   0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
   0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
   0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
   0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
   0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
   0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
   0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
   0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
   0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
   0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
   0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
   0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
   0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
   0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
   0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
   0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
   0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
   0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
   0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
   0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
   0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
   0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
   0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
   0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
   0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
   0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
   0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
   0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
   0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
   0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
   0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
   0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
   0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
   0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
   0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
   0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
   0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
   0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
   0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
   0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
   0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
   0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
   0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
   0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
   0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
   0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
   0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
   0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
   0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
   0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
   0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
   0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
   0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
   0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
   0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
};


/*
 * Declare our function table.  This is static across all driver
 * instances.
 */

static NET_FUNCS dm9000FuncTable =
{
    (FUNCPTR) dm9000Start,      /* Function to start the device. */
    (FUNCPTR) dm9000Stop,       /* Function to stop the device. */
    (FUNCPTR) dm9000Unload,     /* Unloading function for the driver. */
    (FUNCPTR) dm9000Ioctl,      /* Ioctl function for the driver. */
    (FUNCPTR) dm9000Send,       /* Send function for the driver. */
    (FUNCPTR) dm9000MCastAdd,   /* Multicast add function for the */
                                /* driver. */
    (FUNCPTR) dm9000MCastDel,   /* Multicast delete function for */
                                /* the driver. */
    (FUNCPTR) dm9000MCastGet,   /* Multicast retrieve function for */
                                /* the driver. */
    (FUNCPTR) dm9000PollSend,   /* Polling send function */
    (FUNCPTR) dm9000PollRcv,    /* Polling receive function */

    endEtherAddressForm,        /* put address info into a NET_BUFFER */
    endEtherPacketDataGet,      /* get pointer to data in NET_BUFFER */
    endEtherPacketAddrGet       /* Get packet addresses. */
};


END_DEVICE *DrvCtrl;
/*******************************************************************************
*
* sysEtherEndLoad - 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 the initString.
*
* The string contains the target specific parameters like this:
*
* "register addr:int vector:int level:shmem addr:shmem size:shmem width"
*
* RETURNS: An END object pointer or NULL on error.
*/

UINT8	DM9000A_read_reg(UINT16 adr)
{
    UINT8 x;
	
	*DM9000A_Addr_PORT=adr;	
	x=*DM9000A_Data_PORT;	
	return x;
}

void	DM9000A_write_reg(UINT16 adr,UINT8 dat)
{
	*DM9000A_Addr_PORT=adr;
	*DM9000A_Data_PORT=dat;
}

END_OBJ* sysEtherEndLoad( char* initString, void *pBSP )    /* String to be parsed by the driver. */
{
    END_DEVICE  *pDrvCtrl;

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

    if (initString[0] == '\0')
    {
        bcopy((char *)DM9000_DEV_NAME, initString, DM9000_DEV_NAME_LEN);
        return (NULL);
    }

    /* allocate the device structure */

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

    DrvCtrl = pDrvCtrl;
    if (pDrvCtrl == NULL)
    {
        goto errorExit;
    }

    memset( (void*)pDrvCtrl, 0, sizeof( END_DEVICE ) );
    (pDrvCtrl->flags) = 0;
    (pDrvCtrl->op_mode) = DM9000_MEDIA_MODE;

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

    if (dm9000Parse(pDrvCtrl, initString) == ERROR)
    {
        goto errorExit;
    }
    /* Ask the BSP to provide the ethernet address. */

    dm9000Reset (pDrvCtrl);

    /* initialize the END and MIB2 parts of the structure */

    /*
     * The M2 element must come from m2Lib.h
     * This dm9000 is set up for a DIX type ethernet device.
     */
    if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, DM9000_DEV_NAME,
                      pDrvCtrl->unit, &dm9000FuncTable,
                      "END Template Driver.") == ERROR
     || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
                      &pDrvCtrl->enetAddr[0], 6, END_BUFSIZ,
                      END_SPEED)
            == ERROR)
    {
        goto errorExit;
    }

    /* Perform memory allocation/distribution */

    if (dm9000MemInit (pDrvCtrl) == ERROR)
    {
        goto errorExit;
    }

    /* reset and reconfigure the device */

    dm9000Reset (pDrvCtrl);
    dm9000Config (pDrvCtrl);

    /* set the flags to indicate readiness */

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

    return (&pDrvCtrl->end);

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

    return NULL;
}

/*******************************************************************************
*
* dm9000Parse - parse the init string
*
* Parse the input string.  Fill in values in the driver control structure.
*
* The muxLib.o module automatically prepends the unit number to the user's
* initialization string from the BSP (configNet.h).
*
* .IP <unit>
* Device unit number, a small integer.
* .IP <vecNum>
* Interrupt vector number (used with sysIntConnect)
* .IP <intLvl>
* Interrupt level
* .LP
*
* RETURNS: OK or ERROR for invalid arguments.
*/

static STATUS dm9000Parse( END_DEVICE * pDrvCtrl,  /* device pointer */
                           char * initString )     /* information string */
{
    /* Parse the initString */ 
    pDrvCtrl->ivec =  2;	/*0x23;*/
    pDrvCtrl->ilevel = 3;	/*0x3;*/
    return OK;
}

/*******************************************************************************
*
* dm9000MemInit - initialize memory for the chip
*
* This routine is highly specific to the device.
*
* RETURNS: OK or ERROR.
*/
static STATUS dm9000MemInit( END_DEVICE * pDrvCtrl )    /* device to be initialized */
{
     /* This is how we would set up and END netPool using netBufLib(1).
     * This code is pretty generic.
     */

    if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
	{
		printf("the memory init is error!\n");
        return (ERROR);
	}

	/* cache functions descriptor for data buffers 
    Dm9000ABufCacheFuncs.flushRtn = Dm9000ABufFlushRtn;
    Dm9000ABufCacheFuncs.invalidateRtn = Dm9000AFecBufInvRtn;
    Dm9000ABufCacheFuncs.virtToPhysRtn = NULL;
    Dm9000ABufCacheFuncs.physToVirtRtn = NULL;

    pDrvCtrl->cacheFuncs = Dm9000ABufCacheFuncs;*/

    dm9000MclBlkConfig.mBlkNum = 128; /*16;*/
    dm9000ClDescTbl[0].clNum = 128;  /*16;*/
    dm9000MclBlkConfig.clBlkNum = dm9000ClDescTbl[0].clNum;

    /* Calculate the total memory for all the M-Blks and CL-Blks. */

    dm9000MclBlkConfig.memSize = (dm9000MclBlkConfig.mBlkNum *
                                 (MSIZE + sizeof (long))) +
                                 (dm9000MclBlkConfig.clBlkNum *
                                 (CL_BLK_SZ + sizeof(long)));

    if ((dm9000MclBlkConfig.memArea = (char *) memalign (sizeof(long),
                                 dm9000MclBlkConfig.memSize)) == NULL)
	{
		printf("the dm9000MclBlkConfig init is error!\n");
        return (ERROR);
	}

    /* Calculate the memory size of all the clusters. */

    dm9000ClDescTbl[0].memSize = (dm9000ClDescTbl[0].clNum *
                                 (END_BUFSIZ + 8)) + sizeof(int);

    /* Allocate the memory for the clusters from cache safe memory. */

    if ((dm9000ClDescTbl[0].memArea = (char *) memalign ( sizeof(long),
                                  dm9000ClDescTbl[0].memSize)) == NULL)
	{
		printf("the dm9000ClDescTbl init is error!\n");
        return (ERROR);
	}

    if ((int)dm9000ClDescTbl[0].memArea == NULL)
    {
		printf("the system memory unavailable!\n");
        return (ERROR);
    }

    /* Initialize the memory pool. */

    if (netPoolInit(pDrvCtrl->end.pNetPool, &dm9000MclBlkConfig,
                    &dm9000ClDescTbl[0], dm9000ClDescTblNumEnt,
            NULL) == ERROR)
        {
		printf("Could not init buffering!\n");

⌨️ 快捷键说明

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