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

📄 dm9000xend.c

📁 bsp for px270 SCAL的bsp 已经调试通过 for vxworks5.5
💻 C
📖 第 1 页 / 共 3 页
字号:
** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR**/LOCAL STATUS dm9000Start    (    DM9000_END_DEVICE *pDrvCtrl    )    {    /* connect interrupt handler */	*((UINT32*)0x080000d0) = 0;   *((UINT32*)0x080000c0) = 0x00000008; /*   *((UINT32*)0x080000d0) |= 0x04000000; */    (void) intConnect (INUM_TO_IVEC((UINT32)pDrvCtrl->irq),                       (VOIDFUNCPTR) dm9000Int, (int)pDrvCtrl);         /* mark the interface -- up */	     /* reset the device */    dmfe_open(pDrvCtrl);        END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));         intEnable (pDrvCtrl->irq);     return (OK);    }/********************************************************************************* ns83902Send - the driver's actual output routine** This routine accepts outgoing packets from the snd queue, and then * gains exclusive access to the DMA (through a mutex semaphore),* then calls ns83902Transmit() to send the packet out onto the interface.** RETURNS: OK, or ERROR if the packet could not be transmitted.*/LOCAL STATUS dm9000Send    (    DM9000_END_DEVICE* pDrvCtrl,    M_BLK* pMblk    )    {    int	status;	    if ((END_FLAGS_GET(&pDrvCtrl->endObj) & (IFF_UP | IFF_RUNNING)) !=        (IFF_UP | IFF_RUNNING))        {                return (ERROR);        }            /* send packet out over interface */    if ((status = dmfe_start_xmit (pMblk, pDrvCtrl)) == OK)        {	        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);	}    else        {               /* update statistics */        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);        }    return status;        }/********************************************************************************* ns83902Ioctl - the driver's I/O control routine** Perform device-specific commands.** RETURNS: 0, or EINVAL if the command 'cmd' is not supported.*/LOCAL int dm9000Ioctl    (    DM9000_END_DEVICE* pDrvCtrl,    int			cmd,    caddr_t		data        )    {    int 		error = 0;    long		value;    int			saveFlags;        switch ((UINT)cmd)	{        case EIOCSADDR:	    if (data == NULL)		return (EINVAL);            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->endObj),		   END_HADDR_LEN(&pDrvCtrl->endObj));                        break;        case EIOCGADDR:	    if (data == NULL)		return (EINVAL);            bcopy ((char *)END_HADDR(&pDrvCtrl->endObj), (char *)data,		    END_HADDR_LEN(&pDrvCtrl->endObj));            break;        case EIOCSFLAGS:	    value = (long) data;	    if( value < 0 )		{		value = -value;		value--;		END_FLAGS_CLR (&pDrvCtrl->endObj, value);		}	    else		{		END_FLAGS_SET (&pDrvCtrl->endObj, value);		}	    saveFlags = DRV_FLAGS_GET();	    if (DRV_FLAGS_GET() != saveFlags && 	           (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_UP))		{		END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING);				}            break;        case EIOCGFLAGS:	    if (data == NULL)		error = EINVAL;	    else		*(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj);	    break;        case EIOCMULTIADD:                   /* move to mux */            error = dm9000MCastAddrAdd (pDrvCtrl, (char *)data);            break;        case EIOCMULTIDEL:                   /* move to mux */            error = dm9000MCastAddrDel (pDrvCtrl, (char *)data);            break;        case EIOCMULTIGET:                   /* move to mux */            error = dm9000MCastAddrGet (pDrvCtrl, (MULTI_TABLE *)data);            break;        case EIOCPOLLSTART:                  /* move to mux */            error = dm9000PollStart (pDrvCtrl);            break;        case EIOCPOLLSTOP:                   /* move to mux */            error = dm9000PollStop (pDrvCtrl);            break;                    case EIOCGMIB2:            if (data == NULL)                return (EINVAL);            bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data,                  sizeof(pDrvCtrl->endObj.mib2Tbl));            break;        default:            error = EINVAL;	}    return (error);    } /********************************************************************************* ns83902Stop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR*/LOCAL STATUS dm9000Stop    (    DM9000_END_DEVICE* pDrvCtrl    )    {    STATUS		result = OK;    dmfe_shutdown(pDrvCtrl);    /* Disable LAN interrupts */    intDisable (pDrvCtrl->irq);    return (result);    }/******************************************************************************** ns83902Unload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.*/LOCAL STATUS dm9000Unload    (    DM9000_END_DEVICE* pDrvCtrl    )    {    if (pDrvCtrl != NULL)        {        END_OBJECT_UNLOAD (&pDrvCtrl->endObj);        /* free resources */        }    return (OK);    }/********************************************************************************* ns83902MCastAddrAdd - add a multicast address*** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS dm9000MCastAddrAdd    (    DM9000_END_DEVICE*	pDrvCtrl,    char *		pAddr    )    {    int retVal;    retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr);    return ((retVal == OK) ? OK : ERROR);    }/********************************************************************************* ns83902MCastAddrDel - remove a multicast address*** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS dm9000MCastAddrDel    (    DM9000_END_DEVICE*	pDrvCtrl,    char *		pAddr    )    {    int 		retVal;    retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr);/*filter address     if (retVal == ENETRESET)        return dm9000AddrFilterSet (pDrvCtrl, pAddr, FALSE);*/    return ((retVal == OK) ? OK : ERROR);    }/********************************************************************************* ns83902MCastAddrGet - retreive current multicast address list*** RETURNS: OK on success; otherwise ERROR.*/LOCAL STATUS dm9000MCastAddrGet    (    DM9000_END_DEVICE*	pDrvCtrl,    MULTI_TABLE *	pTable    )    {    return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable));    }/********************************************************************************* ns83902PollStart - starting polling mode** RETURNS: OK, always.*/LOCAL STATUS dm9000PollStart    (    DM9000_END_DEVICE*	pDrvCtrl    )    {    int			intLevel;    intLevel = intLock();    /* disable all interrupts */    iow(pDrvCtrl, DMFE_IMR, IMR_PAR);    DRV_FLAGS_SET (DM9000_FLAG_POLL);    intUnlock (intLevel);    return (OK);        }/********************************************************************************* ns83902PollStop - stop polling mode** RETURNS: OK, always.*/LOCAL STATUS dm9000PollStop    (    DM9000_END_DEVICE*	pDrvCtrl    )    {    int			intLevel;    intLevel = intLock();    /* enable interrupts */    iow(pDrvCtrl, DMFE_IMR, IMR_PAR | IMR_PTM | IMR_PRM);    DRV_FLAGS_CLR(DM9000_FLAG_POLL);        intUnlock (intLevel);    return (OK);    }/********************************************************************************* ns83902PollSend - send a packet in polled mode** RETURNS: OK on success, EAGAIN on failure*/LOCAL STATUS dm9000PollSend    (    DM9000_END_DEVICE*	pDrvCtrl,    M_BLK*		pMblk    )    {    return (dm9000Send (pDrvCtrl, pMblk));    }/********************************************************************************* ns83902PollReceive - get a packet in polled mode** RETURNS: OK on success, EAGAIN on failure.*/LOCAL STATUS dm9000PollReceive    (    DM9000_END_DEVICE*	pDrvCtrl,    M_BLK*		pMblk    )    {    STATUS		nRetValue = OK;        return nRetValue;    }/********************************************************************************* ns83902Recv - read a packet off the interface ring buffer** ns83902Recv copies packets from local memory into an mbuf and hands it to* the next higher layer (IP or etherInputHook).** RETURNS: TRUE, or FALSE if the packet reception encountered errors.*/LOCAL void dm9000Recv    (    DM9000_END_DEVICE*	pDrvCtrl,    void*	pCluster,    int     RxLen    )    {      CL_BLK_ID		pClBlk;    M_BLK_ID		pMblk;    /* Process frame received */    if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)        {                netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pCluster);                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }	    /*     * OK we've got a spare, let's get an M_BLK_ID and marry it to the     * one in the ring.     */    if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) ==        NULL)        {        netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);        netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pCluster);                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, (char*)pCluster, RxLen, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);	    pMblk->mBlkHdr.mData 	= (char *)pCluster+2;    pMblk->mBlkHdr.mFlags 	|= M_PKTHDR;	/* set the packet header */    pMblk->mBlkHdr.mLen		= RxLen;		/* set the data len */    pMblk->mBlkPktHdr.len 	= RxLen;		/* set the total len */	        /* Call the upper layer's receive routine. */ /*   printf("iplen = %d, %d, len = %d\n\r", pMblk->mBlkHdr.mData[18], pMblk->mBlkHdr.mData[19],pMblk->mBlkPktHdr.len);*/    END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);cleanRXD:    return;    }/********************************************************************************* ns83902Restart - restart chip after receive ring buffer overflow** This routine is called from an isr handler that deals with a receive DMA* overflow condition.  It gets access to the remote DMA, cleans up NIC* registers and defers work to task context to empty the receive ring buffers.** RETURNS: N/A.*/LOCAL void dm9000Restart    (    DM9000_END_DEVICE*	pDrvCtrl,    UINT8		cr    )    {    }/********************************************************************************* ns83902Int - The driver's interrupt handler** This function clears the cause of the device interrupt(s) and then acts* on the individual possible causes.  The primary goal of this routine is to* minimize the time spent in it.  This is accomplished by deferring processing* to the netTask via the netJobAdd() function.** Note that in case the receiver overruns, we promptly mark the interface as* "down" and leave error handling to task-level.   This is in case netTask* is in the midst of DMA activity, we must allow it to complete.  The receive* handler will give up when it discovers the interface is down, which will* then allow netTask to run our OVW handler.  This provides orderly error * recovery.** RETURNS: N/A.*/LOCAL void dm9000Int    (    DM9000_END_DEVICE*	pDrvCtrl    ){/*	logMsg("enter intr\n\r",1,2,3,4,5,6); */	*((UINT32*)0x080000d0) = 0;   *((UINT32*)0x080000c0) = 0x0;   *((UINT32*)0x40e00048) = 0x1;/*清除沿检测状态位*/	dmfe_interrupt(pDrvCtrl);   *((UINT32*)0x080000c0) = 0x00000008;}static voiddmfe_reset(DM9000_END_DEVICE *pDrvCtrl){	/* RESET device */	DM9000_outb(DMFE_NCR, pDrvCtrl->ioaddr);/*将控制和状态寄存器地址写入pDrvCtrl*/       taskDelay(1);	/* delay 100us */	DM9000_outb(NCR_RST, pDrvCtrl->io_data);/*软件复位和自动清除写入pDrvCtrl*/       taskDelay(1);		/* delay 100us */}/*  Search DM9000 board, allocate space and register it*/static intdmfe_probe( DM9000_END_DEVICE *pDrvCtrl){	static int ret = OK;	unsigned long base;	UINT32 id_val;	UINT16 i;		pDrvCtrl->ioaddr = CONFIG_DM9K_BASE;	pDrvCtrl->io_data = CONFIG_DM9K_BASE + 4;	pDrvCtrl->irq = IRQ_DM9k;           /*modify */		dmfe_reset(pDrvCtrl);		base = CONFIG_DM9K_BASE;	#if 1	/* try two times, DM9000 sometimes gets the first read wrong */	for (i = 0; i < 2; i++) {		DM9000_outb(DMFE_VIDL, base);/*卖主ID低字节地址*/		id_val = DM9000_inb(base + 4);		DM9000_outb(DMFE_VIDH, base);/*卖主ID高字节地址*/		id_val |= DM9000_inb(base + 4) << 8;		DM9000_outb(DMFE_PIDL, base);/*产品ID的低字节*/		id_val |= DM9000_inb(base + 4) << 16;		DM9000_outb(DMFE_PIDH, base);/*产品ID的高字节*/		id_val |= DM9000_inb(base + 4) << 24;		if (id_val == DM9000_ID)			break;		printf("%s: Uhm, wrong id 0x%08x\n", CARDNAME, id_val);		ret = ERROR;	}	if (id_val != DM9000_ID) {		printf("%s: wrong id: 0x%08x\n", CARDNAME, id_val);		ret = ERROR;			}	#endif	return ret;}/*

⌨️ 快捷键说明

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