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

📄 lan8xx.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
            }

        if (FirstBdPtr->status & LAST_IN_FRAME)
            {
            /*---------------------------------------------------------*/
            /* We should always get here since every frame does have a */
            /* buffer with the LAST bit set.                           */
            /* 1. Mark last frame as !FULL  so ReclaimFrames will work */
            /*    correctly.                                           */
            /* 2. Increment to the next buffer.  This is the next one  */
            /*    for the SCC to process.                              */
            /* 3. Set the offset to this next frame in TBPTR           */
            /* 4. Restart the Xmitter.                                 */
            /*---------------------------------------------------------*/
            FirstBdPtr->status  &= ~FULL;
            IncTxBDptr(FirstBdPtr);

            /*---------------------------------------------------------*/
	    /* Set TBPTR                                               */
            /*---------------------------------------------------------*/
            TxBdPtr(E_SCC1_BASE) = (ULONG)FirstBdPtr - (ULONG)E_BuffDescr;

            ReclaimTxFrames();
            while (E_CP_CommandReg & SEMAPHORE_FLAG);
            E_CP_CommandReg = RESTART_TX + SCC1_CH_NUM + SEMAPHORE_FLAG;
            while (E_CP_CommandReg & SEMAPHORE_FLAG);
            }
        else
            {
            /*---------------------------------------------------------*/
            /* Hopefully this does not happen.  The code is left here  */
            /* to deal with anything completely unexpected. The only   */
            /* solution here is to completely reset the TX BD list.    */
            /* It's brutal but it will unhang the xmitter.             */
            /*---------------------------------------------------------*/
            CleanUpTx();
            }
        }
    splx(OldLevel);
    }

/*---------------------------------------------------------------------*/
/* If frames were sent out, refill empty transmit buffer descriptors.  */
/*---------------------------------------------------------------------*/
if (Events & BUFFER_SENT)
   {
   FillTxBDs();
   }


return pSOS_Is_Up;
}

/***********************************************************************/
/*  ReceivePackets: Process all received packets.                      */
/*                                                                     */
/***********************************************************************/
static void ReceivePackets(void)
{
USHORT length, good, type;
RX_BUFF *ep;
mblk_t *m;
frtn_t frtn;
ULONG OldLevel;
USHORT status;
long index;

for (;;)
    {
    OldLevel = splx(MAX_ILEV);

    /*-----------------------------------------------------------------*/
    /* Stop when we hit a buffer with no data, or a BD w/ no buffer    */
    /*-----------------------------------------------------------------*/
    if ((RxNewPtr->status & EMPTY) || (RxNewPtr->address == NULL))
        {
        splx(OldLevel);
        break;
        }

    /*-----------------------------------------------------------------*/
    /* Per packet initialization.                                      */
    /*-----------------------------------------------------------------*/
    length = RxNewPtr->length - 18;
    status = RxNewPtr->status;
    ep = RxNewPtr->address;
    type = ep->type;
    good = TRUE;

    /*-----------------------------------------------------------------*/
    /* Remove this buffer from the BD ring by clearing the BD's        */
    /* address field and advancing the BD ptr to the next buffer.      */
    /* Then reenable interrupts.                                       */
    /*-----------------------------------------------------------------*/
    RxNewPtr->address = NULL;

    if (RxNewPtr >= RxLastBdPtr)
        RxNewPtr = RxFirstBdPtr;
    else
        RxNewPtr++;

    splx(OldLevel);

    /*-----------------------------------------------------------------*/
    /* Determine if this packet is okay.                               */
    /*-----------------------------------------------------------------*/
    if ((status & (CRC_ERROR | OVERRUN | COLLISION)) || (length > 1500))
        good = FALSE;

#if ((BSP_LAN1_FLAGS) & (IFF_MULTICAST))
        /*-------------------------------------------------------------*/
        /* The MC68360 uses a hash table of 64 bits to filter out      */
        /* multicast addresses. Unwanted multicast packets may be      */
        /* received as a result. If the received packet is a multicast */
        /* packet, verify that it is in the table before passing it up */
        /* the protocol stack. It's better to reject unwanted packets  */
        /* as soon as possible.                                        */
        /*                                                             */
        /* Setting the BSP_LAN1_FLAGS so that the IFF_MULTICAST bit is */
        /* reset and re-compiling will remove all multicast address    */
        /* code from the BSP. If multicast addressing is desired, but  */
        /* filtering out multicast addresses in the driver is not      */
        /* desired simply comment out the if statement and recompile.  */
        /* As the number of different multicast addresses in the table */
        /* and on the network increases there is a greater chance that */
        /* unwanted packets will be received. If the number of         */
        /* addresses wanted is small and known not to collide with     */
        /* multicast addresses in use on the network then this if      */
        /* statement can be removed to shorten the time spent in the   */
        /* ISR.                                                        */
        /*                                                             */
        /* If the address is multicast and there is a multicast table  */
        /* defined, do the filtering.                                  */
        /*-------------------------------------------------------------*/
        if (ep->daddr.byte[0] & 1)
            {
            for (index = 0; index < 6; index++)
                 if (((unsigned char)ep->daddr.byte[index]) != 0xFF)
                     break;

            /*---------------------------------------------------------*/
            /* If the destination is not the broadcast address and it  */
            /* is not in the multicast table, return it and get the    */
            /* next packet.                                            */
            /*---------------------------------------------------------*/
            if (index < 6)
                {
                if (lan_mcast.mc_addr)
                    {
                    OldLevel = splx(MAX_ILEV);
                    index =
                        lan_lookup_mcast((UCHAR *)&ep->daddr.byte[0]);
                    splx(OldLevel);

                    if (index < 0)
                        {
                        ReturnBuffer(ep);
                        continue;
                        }
                    }
                else
                    {
                    ReturnBuffer(ep);
                    continue;
                    }
                }
            }
#endif

    /*-----------------------------------------------------------------*/
    /* Collect stats for MIB on broadcast and unicast packets.         */
    /*-----------------------------------------------------------------*/
    if (ep->daddr.byte[0] & 1)
        MG_stat.innucastpkts++;
    else
        MG_stat.inucastpkts++;

    /*-----------------------------------------------------------------*/
    /* If the packet is acceptable, pass it to pNA+.  Otherwise, count */
    /* the receive error and return envelope to the free queue.        */
    /*-----------------------------------------------------------------*/
    if (good)
        {
        MG_stat.inoctets += length + 18;

        frtn.free_arg = (void *)ep;
        frtn.free_func = (void (*)())ReturnBuffer;
        if (Announce && (m = Ni_funcs.esballoc((UCHAR *)ep->buffer,
          length, 0, &frtn)))
            {
            m->b_wptr += length;
            pSOS_Is_Up = (*Announce)(type, (char *)m, length, If_Num,
               (char *)(&ep->saddr), (char *)(&ep->daddr));
            }
        else
            ReturnBuffer(ep);
        }
    else
        {
        inerrors++;
        ReturnBuffer(ep);
        }
    }

/*---------------------------------------------------------------------*/
/* Replenish the receive ring's supply of receive buffers.             */
/*---------------------------------------------------------------------*/
AssignRxBuffers();
}

