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

📄 cs8900a.c

📁 网卡cs8900的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        fall through and tell the device that we got it even though
        we didn't.  That is, the packet is dropped. */
     if (buf_ptr != NU_NULL)
     {
        /* Put the head of the chain onto the incoming packet buffer list */
        MEM_Buffer_Enqueue (&MEM_Buffer_List, buf_ptr);

        /* Compute the total number of bytes that must be copied. */
        bytes_left = pkt_size;

        /* Preserve a pointer to the interface on which this packet was
           received. */
        buf_ptr->mem_buf_device = device;

        /* Clear the flags field. */
        buf_ptr->mem_flags = 0;

        /* Get a work pointer to the buffer chain */
        work_buf = buf_ptr;

        /* This while loop cycles through each of the buffers in the chain.
               The data_ptr and data_len are initialized for each of these
               buffers. This information is required by the CS8900A_Chip_Read
               function that is called below. CS8900A_Chip_Read uses DMA to copy
               the received packet into the buffer chain. */
        while (bytes_left && work_buf)
        {
             /* The first buffer in the chain is a special case. Becase there
                   is management overhead in the first buffer it can not hold as
                   much data as succeding buffers. */
             if (work_buf == buf_ptr)
             {
                 /* Initialize the data_ptr and data_len for the first buffer
                       in the chain. */
                 work_buf->data_len = (bytes_left <= NET_PARENT_BUFFER_SIZE) ?
                            bytes_left :  NET_PARENT_BUFFER_SIZE;

                 work_buf->data_ptr = work_buf->mem_parent_packet;
             }
             else
             {
                 /* Initialize the data_ptr and data_len for the 2nd and
                       succedding buffers. */
                 work_buf->data_len = (bytes_left <= NET_MAX_BUFFER_SIZE) ?
                            bytes_left :  NET_MAX_BUFFER_SIZE;

                 work_buf->data_ptr = work_buf->mem_packet;
             }

             /* Update a count of the bytes that still must have a home. */
             bytes_left -= work_buf->data_len;

             /* Move to the next buffer in the chain */
             work_buf = (NET_BUFFER *)work_buf->next_buffer;

        }

        /* Initialize the total data length for this buffer chain. */
        buf_ptr->mem_total_data_len = pkt_size;


        /* Now perform the actual copy.
          此处需要执行调用从网络芯片拷贝数据到系统内存的函数。*/

        CS8900A_Chip_Read ( device->dev_io_addr, buf_ptr, pFrame );

        /* Update the total number of octets received. */
//        SNMP_ifInOctets(device->dev_unit + 1, (RBUF_HDR_LEN + header[1]));

        return NU_SUCCESS;
     }
     else
     {
        SNMP_ifInDiscards_Inc(device->dev_unit + 1)
        return(-1);
     }
     /*  Re-enable interrupts. */
     NU_Local_Control_Interrupts(previous_int_value);
   }//end of if ((RxEvent & RX_EVENT_RX_OK))
   else 
     return(-1);

} /* end CS8900A_Recv_Packet */

/******************************************************************************/
/* FUNCTION                                                                   */
/*                                                                            */
/*    CS8900A_Xmit_Packet                                                      */
/*                                                                            */
/* DESCRIPTION                                                                */
/*                                                                            */
/*    This function will handle placing the passed in packet onto the actual  */
/*    wire.  This routine will make sure that each packet is at least 60      */
/*    bytes long.                                                             */
/*                                                                            */
/* AUTHOR                                                                     */
/*                                                                            */
/* CALLED BY                                                                  */
/*                                                                            */
/*    NET_Ether_Send                                                          */
/*                                                                            */
/* CALLS                                                                      */
/*                                                                            */
/*    OUTB                                                                    */
/*    INB                                                                     */
/*    CS8900A_Chip_Write                                                        */
/*                                                                            */
/* INPUTS                                                                     */
/*                                                                            */
/*    uint8    : pointer to the packet to be sent.                            */
/*    uiint16  : size of the packet in bytes.                                 */
/*                                                                            */
/* OUTPUTS                                                                    */
/*                                                                            */
/*    sshort   : Returns NU_SUCCESS (0) if ok, else -1 due to wait for trans  */
/*                                                                            */
/* HISTORY                                                                    */
/*                                                                            */
/*        NAME            DATE      REMARKS                                   */
/*                                                                            */
/*  Glen Johnson        02/17/96    Initial version                           */
/*  Glen Johnson        10/14/96    Replaced call to NU_Control_interrupts    */
/*                                  with masking of interrupts on the NIC.    */
/*                                                                            */
/******************************************************************************/
STATUS CS8900A_Xmit_Packet (DV_DEVICE_ENTRY *device, NET_BUFFER *buf_ptr)
{
    int     n_sent;
    int     pktlen = buf_ptr->mem_total_data_len;

//#if SNMP_INCLUDED
#if (INCLUDE_SNMP == NU_TRUE)

    /* Is this a unicast or a non-unicast packet. */
    if ( (buf_ptr->mem_flags & NET_BCAST) || (buf_ptr->mem_flags & NET_MCAST) )
        SNMP_ifOutNUcastPkts_Inc(device->dev_unit + 1);
    else
        SNMP_ifOutUcastPkts_Inc(device->dev_unit + 1);
#endif

    /*
     * Check to make sure that the message has the minimum of at least 60
     * bytes long. If not just set the new length, since hardware will do
     * the checksum for the whole block.
     */
    if (pktlen < 60)
    {
        pktlen = 60;
    }   /* end check for message is to small */

    /* Mask all network interrupts. */
//    CS8900AWritePacketPage(PKTPG_BUS_CTL,
//           CS8900AReadPacketPage(PKTPG_BUS_CTL) & ~BUS_CTL_int_ENBL );

    n_sent = CS8900A_Chip_Write(device->dev_io_addr, buf_ptr);

    /* Re-enable network interrupts. */
//    CS8900AWritePacketPage( PKTPG_BUS_CTL,
//                   CS8900AReadPacketPage(PKTPG_BUS_CTL) | BUS_CTL_int_ENBL );

//    if (n_sent < 60)
//        return (-1);

    SNMP_ifOutOctets(device->dev_unit + 1, n_sent);

    return (NU_SUCCESS);
} /* end CS8900A_Xmit */

