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

📄 ln97xend.c

📁 vxWorks下AMD973芯片的驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:

#endif /*DRV_DEBUG*/

/* locals */

LOCAL int lnTsize = LN_TMD_TLEN;    /* deflt xmit ring size as power of 2 */
LOCAL int lnRsize = LN_RMD_RLEN;    /* deflt recv ring size as power of 2 */

LOCAL BOOL lnKickStartTx = LN_KICKSTART_TX;

/* forward static functions */

LOCAL int 	ln97xReset (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL void 	ln97xInt (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL void 	ln97xHandleRecvInt (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL STATUS 	ln97xRecv (LN_97X_DRV_CTRL * pDrvCtrl, LN_RMD *rmd);
LOCAL LN_RMD *	ln97xFullRMDGet (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL void 	ln97xCsrWrite (LN_97X_DRV_CTRL * pDrvCtrl, int reg,
                               UINT32 value);
LOCAL void 	ln97xRestart (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL STATUS 	ln97xRestartSetup (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL void 	ln97xAddrFilterSet (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL UINT32 	ln97xCsrRead (LN_97X_DRV_CTRL * pDrvCtrl, int reg);
LOCAL void	ln97xBcrWrite (LN_97X_DRV_CTRL * pDrvCtrl, int reg,
                               UINT32 value);
LOCAL void 	ln97xTRingScrub (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL void	ln97xConfig (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL STATUS 	ln97xMemInit (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL UINT32 	ln97xBcrRead (LN_97X_DRV_CTRL * pDrvCtrl, int reg);

/* END Specific interfaces. */

LOCAL STATUS    ln97xStart (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL STATUS    ln97xStop (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL STATUS    ln97xUnload (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL int       ln97xIoctl (LN_97X_DRV_CTRL * pDrvCtrl, int cmd, caddr_t data);
LOCAL STATUS    ln97xSend (LN_97X_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);
LOCAL STATUS    ln97xMCastAddrAdd (LN_97X_DRV_CTRL* pDrvCtrl, char * pAddress);
LOCAL STATUS    ln97xMCastAddrDel (LN_97X_DRV_CTRL * pDrvCtrl,
                                   char * pAddress);
LOCAL STATUS    ln97xMCastAddrGet (LN_97X_DRV_CTRL * pDrvCtrl,
                                    MULTI_TABLE * pTable);
LOCAL STATUS    ln97xPollSend (LN_97X_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);
LOCAL STATUS    ln97xPollReceive (LN_97X_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);
LOCAL STATUS    ln97xPollStart (LN_97X_DRV_CTRL * pDrvCtrl);
LOCAL STATUS    ln97xPollStop (LN_97X_DRV_CTRL * pDrvCtrl);

/*
 * Declare our function table.  This is static across all driver
 * instances.
 */
LOCAL NET_FUNCS ln97xFuncTable =
    {
    (FUNCPTR) ln97xStart,               /* Function to start the device. */
    (FUNCPTR) ln97xStop,                /* Function to stop the device. */
    (FUNCPTR) ln97xUnload,		/* Unloading function for the driver. */
    (FUNCPTR) ln97xIoctl,               /* Ioctl function for the driver. */
    (FUNCPTR) ln97xSend,                /* Send function for the driver. */
    (FUNCPTR) ln97xMCastAddrAdd,        /* Multicast address add  */
    (FUNCPTR) ln97xMCastAddrDel,	/* Multicast address delete */
    (FUNCPTR) ln97xMCastAddrGet,	/* Multicast table retrieve */
    (FUNCPTR) ln97xPollSend,            /* Polling send function  */
    (FUNCPTR) ln97xPollReceive,		/* Polling receive function */
    endEtherAddressForm,       		/* Put address info into a packet.  */
    endEtherPacketDataGet,     		/* Get a pointer to packet data. */
    endEtherPacketAddrGet      		/* Get packet addresses. */
    };

/******************************************************************************
*
* ln97xEndLoad - 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:
*
* <unit>:<devMemAddr>:<devIoAddr>:<pciMemBase:<vecnum>:<intLvl>:<memAdrs>
* :<memSize>:<memWidth>:<csr3b>:<offset>:<flags>
*
* 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, "lnPci") 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 * ln97xEndLoad
    (
    char * initString            /* string to be parse by the driver */
    )		
    {
    LN_97X_DRV_CTRL *	pDrvCtrl;

    DRV_LOG (DRV_DEBUG_LOAD, "Loading ln97x...debug @ 0X%X\n",
             (int)&ln97xDebug, 2, 3, 4, 5, 6);

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

    if (initString [0] == NULL)
        {
        bcopy ((char *)LN_97X_DEV_NAME, initString, LN_97X_DEV_NAME_LEN);
	DRV_LOG (DRV_DEBUG_LOAD, "Returning string...\n", 1, 2, 3, 4, 5, 6);
        return ((END_OBJ *)OK);
        }

    DRV_LOG (DRV_DEBUG_LOAD, "lnstring: [%s]\n",
	    (int)initString, 2, 3, 4, 5, 6);

    /* allocate the device structure */

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

    if (pDrvCtrl == NULL)
        goto errorExit;

    DRV_LOG (DRV_DEBUG_LOAD, "DrvControl : 0x%X\n", (int)pDrvCtrl,
             2, 3, 4, 5, 6);

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

    if (ln97xInitParse (pDrvCtrl, initString) == ERROR)
	{
	DRV_LOG (DRV_DEBUG_LOAD, "Parse failed ...\n", 1, 2, 3, 4, 5, 6);
        goto errorExit;
	}

    /* Have the BSP hand us our address. */

    SYS_ENET_ADDR_GET (pDrvCtrl, &(pDrvCtrl->enetAddr [0]));

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

    if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, LN_97X_DEV_NAME,
                      pDrvCtrl->unit, &ln97xFuncTable,
                      "AMD 79C970 Lance PCI Enhanced Network Driver") == ERROR
     || END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd,
                      &pDrvCtrl->enetAddr[0], 6, ETHERMTU,
                      LN_SPEED)
                    == ERROR)
        goto errorExit;

    DRV_LOG (DRV_DEBUG_LOAD, "END init done ...\n", 1, 2, 3, 4, 5, 6);

    /* Perform memory allocation */

    if (ln97xMemInit (pDrvCtrl) == ERROR)
        goto errorExit;

	
    DRV_LOG (DRV_DEBUG_LOAD, "Malloc done ...\n", 1, 2, 3, 4, 5, 6);

    /* Perform memory distribution and reset and reconfigure the device */

    if (ln97xRestartSetup (pDrvCtrl) == ERROR)
        goto errorExit;

    DRV_LOG (DRV_DEBUG_LOAD, "Restart setup done ...\n", 1, 2, 3, 4, 5, 6);

    /* set the flags to indicate readiness */

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

    DRV_LOG (DRV_DEBUG_LOAD, "Done loading ln97x...\n", 1, 2, 3, 4, 5, 6);

    return (&pDrvCtrl->endObj);

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

    return ((END_OBJ *)NULL);
    }

/*******************************************************************************
*
* ln97xInitParse - parse the initialization string
*
* Parse the input string. This routine is called from ln97xEndLoad() which
* intializes some values in the driver control structure with the values
* passed in the intialization string.
*
* The initialization string format is:
* <unit>:<devMemAddr>:<devIoAddr>:<pciMemBase:<vecNum>:<intLvl>:<memAdrs>
* :<memSize>:<memWidth>:<csr3b>:<offset>:<flags>
*
* .IP <unit>
* Device unit number, a small integer.
* .IP <devMemAddr>
* Device register base memory address
* .IP <devIoAddr>
* Device register base IO address
* .IP <pciMemBase>
* Base address of PCI memory space
* .IP <vecNum>
* Interrupt vector number.
* .IP <intLvl>
* Interrupt level.
* .IP <memAdrs>
* Memory pool address or NONE.
* .IP <memSize>
* Memory pool size or zero.
* .IP <memWidth>
* Memory system size, 1, 2, or 4 bytes (optional).
* .IP <CSR3>
* Value of CSR3 (for endian-ness mainly)
* .IP <offset>
* Offset of starting of data in the device buffers.
* .IP <flags>
* Device specific flags, for future use.
*
* RETURNS: OK, or ERROR if any arguments are invalid.
*/

STATUS ln97xInitParse
    (
    LN_97X_DRV_CTRL *	pDrvCtrl,	/* pointer to the control structure */
    char * 		initString	/* initialization string */
    )
    {
    char*       tok;
    char**      holder = NULL;
    UINT32      devMemAddr;
    UINT32      devIoAddr;

    DRV_LOG (DRV_DEBUG_LOAD, "Parse starting ...\n", 1, 2, 3, 4, 5, 6);

    /* Parse the initString */

    /* Unit number. */

    tok = strtok_r (initString, ":", holder);
    if (tok == NULL)
        return ERROR;

    pDrvCtrl->unit = atoi (tok);

    DRV_LOG (DRV_DEBUG_LOAD, "Unit : %d ...\n", pDrvCtrl->unit, 2, 3, 4, 5, 6);

    /* devAdrs address. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    devMemAddr = (UINT32) strtoul (tok, NULL, 16);

    DRV_LOG (DRV_DEBUG_LOAD, "devMemAddr : 0x%X ...\n", devMemAddr,
             2, 3, 4, 5, 6);

    /* devIoAddrs address */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    devIoAddr = (UINT32) strtoul (tok, NULL, 16);

    DRV_LOG (DRV_DEBUG_LOAD, "devIoAddr : 0x%X ...\n", devIoAddr,
             2, 3, 4, 5, 6);

    /* always use memory mapped IO if provided, else use io map */
    
    if ((devMemAddr == NONE) && (devIoAddr == NONE))
        {
        DRV_LOG (DRV_DEBUG_LOAD, "No memory or IO base specified ...\n",
                 1, 2, 3, 4, 5, 6);
        return (ERROR);
        }
    else if (devMemAddr != NONE)
        {
        pDrvCtrl->devAdrs = devMemAddr;
        pDrvCtrl->flags   |= LS_MODE_MEM_IO_MAP;
        }
    else
        pDrvCtrl->devAdrs = devIoAddr;
        
    /* PCI memory base address as seen from the CPU */
    
    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->pciMemBase = strtoul (tok, NULL, 16);

    DRV_LOG (DRV_DEBUG_LOAD, "Pci : 0x%X ...\n", pDrvCtrl->pciMemBase,
             2, 3, 4, 5, 6);

    /* Interrupt vector. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->ivec = atoi (tok);

    DRV_LOG (DRV_DEBUG_LOAD, "ivec : 0x%X ...\n", pDrvCtrl->ivec,
             2, 3, 4, 5, 6);
    /* Interrupt level. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->ilevel = atoi (tok);
    DRV_LOG (DRV_DEBUG_LOAD, "ilevel : 0x%X ...\n", pDrvCtrl->ilevel,
             2, 3, 4, 5, 6);

    /* Caller supplied memory address. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->memAdrs = (char *)strtoul (tok, NULL, 16);
    DRV_LOG (DRV_DEBUG_LOAD, "memAdrs : 0x%X ...\n", (int)pDrvCtrl->memAdrs,
             2, 3, 4, 5, 6);

    /* Caller supplied memory size. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->memSize = strtoul (tok, NULL, 16);
    DRV_LOG (DRV_DEBUG_LOAD, "memSize : 0x%X ...\n", pDrvCtrl->memSize,
             2, 3, 4, 5, 6);

    /* Caller supplied memory width. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->memWidth = atoi (tok);
    DRV_LOG (DRV_DEBUG_LOAD, "memWidth : 0x%X ...\n", pDrvCtrl->memWidth,
             2, 3, 4, 5, 6);

    /* CSR3B value */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->csr3B = strtoul (tok, NULL, 16);
    DRV_LOG (DRV_DEBUG_LOAD, "CSR3b : 0x%X ...\n", pDrvCtrl->csr3B,
             2, 3, 4, 5, 6);

    /* Caller supplied alignment offset. */
    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
	return ERROR;
    pDrvCtrl->offset = atoi (tok);
    DRV_LOG (DRV_DEBUG_LOAD, "Offset : 0x%X ...\n", pDrvCtrl->offset,
             2, 3, 4, 5, 6);

    /* caller supplied flags */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;

    pDrvCtrl->flags |= strtoul (tok, NULL, 16);
    DRV_LOG (DRV_DEBUG_LOAD, "flags : 0x%X ...\n", pDrvCtrl->flags,
             2, 3, 4, 5, 6);

    return OK;
    }

/*******************************************************************************
*
* ln97xMemInit - initialize memory for Lance chip
*
* Using data in the control structure, setup and initialize the memory
* areas needed.  If the memory address is not already specified, then allocate
* cache safe memory.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS ln97xMemInit
    (
    LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */
    )
    {
    UINT32      sz;             /* temporary size holder */
    int         ix;
    LN_RMD *    pRmd;
    void *      pTemp;
    char *      pTempBuf;

    /* Remember register addresses */

    pDrvCtrl->pRdp   = LN_97X_RDP;
    pDrvCtrl->pRap   = LN_97X_RAP;
    pDrvCtrl->pReset = LN_97X_RST;
    pDrvCtrl->pBdp   = LN_97X_BDP;

    /***** Establish size of shared memory region we require *****/

    if ((int) pDrvCtrl->memAdrs != NONE)  /* specified memory pool */
	{
        /*
         * With a specified memory pool we want to maximize
         * lnRsize and lnTsize
         */

        sz = (pDrvCtrl->memSize - (RMD_SIZ + TMD_SIZ + sizeof (LN_IB)))
               / ((2 * LN_BUFSIZ) + RMD_SIZ + TMD_SIZ);

        sz >>= 1;               /* adjust for roundoff */

        for (lnRsize = 0; sz != 0; lnRsize++, sz >>= 1)
            ;

        lnTsize = lnRsize;      /* lnTsize = lnRsize for convenience */
        }

    /* limit ring sizes to reasonable values */

    lnRsize = max (lnRsize, LN_RMD_MIN); /* 4 Rx buffers is reasonable min */
    lnRsize = min (lnRsize, LN_RMD_MAX); /* 128 Rx buffers is max for chip */
    lnTsize = max (lnTsize, LN_TMD_MIN); /* 4 Tx buffers is reasonable min */
    lnTsize = min (lnTsize, LN_TMD_MAX); /* 128 Tx buffers is max for chip */

    /* Add it all up */

    sz = (((1 << lnRsize) + 1) * RMD_SIZ) +
         (((1 << lnTsize) + 1) * TMD_SIZ) + IB_SIZ + 0x10;

⌨️ 快捷键说明

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