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

📄 if_med.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    switch (cmd)	{	case SIOCSIFADDR:            ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas (ifp, &IA_SIN (data)->sin_addr);	    break;	case SIOCGIFADDR:	    bcopy((caddr_t) es->es_enaddr,		  (caddr_t) ((struct ifreq *) data)->ifr_addr.sa_data, 6);	    break;	case SIOCGIFFLAGS:	    *(short *) data = ifp->if_flags;	    break;	case SIOCSIFFLAGS:	    {            flags = ifp->if_flags;#ifdef BSD43_DRIVER	    if (ifp->if_flags & IFF_PROMISC)	        es->bPromisc = TRUE;	    else	        es->bPromisc = FALSE;#endif	    if (ifp->if_flags & IFF_UP)	        flags |= (IFF_UP | IFF_RUNNING);	    else	        flags &= ~(IFF_UP | IFF_RUNNING);	    ifp->if_flags = flags;	    }	    break;	default:	    error = EINVAL;	}    splx (s);    return (error);    }/********************************************************************************* medXmitIntrHandler - handler for transmit interrupts**/LOCAL void medXmitIntrHandler    (    FAST struct med_softc *es,    FAST u_char xmitStatus    )    {    FAST xmitQCB_s  * pXmitQCB = &(es->xmitQCB);    FAST XBIdx_t      headPkt;    /*     * The following flags indicate packet transmission error:     *     *   ABT - excess collisions, transmission was aborted     *   FU  - NIC FIFO underrun, transmission was aborted (should never occur)     *     * Retransmit the packet.     *     * The following flags indicate a collision occurred but the packet     * was eventually transmitted.     *     *   CRS - carrier lost (lost due to a collision)     *   OWC - out-of-window-collision     *     */    if (xmitStatus & (ABT | FU))        {        es->es_if.if_oerrors++;            /* log transmit error */        if (xmitStatus & ABT)            {            med_Stats.excessColl++;        /* update statistics monitor */	    logMsg("med%d: ERROR - excessive collisions, transmission aborted\n"                   , es->es_if.if_unit, 0,0,0,0,0);            }        if (xmitStatus & FU)            {            med_Stats.FIFO_UdrRun++;       /* update statistics monitor */            logMsg("med%d: ERROR - NIC FIFO underrun, transmission aborted\n",                   es->es_if.if_unit, 0,0,0,0,0);            }        headPkt = pXmitQCB->head;        if (medXmitPacket (es,                           pXmitQCB->xmitBCB [headPkt].pPktBfr,                           pXmitQCB->xmitBCB [headPkt].pktLen) == ERROR)            logMsg("med%d: ERROR - NIC transmitter active, should be off.\n",                   es->es_if.if_unit, 0,0,0,0,0);        }    else  /* no transmission error */        {        if (xmitStatus & CRS)            med_Stats.carrierLost++;      /* update statistics monitor */        if (xmitStatus & OWC)            med_Stats.outOfWndColl++;     /* update statistics monitor */        es->es_if.if_opackets++;          /* log packet output      */        pXmitQCB->xmitBCB [pXmitQCB->head].bPktRdy = FALSE;        medXmitBfrDealloc (pXmitQCB);     /* could be a macro        */        headPkt = pXmitQCB->head;         /* new head index after buf dealloc */        if (pXmitQCB->xmitBCB [headPkt].bPktRdy)            {            if (medXmitPacket (es,                               pXmitQCB->xmitBCB [headPkt].pPktBfr,                               pXmitQCB->xmitBCB [headPkt].pktLen) == ERROR)                logMsg("med%d: ERROR - NIC transmitter active, should be off.\n"		       , es->es_if.if_unit, 0,0,0,0,0);            }        else            {            medXmtrUnlock (&(pXmitQCB->lockNIC_Xmtr));            if (es->es_if.if_snd.ifq_head != NULL) /* if packet(s) on queue   */#ifdef BSD43_DRIVER                netJobAdd ( (FUNCPTR)medStartOutput, es->es_if.if_unit,                           0, 0, 0, 0);#else                netJobAdd ( (FUNCPTR)medStartOutput, (int)es, 0, 0, 0, 0);#endif            }        }    }/********************************************************************************* medIntr - top level DB-ETH interrupt service routine*/LOCAL void medIntr    (    FAST int unit    )    {    FAST u_char            intrStatus;    FAST struct med_softc *es   = med_softc [unit];    FAST NIC_DEVICE       *pNIC = es->nicAddr;    med_Stats.intrCount++;    /* retrieve interrupt status */    intrStatus = pNIC->Isr;    if (intrStatus & OVW)              /* overflow warning, no recv buffers */        {        medSetNIC_IMR (es, UNMASK_NONE,  nic_RECV_BFR_OVF_WARN                                       | nic_PKT_RECV_NO_ERRORS                                       | nic_PKT_RECV_ERROR);        es->bRecvBfrOvfl = TRUE;           /* flag for medRecvIntrHandler() */        intrStatus &= ~(OVW | PRX | RXE);  /* ignore these interrupts */        logMsg ("med%d: receive buffer overflow, all buffers cleared.\n",		unit, 0,0,0,0,0);        med_Stats.OVW_intrCount++;         /* update statistics monitor */        (void) netJobAdd (medInit, unit, 0,0,0,0);        }    if (intrStatus & PRX)              /* packet reception, no error */        {        /*         * Handle packet reception interrupts (with and without errors)         * at task level, until none remaining.         * Mask further PRX (nic_PKT_RECV_NO_ERRORS) interrupts.         * Mask further RXE (nic_PKT_RECV_ERROR) interrupts.         */        medSetNIC_IMR (es, UNMASK_NONE,  nic_PKT_RECV_NO_ERRORS                                       | nic_PKT_RECV_ERROR);        pNIC->Isr = PRX;               /* clear interrupt flag */        med_Stats.PRX_intrCount++;     /* update statistics monitor */        (void) netJobAdd ((FUNCPTR)medRecvIntrHandler, (int)es, 0,0,0,0);        }    if (intrStatus & PTX)              /* packet transmission, not aborted */        {        pNIC->Isr = PTX;               /* clear interrupt flag */        med_Stats.PTX_intrCount++;     /* update statistics monitor */        medXmitIntrHandler(es, pNIC->Tsr);        }    if (intrStatus & TXE)              /* packet transmission aborted */        {        pNIC->Isr = TXE;               /* clear interrupt flag       */        med_Stats.TXE_intrCount++;     /* update statistics monitor  */        medXmitIntrHandler(es, pNIC->Tsr);        }    if (intrStatus & RXE)              /* packet received with error(s) */        {        pNIC->Isr = RXE;               /* clear interrupt flag       */        medRecordRecvError (es);        }    if (intrStatus & CNT)              /* tally counter MSB set      */        {        pNIC->Isr = CNT;               /* clear interrupt flag       */        med_Stats.CNT_intrCount++;     /* update statistics monitor  */        (void) netJobAdd ((FUNCPTR)medReadTallyCntrs, (int)es,0,0,0,0);        }    }/********************************************************************************* medRecordRecvError - record packet reception errors*/LOCAL void medRecordRecvError    (    FAST struct med_softc *es    )    {    med_Stats.RXE_intrCount++;     /* update statistics monitor  */    /*     * Packets received with errors are not saved. Therefore,     * es->pktNextToRead is not updated.     */    es->es_if.if_ierrors++;    /* log every medLogCount errors */    if (medLogCount > 0 && (es->es_if.if_ierrors % medLogCount) == 0)        logMsg ("med%d: receive error\n",		es->es_if.if_unit,0,0,0,0,0);    }/********************************************************************************* medIntEnable - enables/disables the DB-ETH interrupt**/LOCAL void medIntEnable    (    BOOL bEnable    )    {    int oldLevel;    /*     * In an attempt to avoid spurious interrupts     * on Dbus interrupt disable...     */    if (!bEnable)        {        oldLevel = intLock ();        sysDbusEtherIntEnable (bEnable);        intUnlock (oldLevel);        }    else        sysDbusEtherIntEnable (bEnable);    }/********************************************************************************* medReset - reset the interface** Mark interface as inactive and reset the NIC.*/LOCAL void medReset    (    int unit    )    {    struct med_softc  *es   = med_softc [unit];    NIC_DEVICE        *pNIC = es->nicAddr;    es->es_if.if_flags &= ~IFF_RUNNING;    /*     * The following sequence is required when disabling the NIC from     * an active network. (This sequence was derived from the DP8390     * Datasheet Addendum, dated December, 1988, section 2.1.)     */    pNIC->Cr = RPAGE0 | STP | ABORT;    /* clear remote DMA byte count registers */    pNIC->Rbcr0 = 0;    pNIC->Rbcr1 = 0;    /* if the NIC not yet stopped, wait for approximately 2ms */    if ((pNIC->Isr & RST) != nic_STOP_MODE)        medNIC_AwaitStop (pNIC);    }/********************************************************************************* medInit - initialize NIC.** Restart the NIC chip and mark the interface as up.**/LOCAL int medInit    (    int unit    )    {    struct med_softc *es  = med_softc [unit];    struct ifnet     *ifp = &es->es_if;    medIntEnable (FALSE);     /* disable DB-ETH interrupt */    ifp->if_flags &= ~(IFF_UP | IFF_RUNNING | IFF_PROMISC);    /* stop all operations, reset the NIC */    medReset (unit);    /* Clear all driver statistics on first initialization, but     * not on subsequent calls of medInit(), e.g. after receive     * buffer overflow.     */    if (es->bFirstInit)        {        bzero((char *) &med_Stats, sizeof (med_Stats));        es->bFirstInit = FALSE;        }    /* configure and start NIC operations */    medConfigNIC (unit);    /* initialize the NIC IMR shadow register */    es->currentIMR = NIC_INTERRUPTS_HANDLED;    /* flag for medRecvIntrHandler(), no receive buffer overflow */    es->bRecvBfrOvfl = FALSE;    /*     * Initialize the "next-packet-to-read" pointer.     * The NIC's remote DMA capability is not supported by the DB-ETH.     * Therefore, the BNRY register is not maintained by the NIC, and     * it must be maintained by software. However, BNRY must never     * equal CURR.     *     * pktNextToRead: This page pointer is required to determine where     * to retrieve the next received packet.     */    es->pktNextToRead = CURR;    /*     * Initialize the xmitQCB and xmitBfrCB structures.     */    {    xmitQCB_s *pXmitQCB = &(es->xmitQCB);    int        idx;    pXmitQCB->head   = 0;    pXmitQCB->tail   = 0;    pXmitQCB->bEmpty = TRUE;    pXmitQCB->bFull  = FALSE;    for (idx = 0; idx < NUM_XMIT_BFRS; idx++)        {        pXmitQCB->xmitBCB [idx].bPktRdy = FALSE;        pXmitQCB->xmitBCB [idx].pPktBfr             = (char *) (NIC_XMIT_BFR_ADRS + XMIT_BFR_SIZE * idx);        }    for (idx = 1; idx < NUM_XMIT_BFRS; idx++)        pXmitQCB->xmitBCB [idx - 1].next = idx;    /*     * Close the ring. Assign the next index parameter of the last buffer     * control block to the index of the first buffer control block in     * the ring.     */    pXmitQCB->xmitBCB [NUM_XMIT_BFRS - 1].next = 0;    /* allow access to the NIC transmitter */    medXmtrUnlock (&(pXmitQCB->lockNIC_Xmtr));    }    ifp->if_flags |= (IFF_UP | IFF_RUNNING);#ifdef BSD43_DRIVER    if (es->bPromisc)	ifp->if_flags |= (IFF_PROMISC);#endif    medIntEnable (TRUE);    return (0);    }/********************************************************************************* bitReverse - reverse the position of the bits in a byte**/LOCAL u_char  bitReverse    (   u_char in    )    {    int    bit;    u_char fromBitMask;    u_char toBitMask;    u_char out = 0;    fromBitMask = 0x01;    toBitMask   = 0x80;    for (bit = 0; bit < 8; bit++)	{        if (in & fromBitMask)            out |= toBitMask;        fromBitMask = fromBitMask << 1;        toBitMask   = toBitMask   >> 1;	}    return (out);    }/********************************************************************************* medEthAddrGet - Get hardwired ethernet address from DB-ETH.** Read the ethernet address out of the ROM, one byte at a time.* put it in med_softc** INTERNAL* The DB-ETH prototype boards have the 8 data lines reversed to the* Ethernet address PROM. Using the assigned Ethernet address (1st 3* octets), this function determines if the data lines are reversed on* the DB-ETH board it is controling and makes the appropriate* conversion if necessary. Note that this function will fail if each* of the 3 octets are made-up of nybbles which are mirror images of* each other. For example, the following bytes (in hex):* 00, 81, 66, 99, E7, ... The third octet assigned to Matrix Corp.* is 0x0b. This octet in PROM will be determine whether to reverse* the data values.*/LOCAL void medEthAddrGet    (    int unit    )    {    u_char             octet;    u_int              octetSel;    BOOL               bReversed;    struct  med_softc *es = med_softc [unit];    u_char            *pEthOctet = (u_char *) (ETH_ADRS_PROM_ADRS);    /* XXX optimize by saving result in static variable then just test var. ? */    bReversed = FALSE;    if (*(pEthOctet + 2) != 0x0b)        bReversed = TRUE;    for (octetSel = 0; octetSel < 6; octetSel++ )        {        octet = *pEthOctet;        if (bReversed)            octet = bitReverse (octet);        es->es_enaddr [octetSel] = octet;        pEthOctet++;        }    }/********************************************************************************* medConfigNIC - Configure the NIC for operation** INTERNAL* This NIC initialization/configuration sequence was derived from the* DP8390 Datasheet Addendum, dated December, 1988, section 2.0. This

⌨️ 快捷键说明

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