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

📄 if_seeq.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	{	/* write direction: wait until buffer writing is complete. */	if (seeqFlushFIFO (pDrvCtrl) != OK)	    return (ERROR);	}    /* Set DMA address */    SEEQ_WRITE (pDev->pDma, addr);    return (OK);    }/******************************************************************************** seeqChipReset - hardware reset of chip (stop it)** NOMANUAL*/void seeqChipReset    (    int unit    )    {    int i;    int oldLevel;    DRV_CTRL *pDrvCtrl = &drvCtrl[unit];    SEEQ_DEVICE *pDev;    volatile UCHAR *bwind;    /* Sanity check the unit number */    if (unit < 0 || unit >= MAX_UNITS)	return;#ifdef DEBUG    if (seeqDebug)	logMsg ("seeqChipReset(%d)\n", unit, 0, 0, 0, 0, 0);#endif    pDrvCtrl->flags = 0;    pDrvCtrl->txCount = 0;    /* Reset the chip */    pDev = pDrvCtrl->devAdrs;    SEEQ_WRITE (pDev->pCfg1, 0);    SEEQ_WRITE (pDev->pCfg2, SEEQ_CONF2_RESET);    /* Delay at least 4us */    taskDelay (1);    /* Check status register for 0x5800 */    if (SEEQ_READ(pDev->pStat) != 0x5800)	{	logMsg ("seeq: probe at 0x%x failed, got 0x%04x\n",		(int) pDrvCtrl->devAdrs->pCmd, SEEQ_READ(pDev->pStat),		0, 0, 0, 0);	}    /* lock interrupts */    oldLevel = intLock ();    /* Program the interrupt vector */    SEEQ_WRITE (pDev->pCfg1, ((SEEQ_READ(pDev->pCfg1) & 0xfff0)				| SEEQ_CONF1_IVEC));    SEEQ_WRITE (pDev->pBwind, pDrvCtrl->inum);    /* Program station addr 0 w/ our e-net addr */    /* Turn Tx, Rx and DMA off, then ack any interrupts */    SEEQ_WRITE (pDev->pCmd, (SEEQ_CMD_FIFO_WRITE | SEEQ_CMD_ALL_OFF));    SEEQ_WRITE (pDev->pCmd, (SEEQ_CMD_FIFO_WRITE | SEEQ_CMD_ALL_OFF			    | SEEQ_CMD_ALL_ACK));    /* Select address 0 */    SEEQ_WRITE (pDev->pCfg1, ((SEEQ_READ(pDev->pCfg1) & 0xfff0) | 0));    /* Get byte pointer to buffer window */    bwind = ((volatile UCHAR *) pDev->pBwind) + SEEQ_LSB_OFFSET;    /* Program the ethernet address */    for (i = 0; i < 6; ++i)	SEEQ_WRITE_BYTE (bwind, ((UCHAR *)pDrvCtrl->idr.ac_enaddr)[i]);    /*     * Configure the local memory buffer to allow half of the     * space for transmit and half for receive.     */    pDrvCtrl->tea = 0x7f;    pDrvCtrl->rea = 0xffff;    pDrvCtrl->rxNext = (pDrvCtrl->tea + 1) << 8;    pDrvCtrl->txEnd = ((pDrvCtrl->tea + 1) << 8) - 1;    pDrvCtrl->txNext = 0;    pDrvCtrl->txCurr = 0;    pDrvCtrl->txLow = 0;    SEEQ_WRITE(pDev->pCfg1, (*pDev->pCfg1 & 0xfff0) | SEEQ_CONF1_TXEND);    SEEQ_WRITE(pDev->pBwind, pDrvCtrl->tea);    SEEQ_WRITE(pDev->pTxptr, pDrvCtrl->txNext);    SEEQ_WRITE(pDev->pRxptr, pDrvCtrl->rxNext);    SEEQ_WRITE(pDev->pRxend, pDrvCtrl->rea);    /*     * Config1 register setup:     *     * Specific Addr 0: Enabled     * Specific Addr 1: Disabled     * Specific Addr 2: Disabled     * Specific Addr 3: Disabled     * Specific Addr 4: Disabled     * Specific Addr 5: Disabled     * DMA Burst Length: 1 byte     * DMA Burst Interval: continuous     * MatchMode: Specific Addresses + Broadcast Addr     */    *pDev->pCfg1	= SEEQ_CONF1_ADDR0_EN			| SEEQ_CONF1_RX_SPEC_BROAD			| SEEQ_CONF1_DMA_BURST_INTERVAL_0;    /*     * Config2 register setup:     *     * select byte swapping, or not. Yes for BIG_ENDIAN     * AutoUpdate REA:  Disabled.     * Receive While Transmitting: Enabled.     * CRC ErrorEnable:	CRC Error packets not accepted.     * Dribble Error Enable: Dribble packets not accepted.     * Pass Long/Short Enable: Neither long or short packets accepted.     * Preamble Select:  Std 802.3 64 bit preamble selected.     * RecCRC: CRC is stripped from incoming packets.     * XmitNoCRC: Outgoing packets have CRC appended.     * Loopback:  Loopback disabled.     * CTRLO: CTRL0 pin is low.     * RESET: Not asserted.     */    SEEQ_WRITE (pDev->pCfg2, SEEQ_CFG2_BSWAP);    /*     * Configure for RX and TX off and interrupts disabled.     * Ack any pending interrupts.     */    SEEQ_WRITE (pDev->pCmd, (SEEQ_CMD_RX_OFF | SEEQ_CMD_TX_OFF				    | SEEQ_CMD_ALL_ACK));    intUnlock (oldLevel);    }/******************************************************************************** seeqTxReset - Reset the TX** NOMANUAL*/void seeqTxReset    (    int unit    )    {    int oldLevel;    DRV_CTRL *pDrvCtrl = &drvCtrl[unit];    SEEQ_DEVICE *pDev;    /* Sanity check the unit number */    if (unit < 0 || unit >= MAX_UNITS)	return;#ifdef DEBUG    if (seeqDebug)	logMsg ("seeqTxReset(%d)\n", unit, 0, 0, 0, 0, 0);#endif    pDev = pDrvCtrl->devAdrs;    oldLevel = intLock ();    /* Report an error */    ++pDrvCtrl->idr.ac_if.if_oerrors;    /* Recover - disable the TX */    SEEQ_WRITE (pDev->pCmd, ((SEEQ_READ(pDev->pStat) & SEEQ_STAT_CMD_MASK)				    | SEEQ_CMD_TX_OFF));    pDrvCtrl->txNext = 0;    pDrvCtrl->txCurr = 0;    pDrvCtrl->txCount = 0;    SEEQ_WRITE (pDev->pTxptr, 0);    /* Ack the buffer and TX interrupts */    SEEQ_WRITE (pDev->pCmd, ((SEEQ_READ(pDev->pStat) & SEEQ_STAT_CMD_MASK)				    | SEEQ_CMD_TX_ACK | SEEQ_CMD_BUF_ACK));    intUnlock (oldLevel);    }/******************************************************************************** seeqRxReset - Reset the RX** NOMANUAL*/void seeqRxReset    (    int unit    )    {    int oldLevel;    DRV_CTRL *pDrvCtrl = &drvCtrl[unit];    SEEQ_DEVICE *pDev;    /* Sanity check the unit number */    if (unit < 0 || unit >= MAX_UNITS)	return;#ifdef DEBUG    if (seeqDebug)	logMsg ("seeqRxReset(%d)\n", unit, 0, 0, 0, 0, 0);#endif    pDev = pDrvCtrl->devAdrs;    oldLevel = intLock ();    /* Report an error */    ++pDrvCtrl->idr.ac_if.if_ierrors;    /* Recover - disable the RX */    SEEQ_WRITE (pDev->pCmd, ((SEEQ_READ(pDev->pStat) & SEEQ_STAT_CMD_MASK)				    | SEEQ_CMD_RX_OFF));    pDrvCtrl->rxNext = (pDrvCtrl->tea + 1) << 8;    SEEQ_WRITE (pDev->pRxptr, pDrvCtrl->rxNext);    /* Ack the buffer and RX interrupts */    SEEQ_WRITE (pDev->pCmd, ((SEEQ_READ(pDev->pStat) & SEEQ_STAT_CMD_MASK)				    | SEEQ_CMD_RX_ACK | SEEQ_CMD_BUF_ACK				    | SEEQ_CMD_RX_ON ));    intUnlock (oldLevel);    }/******************************************************************************** seeqReset - reset the interface** Mark interface as inactive & reset the chip** NOMANUAL*/LOCAL void seeqReset    (    int unit    )    {    int oldLevel;    DRV_CTRL *pDrvCtrl = &drvCtrl[unit];    /* Sanity check the unit number */    if (unit < 0 || unit >= MAX_UNITS)	return;    oldLevel = intLock ();    /* Reset the chip */    SEEQ_WRITE (pDrvCtrl->devAdrs->pCfg1, 0);    SEEQ_WRITE (pDrvCtrl->devAdrs->pCfg2, SEEQ_CONF2_RESET);    /* Mark the interface as down */    pDrvCtrl->idr.ac_if.if_flags = 0;    intUnlock (oldLevel);    }/******************************************************************************** seeqReceive - handle receiving packets.** NOMANUAL*/LOCAL void seeqReceive    (    int unit    )    {    USHORT	nextFrame;    USHORT	headerStatus;    int		pktByteCnt = 0;    DRV_CTRL	*pDrvCtrl = &drvCtrl[unit];    SEEQ_DEVICE *pDev = pDrvCtrl->devAdrs;    /* If interface was shutdown, abort service request */    if (!(pDrvCtrl->idr.ac_if.if_flags & IFF_UP))	{	pDrvCtrl->flags &= ~SEEQ_RX_OUTSTANDING;	return;	}    if (!(pDrvCtrl->flags & SEEQ_RX_OUTSTANDING))	{#ifdef DEBUG	if (seeqDebug)	    logMsg ("seeq: no RX request outstanding\n",		    0, 0, 0, 0, 0, 0);#endif	return;	}    pDrvCtrl->flags &= ~SEEQ_RX_OUTSTANDING;    do	{	int i;	USHORT frameStatus;	USHORT frameLength;	USHORT tmp;	if (seeqSetDMARead(pDrvCtrl, pDrvCtrl->rxNext) != OK)	    {	    /* re-queue for later processing. */#ifdef DEBUG	    if (seeqDebug)		logMsg ("RX: Set DMA failed\n", 0, 0, 0, 0, 0, 0);#endif	    seeqRxReset (pDrvCtrl->unit);	    pDrvCtrl->flags |= SEEQ_RX_OUTSTANDING;	    netJobAdd ((FUNCPTR) seeqReceive, unit, 0, 0, 0, 0);	    break;	    }	nextFrame = SEEQ_READ (pDev->pBwind);	/* Get the header and frame status */	tmp = SEEQ_READ (pDev->pBwind);	headerStatus = tmp >> 8;	frameStatus = tmp & 0x00ff;	/*	 * Stop under any of the following conditions:	 *   The packet isn't done	 *   The next packet is this packet (looped back).	 */	if (!(frameStatus & SEEQ_RX_PSTAT_DONE)	    || (nextFrame == pDrvCtrl->rxNext))	    break;	if (nextFrame < pDrvCtrl->rxNext)	    {	    /* The receiver wrapped around */	    frameLength = (pDrvCtrl->rea+1) - pDrvCtrl->rxNext - 4		+ (nextFrame - (int)((pDrvCtrl->tea + 1)<<8));	    }	else	    {	    /* The frame is sequential, not wrapped */	    frameLength = nextFrame - pDrvCtrl->rxNext - 4;	    }	/* account for space consumed in the buffer. */	pktByteCnt += frameLength + 4;	if (pktByteCnt > 0x8000)	    {#ifdef DEBUG	    if (seeqDebug)		logMsg ("RX packet overflows\n", 0, 0, 0, 0, 0, 0);#endif	    seeqRxReset (pDrvCtrl->unit);	    break;	    }#ifdef DEBUG	if (seeqDebug)	    logMsg ("RX pkt: @ 0x%04x Frame 0x%02x Header 0x%02x len %4d nxt 0x%04x\n",		    pDrvCtrl->rxNext, frameStatus, headerStatus,		    frameLength, nextFrame, 0);#endif	if (frameStatus != SEEQ_RX_PSTAT_DONE)	    {	    /* one of the errors */	    if (frameStatus & SEEQ_RX_PSTAT_OVERSIZE)		++pDrvCtrl->idr.ac_if.if_ierrors;	    if (frameStatus & SEEQ_RX_PSTAT_CRC)		++pDrvCtrl->idr.ac_if.if_ierrors;	    if (frameStatus & SEEQ_RX_PSTAT_DRIBBLE)		++pDrvCtrl->idr.ac_if.if_ierrors;	    if (frameStatus & SEEQ_RX_PSTAT_SHORT)		++pDrvCtrl->idr.ac_if.if_ierrors;	    }	else	    {	    ETH_HDR	*pHdr = (ETH_HDR *) pDrvCtrl->rxBuf;	    char	*bufp = (char *) pDrvCtrl->rxBuf;	    /* Read in the entire packet */	    for (i = 0; i < frameLength/2; ++i)		{		((USHORT *) bufp)[i] = SEEQ_READ (pDev->pBwind);		}	    /* Get the last odd byte */	    if (frameLength & 1)		{		bufp[frameLength-1] = SEEQ_READ_BYTE (pDev->pBwind);		}	    /* call input hook if any */	    if ((etherInputHookRtn == NULL)		|| !(*etherInputHookRtn) (&pDrvCtrl->idr.ac_if,					  bufp, frameLength))		{		MBUF *pMbuf;		bufp += SIZEOF_ETHERHEADER;		frameLength -= SIZEOF_ETHERHEADER;		pMbuf = copy_to_mbufs (bufp, frameLength, 0,				       (IFNET *) &pDrvCtrl->idr.ac_if);		if (pMbuf != NULL)		    {		    do_protocol_with_type (ntohs (pHdr->ether_type), pMbuf,					   &pDrvCtrl->idr, frameLength);		    pDrvCtrl->idr.ac_if.if_ipackets++;		    }		}	    }	/* adjust circular buffer */

⌨️ 快捷键说明

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