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

📄 dm9000end.c

📁 DM9000A 在Vxworks下的底层驱动,这个很难找的.
💻 C
📖 第 1 页 / 共 5 页
字号:
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);
static UWORD    read_srom_word( END_DEVICE *dev, UCHAR offset);
static void     write_srom_word( END_DEVICE *dev, UCHAR offset, UWORD value );
static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, UCHAR flag);
static void     udelay( int us );
static void     Delay500ns(void);

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 Specific interfaces. */

/* This is the only externally visible interface. */
/* END_OBJ*        dm9000Load (char* initString); */
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 );
/*
 * 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. */
};

/*static isrLink_t sysEndIsrLink =
{
    (void*)dm9000Int,   /* rtn */
    /*0,                  /* arg */
   /* NULL                /* next */
/*};*/

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

END_OBJ* sysEtherEndLoad( char* initString, void *pBSP )    /* String to be parsed by the driver. */
{
    END_DEVICE  *pDrvCtrl;
	char tmp;
    DRV_LOG (DRV_DEBUG_LOAD, "Loading dm9000...", 1, 2, 3, 4, 5, 6);
 /*   printf("loading dm9000......\n");
	DM9000_IN_CHAR(0x28,tmp);
	printf("tmp = %x\n",tmp);*/
    if (initString == NULL)
    {
        DRV_LOG (DRV_DEBUG_LOAD, "initString == NULL", 1, 2, 3, 4, 5, 6);
        return (NULL);
    }

    if (initString[0] == '\0')
    {
        DRV_LOG (DRV_DEBUG_LOAD, "initString[0] == 0", 1, 2, 3, 4, 5, 6);
        bcopy((char *)DM9000_DEV_NAME, initString, DM9000_DEV_NAME_LEN);
        return (NULL);
    }

    /*if (sysMedusaPresent == FALSE)
    {
        DRV_LOG (DRV_DEBUG_LOAD, "sysMedusaPresent == FALSE", 1, 2, 3, 4, 5, 6);
        return NULL;
    }*/

    /* allocate the device structure */

    pDrvCtrl = (END_DEVICE *)calloc(sizeof (END_DEVICE), 1);
    
    DrvCtrl = pDrvCtrl;
    if (pDrvCtrl == NULL)
    {
        DRV_LOG (DRV_DEBUG_LOAD, "calloc() == NULL", 1, 2, 3, 4, 5, 6);
        goto errorExit;
        printf("error exit\n");
    }
    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)
    {
        DRV_LOG (DRV_DEBUG_LOAD, "Parse() == ERROR", 1, 2, 3, 4, 5, 6);
        goto errorExit;
    }

    /* Ask the BSP to provide the ethernet address. */

    dm9000Reset (pDrvCtrl);
    /*printf("reset.....\n");*/
    /* 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)
    {
        DRV_LOG (DRV_DEBUG_LOAD, "END_OBJ_INIT() == END_MIB_INIT()==ERROR", 1, 2, 3, 4, 5, 6);
        printf("obj init error\n");
        goto errorExit;
    }

    /* Perform memory allocation/distribution */

    if (dm9000MemInit (pDrvCtrl) == ERROR)
    {
        DRV_LOG (DRV_DEBUG_LOAD, "MemInit() == ERROR", 1, 2, 3, 4, 5, 6);
        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);
		
    DRV_LOG (DRV_DEBUG_LOAD, "Done loading Template...", 1, 2, 3, 4, 5, 6);
    /*printf("Done loading Template...\n");*/
	
    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 */
{
    int               tmp1;
    unsigned long int tmp2, tmp3, tmp4;
    int               tmp5;

    /* Parse the initString */

    DRV_LOG (DRV_DEBUG_LOAD, "dm9000Parse()", 1, 2, 3, 4, 5, 6);
    DRV_LOG (DRV_DEBUG_LOAD, initString, 1, 2, 3, 4, 5, 6);
    if (sscanf(initString, "%d:%d:%lx:%lx:%lx:%d",
            &tmp1,
            &(pDrvCtrl->unit),
            &tmp2,
            &tmp3,
            &tmp4,
            &tmp5 ) != 6 /* the number of parameters */ )
        return ERROR;
    pDrvCtrl->ivec =  0x23;
    pDrvCtrl->ilevel = 0x3;
    /*printf("parm ok\n");*/
    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)
        return (ERROR);

    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)
        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)
        return (ERROR);

    if ((int)dm9000ClDescTbl[0].memArea == NULL)
    {
        DRV_LOG (DRV_DEBUG_LOAD, "system memory unavailable",
        1, 2, 3, 4, 5, 6);
        return (ERROR);
    }

    /* Initialize the memory pool. */

    if (netPoolInit(pDrvCtrl->end.pNetPool, &dm9000MclBlkConfig,
                    &dm9000ClDescTbl[0], dm9000ClDescTblNumEnt,
            NULL) == ERROR)
        {
        DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering",
        1, 2, 3, 4, 5, 6);
        return (ERROR);
        }

    /*
     * If you need clusters to store received packets into then get them
     * here ahead of time.
     */

    if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool,
        (END_BUFSIZ), FALSE))
        == NULL)
        return (ERROR);
   DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete", 1, 2, 3, 4, 5, 6);

    return OK;
}

