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

📄 ln97xend.c

📁 VMware上运行vxWorks的BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
     */    if ((pMblk = mBlkGet(pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA))        == NULL)        {        netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);        netClFree (pDrvCtrl->endObj.pNetPool, pNewCluster);        DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);    len = LN_PKT_LEN_GET (pRmd);	/* get packet length */    LN_RMD_TO_ADDR (pRmd, pCluster);	/* Get pointer to packet */    pCluster -= pDrvCtrl->offset;        DRV_LOG (DRV_DEBUG_RX, "Packet @ 0x%X for %d bytes!\n", pCluster,             len, 3, 4, 5, 6);    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    /* make the packet data coherent */    LN_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, len);    pMblk->mBlkHdr.mData  += pDrvCtrl->offset;    pMblk->mBlkHdr.mLen   = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;    DRV_LOG (DRV_DEBUG_RX, "Calling upper layer!\n", 1, 2, 3, 4, 5, 6);    /* Deal with memory alignment. */    pNewCluster += pDrvCtrl->offset;    /* Give receiver a new buffer */    LN_RMD_BUF_TO_ADDR (pRmd, pTemp, pNewCluster);    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);cleanRXD:    /* clear status bits */    LN_CLEAN_RXD (pRmd);    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    /* Advance our management index */    pDrvCtrl->rmdIndex = (pDrvCtrl->rmdIndex + 1) & (pDrvCtrl->rringSize - 1);    return (OK);    }/********************************************************************************* lnSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine.  ** RETURNS: OK or ERROR.*/LOCAL STATUS ln97xSend    (    LN_97X_DRV_CTRL * 	pDrvCtrl,  /* device to be initialized */    M_BLK_ID 		pMblk      /* data to send */    )    {    LN_TMD *		pTmd;    UINT32		ltmd1;    void *       	pTemp;    char *       	pBuf;    char *       	pOrig;    int         	level;    int         	len = 0;    /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    if (!(pDrvCtrl->flags & LS_POLLING))        END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);    pTmd = pDrvCtrl->pTring + pDrvCtrl->tmdIndex;    DRV_LOG (DRV_DEBUG_TX, "Send : index %d tmd = 0x%X\n",             pDrvCtrl->tmdIndex, (int)pTmd, 3, 4, 5, 6);    LN_CACHE_INVALIDATE (pTmd, TMD_SIZ);    ltmd1 = PCI_SWAP (pTmd->tBufTmd1);        if ((ltmd1 & TMD1_OWN) ||	(((pDrvCtrl->tmdIndex + 1) & (pDrvCtrl->tringSize - 1))         == pDrvCtrl->tmdIndexC))        {        if (!(pDrvCtrl->flags & LS_POLLING))            END_TX_SEM_GIVE (&pDrvCtrl->endObj);        /* Are we still on the first chunk? */        DRV_LOG (DRV_DEBUG_TX, "Out of TMDs!\n", 1, 2, 3, 4, 5, 6);        level = intLock ();        pDrvCtrl->txBlocked = TRUE;        intUnlock (level);        return (END_ERR_BLOCK);        }    DRV_LOG (DRV_DEBUG_TX, "before cluster get %d %d\n",             pDrvCtrl->endObj.pNetPool,             pDrvCtrl->pClPoolId, 3, 4, 5, 6);    pOrig = pBuf = netClusterGet (pDrvCtrl->endObj.pNetPool,                                  pDrvCtrl->pClPoolId);    DRV_LOG (DRV_DEBUG_TX, "after cluster get pBuf = 0x%X\n",             (int)pBuf, 2, 3, 4, 5, 6);    if (pBuf == NULL)        {        netMblkClChainFree(pMblk);        return (ERROR);        }    pBuf += pDrvCtrl->offset;	/* take care of the alignment */    len = netMblkToBufCopy (pMblk, pBuf, NULL);    netMblkClChainFree(pMblk);    LN_TMD_BUF_TO_ADDR(pTmd, pTemp, pBuf);    len = max (len, ETHERSMALL);    pTmd->tBufTmd2 = 0;         /* clear buffer error status */    ltmd1 = TMD1_STP | TMD1_ENP | TMD1_CNST;    ltmd1 |= (TMD1_BCNT_MSK & -len);    pTmd->tBufTmd1 = PCI_SWAP (ltmd1);    CACHE_PIPE_FLUSH ();    LN_CACHE_INVALIDATE (pTmd, TMD_SIZ);    ltmd1 |= TMD1_OWN;    DRV_LOG (DRV_DEBUG_TX, "TMD1 = 0x%X\n", ltmd1, 2, 3, 4, 5, 6);        /* write to actual register */    pTmd->tBufTmd1 = PCI_SWAP (ltmd1);    pDrvCtrl->freeRtn [pDrvCtrl->tmdIndex] = (FUNCPTR)netClFree;    pDrvCtrl->freeData [pDrvCtrl->tmdIndex].arg1 = pDrvCtrl->endObj.pNetPool;    pDrvCtrl->freeData [pDrvCtrl->tmdIndex].arg2 = pOrig;    /* Advance our management index */    pDrvCtrl->tmdIndex = (pDrvCtrl->tmdIndex + 1) & (pDrvCtrl->tringSize - 1);    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    if (lnKickStartTx)        {        if (!(pDrvCtrl->flags & LS_POLLING))            ln97xCsrWrite (pDrvCtrl, 0, (CSR0_INTMASK | CSR0_TDMD));        else            ln97xCsrWrite (pDrvCtrl, 0, CSR0_TDMD);        }    if (!(pDrvCtrl->flags & LS_POLLING))        END_TX_SEM_GIVE (&pDrvCtrl->endObj);    /* Bump the statistic counter. */    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);    return (OK);    }/********************************************************************************* ln97xIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS OK or ERROR value*/LOCAL int ln97xIoctl    (    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */    int 		cmd,	 /* ioctl command to execute */    caddr_t 		data	 /* date to get or set */    )    {    long 		value;    int 		error = 0;    switch (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--;		/* HELP: WHY ??? */		END_FLAGS_CLR (&pDrvCtrl->endObj, value);		}	    else		{		END_FLAGS_SET (&pDrvCtrl->endObj, value);		}	    ln97xConfig (pDrvCtrl);            break;        case EIOCGFLAGS:	    *(int *)data = END_FLAGS_GET (&pDrvCtrl->endObj);            break;	case EIOCPOLLSTART:	    error = ln97xPollStart (pDrvCtrl);	    break;	case EIOCPOLLSTOP:	    error = ln97xPollStop (pDrvCtrl);	    break;        case EIOCGMIB2:            if (data == NULL)                return (EINVAL);            bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data,                  sizeof(pDrvCtrl->endObj.mib2Tbl));            break;        case EIOCGFBUF:            if (data == NULL)                return (EINVAL);            *(int *)data = LN_MIN_FBUF;            break;        case EIOCGMWIDTH:            if (data == NULL)                return (EINVAL);            *(int *)data = pDrvCtrl->memWidth;            break;        case EIOCGHDRLEN:            if (data == NULL)                return (EINVAL);            *(int *)data = 14;            break;        default:            error = EINVAL;        }    return (error);    }/********************************************************************************* ln97xReset - hardware reset of chip (stop it)** This routine is responsible for resetting the device and switching into* 32 bit mode.** RETURNS: OK/ERROR*/LOCAL int ln97xReset    (    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    )    {    UINT32 		resetTmp;    /* Enable 32 bit access by doing a 32 bit write */    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRdp, 0);    ln97xCsrWrite (pDrvCtrl, CSR(0), CSR0_STOP);        /* Generate a soft-reset of the controller */    SYS_IN_LONG(pDrvCtrl, pDrvCtrl->pReset, resetTmp);    /* This isn't a real test - it just stops the compiler ignoring the read */    if (resetTmp == 0x12345678)	return (ERROR);    ln97xBcrWrite (pDrvCtrl, BCR(20), BCR20_SWSTYLE_PCNET);    /* autoselect port tye - 10BT or AUI */    ln97xBcrWrite (pDrvCtrl, BCR(2), BCR2_AUTO_SELECT);     /* read BCR */    resetTmp = ln97xBcrRead (pDrvCtrl, BCR(20));    return (OK);    }/********************************************************************************* ln97xCsrWrite - select and write a CSR register** This routine selects a register to write, through the RAP register and* then writes the CSR value to the RDP register.** RETURNS: N/A*/LOCAL void ln97xCsrWrite    (    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */    int 		reg,	 /* CSR register to select */    UINT32 		value	 /* CSR value to write */    )    {    int 		level;    level = intLock ();    /* select CSR */    reg &= 0xff;    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg));    CACHE_PIPE_FLUSH ();    value &=0xffff;    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRdp, PCI_SWAP (value));    CACHE_PIPE_FLUSH ();    intUnlock (level);    }/********************************************************************************* ln97xCsrRead - select and read a CSR register** This routine selects a register to read, through the RAP register and* then reads the CSR value from the RDP register.** RETURNS: N/A*/LOCAL UINT32 ln97xCsrRead    (    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */    int			reg  	 /* register to select */    )    {    int 		level;    UINT32 		result;        level = intLock ();    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg));    CACHE_PIPE_FLUSH ();    SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pRdp, result);    intUnlock (level);    return (PCI_SWAP (result) & 0x0000FFFF);    }/********************************************************************************* ln97xBcrWrite - select and write a BCR register** This routine writes the bus configuration register. It first selects the* BCR register to write through the RAP register and then it writes the value* to the BDP register.** RETURNS: N/A*/LOCAL void ln97xBcrWrite    (    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */    int 		reg,     /* BCR register to select */    UINT32 		value    /* BCR value to write */    )    {    int 		level;    reg &= 0xff;    value &=0xffff;    level = intLock ();    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP(reg));    CACHE_PIPE_FLUSH ();    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pBdp, PCI_SWAP(value));    intUnlock (level);    }/********************************************************************************* ln97xBcrRead - select and read a BCR register** This routine reads the bus configuration register. It first selects the* BCR register to read through the RAP register and then it reads the value* from the BDP register.** RETURNS: N/A*/LOCAL UINT32 ln97xBcrRead    (    LN_97X_DRV_CTRL *	pDrvCtrl,		/* driver control */    int		reg			/* register to select */    )

⌨️ 快捷键说明

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