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

📄 if_cs.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Issue the command to read the offset within the EEPROM */    csPacketPageW (pCs, CS_PKTPG_EEPROM_CMD, offset | CS_EEPROM_CMD_READ);    /* Wait until the command is completed */    for (ix=0; ix<CS_MAXLOOP; ix++)	if (!(csPacketPageR (pCs, CS_PKTPG_SELF_ST) & CS_SELF_ST_SI_BUSY))	    break;    if (ix == CS_MAXLOOP)	{	printf ("\ncs0 - Can not read from EEPROM\n");	return (ERROR);	}    /* Get the EEPROM data from the EEPROM data register */    *pValue = csPacketPageR (pCs, CS_PKTPG_EEPROM_DATA);     return (OK);    }/********************************************************************************* csInit - resets and then initializes the CS8900 chip** This routine is a major entry point and is called to initialize this network* interface driver.  This routine may be called several times for each* operating system reboot to dynamically bring the network interface driver* to an up and running state.  This routine is called by the protocol stack,* the set_if_addr() routine, and the csIoctl() routine.** RETURNS: OK or ERROR*/LOCAL STATUS csInit    (    int unit    )    {    FAST CS_SOFTC *pCs = &cs_softc[unit];    if (unit >= MAXUNITS)	return (ERROR);    /* Mark the interface as down */    pCs->arpCom.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);    /* Enable debugging */    /* pCs->arpCom.ac_if.if_flags |= IFF_DEBUG; */    csError (pCs, "Initializing interface");    /* Reset the chip */    if (csChipReset (pCs) == ERROR)	{	csError (pCs, "Can not reset the chip");	return (ERROR);	}    /* Initialize the chip */    csChipInit (pCs);    /* Mark the interface as up and running */    pCs->arpCom.ac_if.if_flags |= (IFF_UP | IFF_RUNNING);    return (OK);    }/********************************************************************************* csReset - resets the CS8900 chip.** This routine is a major entry point and is called by the protocol stack to* shut down this network interface driver.  This routine may be called several* times for each operating system reboot to dynamically bring the network* interface driver to a non-running state.** RETURNS: N/A*/LOCAL void csReset    (    int unit    )    {    FAST CS_SOFTC *pCs = &cs_softc[unit];    if (unit >= MAXUNITS)	return;    csError (pCs, "Resetting interface");    /* Mark the interface as down */    pCs->arpCom.ac_if.if_flags &= ~IFF_RUNNING;    /* Reset the chip */    csChipReset (pCs);    }/********************************************************************************* csIoctl - ioctl for interface** This routine is a major entry point and is called by the protocol stack to* modify characteristics of this network interface driver.  There are many* network interface ioctl commands, but this driver only supports two of them:* Set Interface Address and Set Interface Flags.** RETURNS: OK if successful, otherwise errno.*/LOCAL int csIoctl    (    struct ifnet *pIf,    int command,    char *pData    )    {    FAST CS_SOFTC *pCs = &cs_softc[pIf->if_unit];    int result         = OK;  /* Assume everything will go OK */    int state          = splnet();    switch (command)	{	case SIOCSIFADDR:  /* Set interface address (IP address) */	    csError (pCs, "Ioctl: Set interface address");	    result = set_if_addr (pIf, pData, (UCHAR *)pCs->arpCom.ac_enaddr);	    /* Note: set_if_addr () calls csInit() */	    break;	case SIOCSIFFLAGS:  /* Set interface flags */	    csError (pCs, "Ioctl: Set interface flags");	    if (pIf->if_flags & IFF_UP)		{		/* Mark the interface as up and running */		pCs->arpCom.ac_if.if_flags |= (IFF_UP | IFF_RUNNING);		/* Initialize the interface */		csInit (pIf->if_unit);		}	    else  /* The interface is down */		{		/* Mark the interface as down */		pCs->arpCom.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);		/* Reset the chip */		csChipReset (pCs);		}	    break;	default:	    result = EINVAL;  /* Invalid argument */	    break;	}    splx (state);    return (result);    }/********************************************************************************* csChipReset - resets the CS8900 chip** This routine resets the CS8900 chip.** RETURNS: OK or ERROR*/LOCAL STATUS csChipReset     (    CS_SOFTC *pCs    )    {    int intState;    int ix;    UCHAR temp;    /* Disable interrupts at the CPU so reset command is atomic */    intState = intLock ();	/* INT LOCK */    /* We are now resetting the chip     * A spurious interrupt is generated by the chip when it is reset.     * This variable informs the interrupt handler to ignore this interrupt.     */    pCs->resetting = TRUE;    /* Issue a reset command to the chip */    csPacketPageW (pCs, CS_PKTPG_SELF_CTL, CS_SELF_CTL_RESET);    /* Re-enable interrupts at the CPU */    intUnlock (intState);	/* INT UNLOCK */    /* The chip is always in IO mode after a reset */    pCs->inMemoryMode = FALSE;    /* If transmission was in progress, it is not now */    pCs->txInProgress = FALSE;    /* Delay for 125 micro-seconds (one eighth of a second) */    CS_MSEC_DELAY(125);    /* Transition SBHE to switch chip from 8-bit to 16-bit */    CS_IN_BYTE (pCs->ioAddr + CS_PORT_PKTPG_PTR, &temp);    CS_IN_BYTE (pCs->ioAddr + CS_PORT_PKTPG_PTR + 1, &temp);    CS_IN_BYTE (pCs->ioAddr + CS_PORT_PKTPG_PTR, &temp);    CS_IN_BYTE (pCs->ioAddr + CS_PORT_PKTPG_PTR + 1, &temp);    /* Wait until the EEPROM is not busy */    for (ix=0; ix<CS_MAXLOOP; ix++)	if (!(csPacketPageR (pCs, CS_PKTPG_SELF_ST) & CS_SELF_ST_SI_BUSY))	    break;    if (ix == CS_MAXLOOP)	return (ERROR);    /* Wait until initialization is done */    for (ix=0; ix<CS_MAXLOOP; ix++)	if (csPacketPageR (pCs, CS_PKTPG_SELF_ST) & CS_SELF_ST_INIT_DONE)	    break;    if (ix == CS_MAXLOOP)	return (ERROR);    /* Reset is no longer in progress */    pCs->resetting = FALSE;    return (OK);    }/********************************************************************************* csChipInit - initializes the CS8900 chip** This routine uses the instance global variables in the cs_softc structure to* initialize the CS8900 chip.** RETURNS: N/A*/LOCAL void csChipInit    (    CS_SOFTC *pCs    )    {    USHORT busCtl;    USHORT selfCtl;    CS_IA  *pIA;    /* If memory mode is enabled */    if (pCs->configFlags & CS_CFGFLG_MEM_MODE)	{	/* If external logic is present for address decoding */	if (csPacketPageR (pCs, CS_PKTPG_SELF_ST) & CS_SELF_ST_EL_PRES)	    {	    /* Program the external logic to decode address bits SA20-SA23 */	    csPacketPageW (pCs, CS_PKTPG_EEPROM_CMD,		       ((UINT)(pCs->pPacketPage)>>20) | CS_EEPROM_CMD_ELSEL);	    }	/* Setup chip for memory mode */	csPacketPageW (pCs, CS_PKTPG_MEM_BASE, (UINT)(pCs->pPacketPage)&0xFFFF);	csPacketPageW (pCs, CS_PKTPG_MEM_BASE+2, (UINT)(pCs->pPacketPage)>>16);	busCtl = CS_BUS_CTL_MEM_MODE;	if (pCs->configFlags & CS_CFGFLG_USE_SA)	    busCtl |= CS_BUS_CTL_USE_SA;	csPacketPageW (pCs, CS_PKTPG_BUS_CTL, busCtl);	/* We are in memory mode now! */	pCs->inMemoryMode = TRUE;	}    /* If IOCHRDY is enabled then clear the bit in the busCtl register */    busCtl = csPacketPageR (pCs, CS_PKTPG_BUS_CTL);    if (pCs->configFlags & CS_CFGFLG_IOCHRDY)	csPacketPageW (pCs, CS_PKTPG_BUS_CTL, busCtl & ~CS_BUS_CTL_IOCHRDY);    else	csPacketPageW (pCs, CS_PKTPG_BUS_CTL, busCtl | CS_BUS_CTL_IOCHRDY);    /* Set the Line Control register to match the media type */    if (pCs->mediaType == CS_MEDIA_10BASET)	csPacketPageW (pCs, CS_PKTPG_LINE_CTL, CS_LINE_CTL_10BASET);    else	csPacketPageW (pCs, CS_PKTPG_LINE_CTL, CS_LINE_CTL_AUI_ONLY);    /* Set the BSTATUS/HC1 pin to be used as HC1 */    /* HC1 is used to enable the DC/DC converter */    selfCtl = CS_SELF_CTL_HC1E;    /* If the media type is 10Base2 */    if (pCs->mediaType == CS_MEDIA_10BASE2)	{	/* Enable the DC/DC converter	 * If the DC/DC converter has a low enable	 *   Set the HCB1 bit, which causes the HC1 pin to go low	 */	if ((pCs->configFlags & CS_CFGFLG_DCDC_POL) == 0)	    selfCtl |= CS_SELF_CTL_HCB1;	}    else  /* Media type is 10BaseT or AUI */	{	/* Disable the DC/DC converter	 * If the DC/DC converter has a high enable	 *   Set the HCB1 bit, which causes the HC1 pin to go low	 */	if ((pCs->configFlags & CS_CFGFLG_DCDC_POL) != 0)	    selfCtl |= CS_SELF_CTL_HCB1;	}    csPacketPageW (pCs, CS_PKTPG_SELF_CTL, selfCtl);    /* If media type is 10BaseT */    if (pCs->mediaType == CS_MEDIA_10BASET)	{	/* If full duplex mode then set the FDX bit in TestCtl register */	if (pCs->configFlags & CS_CFGFLG_FDX)	    csPacketPageW (pCs, CS_PKTPG_TEST_CTL, CS_TEST_CTL_FDX);	}    /* Initialize the config and control registers */    csPacketPageW (pCs, CS_PKTPG_RX_CFG, CS_RX_CFG_ALL_IE);    csPacketPageW (pCs, CS_PKTPG_RX_CTL,		   CS_RX_CTL_RX_OK_A | CS_RX_CTL_IND_A | CS_RX_CTL_BCAST_A);    csPacketPageW (pCs, CS_PKTPG_TX_CFG, CS_TX_CFG_ALL_IE);    csPacketPageW (pCs, CS_PKTPG_BUF_CFG, CS_BUF_CFG_RX_MISS_IE);    /* Put Ethernet address into the Individual Address register */    pIA = (CS_IA *)pCs->arpCom.ac_enaddr;    csPacketPageW (pCs, CS_PKTPG_IND_ADDR,   pIA->word[0]);    csPacketPageW (pCs, CS_PKTPG_IND_ADDR+2, pIA->word[1]);    csPacketPageW (pCs, CS_PKTPG_IND_ADDR+4, pIA->word[2]);    /* Set the interrupt level in the chip */    if (pCs->intLevel == 5)	csPacketPageW (pCs, CS_PKTPG_INT_NUM, 3);    else	csPacketPageW (pCs, CS_PKTPG_INT_NUM, (pCs->intLevel) - 10);    /* Enable reception and transmission of frames */    csPacketPageW (pCs, CS_PKTPG_LINE_CTL,		    csPacketPageR (pCs, CS_PKTPG_LINE_CTL) |				   CS_LINE_CTL_RX_ON | CS_LINE_CTL_TX_ON);    /* Enable interrupt at the chip */    csPacketPageW (pCs, CS_PKTPG_BUS_CTL,		    csPacketPageR (pCs, CS_PKTPG_BUS_CTL) |				   CS_BUS_CTL_INT_ENBL);    }#ifdef BSD43_DRIVER/********************************************************************************* csOutput - ethernet output routine** This routine is a major entry point and is called by the protocol stack to* transmit a packet across the LAN.  The packet data is passed to this routine* in a chain of mbuf structures.** This routine calls the ether_output() routine, which in turn calls the* csStartOutput() routine.  The ether_output() routine resolves the destination* IP address to it's Ethernet address, builds an Ethernet header and prepends* the Ethernet header to the mbuf chain.  The mbuf chain is added to the end* of the network interface driver's transmit queue.  If the network interface* NOTRAILERS flag is clear (trailers enabled), then the ether_output() routine* converts the packet data to the trailers format.  Finally, the ether_output()* routine calls the csStartOutput() routine begin transmission of the packet.** RETURNS: OK if successful, otherwise errno.*/LOCAL int csOutput    (    struct ifnet *pIf,    struct mbuf *pMbufChain,    SOCKADDR *pDst    )    {    FAST CS_SOFTC *pCs = &cs_softc[pIf->if_unit];    return (ether_output (pIf, pMbufChain, pDst, (FUNCPTR)csStartOutput,			  &pCs->arpCom));    }/********************************************************************************* csStartOutput - copy a packet to the interface** This routine is called to start the transmission of the packet at the head* of the transmit queue.  This routine is called by the ether_output() routine* when a new packet is added to the transmit queue and this routine is called* by csIntrTx() via netTask() when a previous packet transmission is* completed.  This routine is always executed at task time (never at interrupt* time).** Note: This network interface driver does not support output hook routines,* because to do so requires that an image of the transmit packet be built in* memory before the image is copied to the CS8900 chip.  It is much more* efficient to copy the image directly from the mbuf chain to the CS8900 chip.* However, this network interface driver does support input hook routines.** RETURNS: N/A*/LOCAL void csStartOutput    (    int unit    )    {    FAST CS_SOFTC *pCs = &cs_softc[unit];#else /* BSD43_DRIVER */LOCAL void csStartOutput    (    CS_SOFTC * pCs		/* pointer to control structure */    )    {#endif /* BSD43_DRIVER */    FAST struct mbuf *pMbuf;    struct mbuf *pMbufChain;    struct ifqueue *pTxQueue;    USHORT busStatus;    USHORT length;    int intState;#ifdef BSD43_DRIVER    if (unit >= MAXUNITS)	return;#endif /* BSD43_DRIVER */    pTxQueue = &pCs->arpCom.ac_if.if_snd;    /* Note the maximum depth of the transmit queue */    if (pTxQueue->ifq_len > pCs->maxTxDepth)	pCs->maxTxDepth = pTxQueue->ifq_len;    /* Don't interrupt a transmission in progress */    if (pCs->txInProgress)	return;    /* Disable interrupts at the CPU so disabling chip interrupt is atomic */    intState = intLock ();	/* INT LOCK */    /* Disable interrupt at the chip so transmit sequence is not disturbed */    csPacketPageW (pCs, CS_PKTPG_BUS_CTL,		    csPacketPageR (pCs, CS_PKTPG_BUS_CTL) &				   ~CS_BUS_CTL_INT_ENBL);    /* Re-enable interrupts at the CPU */    intUnlock (intState);	/* INT UNLOCK */

⌨️ 快捷键说明

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