/****************************************************************************/
/* FUNCTION                                                                 */
/*                                                                          */
/*   CS8900A_Transmit                                                        */
/*                                                                          */
/* DESCRIPTION                                                              */
/*                                                                          */
/*    This function will transmit any packets that are waiting in the       */
/*    transmit queue. This is the entry point for the transmit HISR.        */
/*                                                                          */
/* AUTHOR                                                                   */
/*                                                                          */
/*                                                                          */
/* CALLED BY                                                                */
/*                                                                          */
/*    Activated by the LISR                                                 */
/*                                                                          */
/* CALLS                                                                    */
/*                                                                          */
/*    NU_Control_interrupts                                                 */
/*    dll_dequeue                                                           */
/*    dll_enqueue                                                           */
/*    CS8900A_Xmit_Packet                                                    */
/*                                                                          */
/* INPUTS                                                                   */
/*                                                                          */
/*    No inputs to the function                                             */
/*                                                                          */
/* OUTPUTS                                                                  */
/*                                                                          */
/*    No outputs from this function                                         */
/*                                                                          */
/* HISTORY                                                                  */
/*                                                                          */
/*    NAME                DATE        REMARKS                               */
/*                                                                          */
/*    Glen Johnson         02/17/96    Initial version.                     */
/*                                                                          */
/****************************************************************************/

void CS8900A_Transmit (void)
{
    STATUS              previous_int_value;
    NET_BUFFER          *buf_ptr;
    DV_DEVICE_ENTRY     *device;

    /* Get a pointer to the device. */
    device = CS8900A_RBuffer[CS8900A_Read];

    /* Update the read index. */
    if(CS8900A_Read >= (MAX_CS8900A_DEVICES -1))
        CS8900A_Read = 0;
    else
        CS8900A_Read++;

    if (device == NU_NULL)
        return;

    /*  Lock out interrupts.  */
    previous_int_value = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);

    /* If there is an item on the transmit list (there should be everytime we
     * get here) then remove it because it has just been successfully
     * transmitted. */
    if(device -> dev_transq.head)
    {
        buf_ptr = MEM_Buffer_Dequeue(&device->dev_transq);

        MEM_One_Buffer_Chain_Free (buf_ptr, buf_ptr->mem_dlist);

        /* If there is another item on the list, transmit it. */
        if(device -> dev_transq.head)
        {
            /*  Re-enable interrupts. */
            NU_Local_Control_Interrupts(previous_int_value);

            /* Transmit the next packet. */
            CS8900A_Xmit_Packet(device, device->dev_transq.head);
            
            return;  //because has enabled interrupt
        }
    }

    /*  Re-enable interrupts. */
    NU_Local_Control_Interrupts(previous_int_value);

}  /* CS8900A_Transmit */

/*缓冲区事件的高级中断处理程序。*/
void CS8900A_BufferEvent(void)
{
    STATUS              previous_int_value;
    NET_BUFFER          *buf_ptr;
    DV_DEVICE_ENTRY     *device;

    /* Get a pointer to the device. */
    device = CS8900A_THOSTBuffer[Host_Data_Read];

    /* Update the read index. */
    if(Host_Data_Read >= (MAX_CS8900A_DEVICES -1))
        Host_Data_Read = 0;
    else
        Host_Data_Read++;

    if (device == NU_NULL)
        return;

    /*  Lock out interrupts.  */
    previous_int_value = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);

    /* If there is an item on the transmit list (there should be everytime we

⌨️ 快捷键说明

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