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

📄 ln7990end.c

📁 7990驱动编程
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************* ln7990RestartSetup - setup memory descriptors and turn on chip** Initializes all the shared memory structures and turns on the chip.*/LOCAL STATUS ln7990RestartSetup    (    LN7990END_DEVICE *pDrvCtrl    )    {    int 	rsize;    int 	tsize;    ln_tmd * 	pTmd;    void * 	pTemp;    /* reset the device */    ln7990Reset (pDrvCtrl);    /* setup Rx buffer descriptors  - align on 000 boundary */    rsize = pDrvCtrl->rringLen;    pDrvCtrl->pRring = (ln_rmd *) ( ( (int)pDrvCtrl->pRring + 7) & ~7);        /*      * setup Tx buffer descriptors  -      *      save unaligned location and align on 000 boundary      */    pTmd = pDrvCtrl->pTring;    tsize = pDrvCtrl->tringLen;    pDrvCtrl->pTring = (ln_tmd *) ( ( (int)pDrvCtrl->pTring + 7) & ~7);    /* setup the initialization block */    pDrvCtrl->ib = (ln_ib *)pDrvCtrl->pShMem;    /* HELP */    swab ((char *) END_HADDR(&pDrvCtrl->end), pDrvCtrl->ib->lnIBPadr, 6);    CACHE_PIPE_FLUSH ();    pTemp = LN_CACHE_VIRT_TO_PHYS (pDrvCtrl->pRring);   /* point to Rx ring */    LN_ADDR_TO_IB_RMD (pTemp, pDrvCtrl->ib, rsize);    pTemp = LN_CACHE_VIRT_TO_PHYS (pDrvCtrl->pTring);   /* point to Tx ring */    LN_ADDR_TO_IB_TMD (pTemp, pDrvCtrl->ib, tsize);    DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);    /* reconfigure the device */    ln7990Config (pDrvCtrl);    return (OK);     }     /********************************************************************************* ln7990Restart - restart the device after a fatal error** This routine takes care of all the messy details of a restart.  The device* is reset and re-initialized.  The driver state is re-synchronized.*/LOCAL void ln7990Restart    (    LN7990END_DEVICE *pDrvCtrl    )    {    ln7990Reset (pDrvCtrl);    ln7990RestartSetup (pDrvCtrl);    /* set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->end,                    IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST                    | IFF_MULTICAST);    }/******************************************************************************** ln7990Config - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** NOMANUAL*/LOCAL void ln7990Config    (    LN7990END_DEVICE *pDrvCtrl    )    {    u_short stat;    void* pTemp;    int timeoutCount = 0;    ln_rmd *pRmd;    ln_tmd *pTmd;    int ix;    /* Set promiscuous mode if it's asked for. */    if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC)        {        DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode on!\n",                 1, 2, 3, 4, 5, 6);                /* chip will be in promiscuous mode */                pDrvCtrl->ib->lnIBMode = 0x8000;        }    else        {        DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode off!\n",                 1, 2, 3, 4, 5, 6);        pDrvCtrl->ib->lnIBMode = 0; /* chip will be in normal receive mode */        }        CACHE_PIPE_FLUSH ();    ln7990CsrWrite (pDrvCtrl, 0, lncsr_STOP);     /* set the stop bit */    /* Set up address filter for multicasting. */	    if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0)	{	ln7990AddrFilterSet (pDrvCtrl);	}    ln7990CsrWrite (pDrvCtrl, 3, pDrvCtrl->csr3B);    pRmd = pDrvCtrl->pRring;    for (ix = 0; ix < pDrvCtrl->rringSize; ix++, pRmd++)        {        pRmd->rbuf_bcnt = -(LN_BUFSIZ);		/* neg of buffer byte count */        LN_CLEAN_RXD (pRmd);        }    pDrvCtrl->rmdIndex = 0;        pTmd = pDrvCtrl->pTring;    for (ix = 0; ix < pDrvCtrl->tringSize; ix++, pTmd++)        {        pTmd->tbuf_bcnt = 0;			/* no message byte count yet */        pTmd->tbuf_err = 0;			/* no error status yet */        LN_TMD_CLR_ERR (pTmd);        }        pDrvCtrl->tmdIndex = 0;    pDrvCtrl->tmdIndexC = 0;        /* Point the device to the initialization block */    pTemp = LN_CACHE_VIRT_TO_PHYS (pDrvCtrl->ib);    ln7990CsrWrite (pDrvCtrl, 2,		       (u_short)(((u_long)pTemp >> 16) & 0x000000ff));    ln7990CsrWrite (pDrvCtrl, 1, (u_long) pTemp);    ln7990CsrWrite (pDrvCtrl, 0, lncsr_INIT);    /* init chip (read IB) */    /* hang until Initialization DONe, ERRor, or timeout */    while (((stat = ln7990Csr0Read (pDrvCtrl)) &	    (lncsr_IDON | lncsr_ERR)) == 0)        {        if (timeoutCount++ > 0x10000)	    break;	DELAY (1000 * timeoutCount);        }    DRV_LOG (DRV_DEBUG_LOAD, "Timeoutcount %d\n", timeoutCount,             2, 3, 4, 5, 6);    /* log chip initialization failure */    if ((stat & lncsr_ERR) || (timeoutCount >= 0x10000))        {	DRV_LOG (DRV_DEBUG_LOAD, "%s: Device initialization failed\n",                 (int)END_DEV_NAME(&pDrvCtrl->end), 0,0,0,0,0);        return;        }    if (!(pDrvCtrl->flags & LS_POLLING))	{	ln7990CsrWrite (pDrvCtrl, 0, lncsr_INEA | lncsr_STRT);	}    else	{	ln7990CsrWrite (pDrvCtrl, 0, lncsr_STRT);	}    }/******************************************************************************** ln7990AddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the ln7990AddrAdd() routine) and sets the* device's filter correctly.** NOMANUAL*/LOCAL void ln7990AddrFilterSet    (    LN7990END_DEVICE *pDrvCtrl    )    {    ETHER_MULTI* pCurr;    ln_ib *pIb;    u_char *pCp;    u_char c;    u_long crc;    int len;    int count;    pIb = pDrvCtrl->ib;    LN_ADDRF_CLEAR (pIb);    pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);    while (pCurr != NULL)	{	/*	 * One would think, given the AM7990 document's polynomial	 * of 0x04c11db6, that this should be 0x6db88320 (the bit	 * reversal of the AMD value), but that is not right.  See	 * the BASIC listing: bit 0 (our bit 31) must then be set.	 */	pCp = (unsigned char *)&pCurr->addr;	crc = 0xffffffff;	for (len = 6; --len >= 0;)	    {	    c = *pCp++;	    for (count = 0; count < 8; count++)		{		if ((c & 0x01) ^ (crc & 0x01))		    {		    crc >>= 1;		    crc = crc ^ 0xedb88320;		    }		else		    {		    crc >>= 1;		    }		c >>= 1;		}	    }	/* Just want the 6 most significant bits. */	crc = crc >> 26;	/* Turn on the corresponding bit in the filter. */	LN_ADDRF_SET (pIb, crc);	pCurr = END_MULTI_LST_NEXT(pCurr);	}    }/********************************************************************************* ln7990PollReceive - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.*/LOCAL STATUS ln7990PollReceive    (    LN7990END_DEVICE *pDrvCtrl,    M_BLK_ID pMblk    )    {    ln_rmd *pRmd;    u_short stat;    u_long phys;    char* pPacket;    int len;    DRV_LOG (DRV_DEBUG_POLL_RX, "PRX b\n", 1, 2, 3, 4, 5, 6);    /* Read the device status register */    stat = ln7990Csr0Read (pDrvCtrl);    /* Check for errors */    if (stat & (lncsr_BABL | lncsr_MISS | lncsr_MERR))        {        ++pDrvCtrl->csr0Errs;        DRV_LOG (DRV_DEBUG_POLL_RX, "PRX bad error\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);        /* restart chip on fatal error */        if (stat & lncsr_MERR)        /* memory error */            {	    END_FLAGS_CLR (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));            DRV_LOG (DRV_DEBUG_POLL_RX, "PRX restart\n", 1, 2, 3, 4, 5, 6);            ln7990Restart (pDrvCtrl);	    return (EAGAIN);            }        }    /*     * clear receive interrupts, and clear any errors that may be set.     */    ln7990CsrWrite (pDrvCtrl, 0, ((stat &            (lncsr_BABL|lncsr_CERR|lncsr_MISS|lncsr_MERR|             lncsr_RINT))));    /* Packet must be checked for errors. */    pRmd = ln7990FullRMDGet (pDrvCtrl);    if (pRmd == NULL)	{        DRV_LOG (DRV_DEBUG_POLL_RX, "PRX no rmd\n", 1, 2, 3, 4, 5, 6);	return (EAGAIN);	}    if  (LN_RMD_ERR (pRmd))	{	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);        DRV_LOG (DRV_DEBUG_POLL_RX, "PRX bad rmd\n", 1, 2, 3, 4, 5, 6);	goto cleanRXD;	}    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);    len = LN_PKT_LEN_GET (pRmd);		/* get packet length */    /* Get pointer to packet */    LN_RMD_TO_ADDR (pDrvCtrl->memBase, pRmd, phys);    pPacket = (char *) LN_CACHE_PHYS_TO_VIRT (phys);    LN_CACHE_INVALIDATE (pPacket, len);   /* make the packet coherent */    /* Upper layer provides the buffer. */    if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT)))	{        DRV_LOG (DRV_DEBUG_POLL_RX, "PRX bad mblk len:%d flags:%d\n",                 pMblk->mBlkHdr.mLen, pMblk->mBlkHdr.mFlags, 3, 4, 5, 6);	return (EAGAIN);	}    pMblk->mBlkHdr.mData += pDrvCtrl->offset;    bcopy (pPacket, pMblk->mBlkHdr.mData, len);    pMblk->mBlkHdr.mLen = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;    /* Done with descriptor, clean up and give it to the device. */    cleanRXD:    LN_CLEAN_RXD (pRmd);    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    /* Advance our management index */    pDrvCtrl->rmdIndex = (pDrvCtrl->rmdIndex + 1) & (pDrvCtrl->rringSize - 1);    DRV_LOG (DRV_DEBUG_POLL_RX, "PRX ok\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* ln7990PollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.*/LOCAL STATUS ln7990PollSend    (    LN7990END_DEVICE* pDrvCtrl,    M_BLK_ID pMblk    )    {    ln_tmd*	pTmd;    void*       pTemp;    int         len;    int         oldLevel;    u_short	stat;    char*       pBuf = NULL;    char*       pOrig = NULL;        DRV_LOG (DRV_DEBUG_POLL_TX, "PTX b\n", 1, 2, 3, 4, 5, 6);    /* See if next TXD is available */    pTmd = pDrvCtrl->pTring + pDrvCtrl->tmdIndex;    LN_CACHE_INVALIDATE (pTmd, TMD_SIZ);    if ((pTmd->tbuf_stat & lntmd1_OWN) || (((pDrvCtrl->tmdIndex + 1) &        (pDrvCtrl->tringSize - 1)) == pDrvCtrl->tmdIndexC))        {        DRV_LOG (DRV_DEBUG_POLL_TX, "Out of tmds.\n", 1, 2, 3, 4, 5, 6);        if (!pDrvCtrl->txCleaning)            netJobAdd ((FUNCPTR)ln7990ScrubTRing, (int) pDrvCtrl, 0, 0, 0, 0);       return (EAGAIN);        }    /*     * If we don't have alignment issues then we can transmit     * directly from the M_BLK otherwise we have to copy.     */        if ((pDrvCtrl->offset == 0) && (pMblk->mBlkHdr.mNext == NULL))        {        len = max (ETHERSMALL, pMblk->m_len);        LN_TMD_BUF_TO_ADDR(pTmd, pTemp, pMblk->m_data);        DRV_LOG (DRV_DEBUG_POLL_TX, "offset == 0.\n", 1, 2, 3, 4, 5, 6);        }    else        {        DRV_LOG (DRV_DEBUG_POLL_TX, "offset != 0.\n", 1, 2, 3, 4, 5, 6);        pOrig = pBuf = netClusterGet(pDrvCtrl->end.pNetPool,                       

⌨️ 快捷键说明

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