/***********************************************************************/
/*   FillTxBDs: Move outgoing packets from the outgoing queue to       */
/*             the transmit buffer descriptor ring, if possible.       */
/*                                                                     */
/*        NOTE: This includes a workaround for the padding problem     */
/*              on the 68360                                           */
/***********************************************************************/
static void FillTxBDs(void)
{
ULONG old_level;
USHORT FrameLength;
TX_HDR *TxhPtr;
mblk_t *m, *tmp, *m_prev;
BuffDescType *FirstBdPtr;
BuffDescType *PrevBdPtr=NULL;
UINT NrBDs;
int i, copy_size, length;
UCHAR *src;

old_level = splx(MAX_ILEV);

/*---------------------------------------------------------------------*/
/* Free up some BDs if possible.                                       */
/*---------------------------------------------------------------------*/
ReclaimTxFrames();

for (;;)
    {
    /*-----------------------------------------------------------------*/
    /* If there are no outgoing messages queued, or if there are not   */
    /* enough descriptors available for the first queued frame, we     */
    /* can't do anything.                                              */
    /*-----------------------------------------------------------------*/
    if ((TxhOutHead == NULL) || (TxFreeBDs < 3))
       break;

    /*-----------------------------------------------------------------*/
    /* Extract the top message.   If queue is left empty, assign NULL  */
    /* to the queue tail as well as to the queue head.                 */
    /*-----------------------------------------------------------------*/
    TxhPtr = TxhOutHead;
    TxhOutHead = TxhOutHead->next;
    if (TxhOutHead == NULL)
        TxhOutTail = NULL;

    /*-----------------------------------------------------------------*/
    /* Put the transmit header into the descriptor ring.  Note that    */
    /* we save a pointer to this first buffer descriptor, and we don't */
    /* set the "FULL" bit for this first buffer descriptor yet.  After */
    /* all of the other buffer descriptors for this frame are set up,  */
    /* we will turn on the "FULL" bit in this descriptor.  That way    */
    /* we prevent the CPM from transmitting the frame before we have   */
    /* all of the descriptors in place.                                */
    /*-----------------------------------------------------------------*/
    FirstBdPtr = TxNewPtr;

    /*-----------------------------------------------------------------*/
    /* Add the transmit header to the BD list.                         */
    /*-----------------------------------------------------------------*/
    TxNewPtr->address = TxhPtr;
    TxNewPtr->length = 14;
    if (TxNewPtr == TxLastBdPtr)
        TxNewPtr->status = (USHORT)WRAP | PAD | TX_CRC;
    else
        TxNewPtr->status = PAD | TX_CRC;
    IncTxBDptr(TxNewPtr);
    TxFreeBDs--;

    FrameLength = 14;
    NrBDs = 1;

    /*-----------------------------------------------------------------*/
    /* Now put the buffers pointed to by the message block triplet in. */
    /*-----------------------------------------------------------------*/
    m = TxhPtr->msg_ptr;
    m_prev = m;
    while (m)
        {
        /*-------------------------------------------------------------*/
        /* Skip all zero length elements in the mblk list, since       */
        /* adding a buffer of length zero to the BD pool is bad. Free  */
        /* the zero length element and "close" the hole in the chain.  */
        /*-------------------------------------------------------------*/
        length = m->b_wptr - m->b_r

⌨️ 快捷键说明

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