/*******************************************************************************
*
* dm9000Start - start the device
*
* This function calls BSP functions to connect interrupts and start the
* device running in interrupt mode.
*
* RETURNS: OK or ERROR
*
*/

static STATUS dm9000Start( END_DEVICE * pDrvCtrl )  /* device ID */
{
    STATUS result;

    DRV_LOG (DRV_DEBUG_LOAD, "dm9000Start.", 1, 2, 3, 4, 5, 6);
    /*printf("dm9000 startd\n");*/
   /* sysEndIsrLink.arg = (int)pDrvCtrl;*/
    SYS_INT_CONNECT (pDrvCtrl, dm9000Int, (int)pDrvCtrl, &result);
    /*result = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec), \
			     dm9000Int, 0);*/
    if (result == ERROR)
    {
        printf("interrupt connect error\n");
        return ERROR;
    }
    /*printf("Interrupt connected.\n");*/
    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.", 1, 2, 3, 4, 5, 6);

   /* SYS_INT_ENABLE (pDrvCtrl);*/
    sysIntEnablePIC (pDrvCtrl->ilevel);
    DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.", 1, 2, 3, 4, 5, 6);

    /* TODO - start the device, enabling interrupts */

    /* Activate DM9000 */
    DM9000_OUT_CHAR( 0x05, DM9000_REG05 | 1 );      /* RX enable */
    DM9000_OUT_CHAR( 0xff, DM9000_REGFF );          /* Enable TX/RX interrupt mask */

    return (OK);
}

/*******************************************************************************
*
* dm9000Int - handle controller interrupt
*
* This routine is called at interrupt level in response to an interrupt from
* the controller.
*
* RETURNS: N/A.
*/

static void dm9000Int( END_DEVICE  *pDrvCtrl  )  /* interrupting device */
{
    UCHAR stat, reg_save, isr_status, nsr_status; /* tx_status, */

    /*if( !PIC_CHECK_EXT1() )
        return;
    PIC_CLEAR_EXT1();*/
	
    /* TODO */

    /* Save previous register address */
    /*printf("in Interrupt\n");*/
    sysIntDisablePIC (pDrvCtrl->ilevel);
    DM9000_IN_ADDR( reg_save );
    /* Disable all interrupt */
    /*DM9000_OUT_CHAR( 0x05, 0x00 );*/
    DM9000_OUT_CHAR( 0xff, 0x80 );

    /* Read the device status register */

    stat = dm9000StatusRead (pDrvCtrl);
    /* Clear NSR status */
    DM9000_IN_CHAR( 0x01, nsr_status );
    /* Clear ISR status */
    DM9000_IN_CHAR( 0xfe, isr_status );
    DM9000_OUT_CHAR( 0xfe, isr_status );

    DRV_LOG (DRV_DEBUG_INT, "Got an interrupt!", 1, 2, 3, 4, 5, 6);
    if( (!(nsr_status & 0x40)) || (pDrvCtrl->device_wait_reset == 1) )
    {
        DRV_LOG (DRV_DEBUG_STATUS, "Got an link failed interrupt!", 1, 2, 3, 4, 5, 6);

        netJobAdd ((FUNCPTR) muxError, (int) &(pDrvCtrl->end),
               (int) &(pDrvCtrl->err), 0, 0, 0);

        netJobAdd ((FUNCPTR)dm9000needreset, (int)(pDrvCtrl),
                   0, 0, 0, 0);

        logMsg("reset 9000\n",0,0,0,0,0,0);  
        goto intRet;
    }

    /*
     * enable interrupts, clear receive and/or transmit interrupts, and clear
     * any errors that may be set.
     */

    /* TODO - Check for errors */

    /* Have netTask handle any input packets */
    if( (isr_status & 1 )&&(stat & DM9000_RXON) )
    {
        DRV_LOG (DRV_DEBUG_INT, "Handle an RX interrupt!", 1, 2, 3, 4, 5, 6);

⌨️ 快捷键说明

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