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

📄 ne2000.c

📁 最近在國外網站抓到的作業系統 以Arm為基礎去開發的
💻 C
📖 第 1 页 / 共 5 页
字号:

    /* Set up DMA byte count.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RBCR0), amount);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RBCR1), amount >> 8);

    /* Set up source address in NIC mem.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RSAR0), src);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RSAR1), src >> 8);

    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD0 | NE2000_CR_PAGE_0 | NE2000_CR_STA);

    if (sc->isa16bit)
        insw((IOADDRESS) REF_ASIC_ADDR(asic_addr_NE2000_NOVELL_DATA), (unsigned short KS_FAR *) dst, amount / 2);
    else
        insb((IOADDRESS) REF_ASIC_ADDR(asic_addr_NE2000_NOVELL_DATA), dst, amount);
}

/*
 * Write a DCU to the destination NIC memory address using programmed I/O
 */
BOOLEAN ne2000_pio_write_pkt(PNE2000_SOFTC sc, PFCBYTE packet, int length, UINT16 dst)
{
int     maxwait; /* about 120us */
UINT8    savebyte[2];
BOOLEAN ret_val=TRUE;

    /* Select page 0 registers.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_0 | NE2000_CR_STA);

    /* Reset remote DMA complete flag.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR), NE2000_ISR_RDC);

    /* Set up DMA UINT8 count.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RBCR0), length);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RBCR1), length >> 8);

    /* Set up destination address in NIC mem.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RSAR0), dst);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RSAR1), dst >> 8);

    /* Set remote DMA write.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD1 | NE2000_CR_PAGE_0 | NE2000_CR_STA);

    /*
     * Transfer DCU to the NIC memory.
     * 16-bit cards require that data be transferred as words, and only
     * words, so that case requires some extra code to patch over
     * odd-length DCUs.
     */
    if (!sc->isa16bit) 
    {
        /* NE1000s are easy.   */
        outsb((IOADDRESS) REF_ASIC_ADDR(asic_addr_NE2000_NOVELL_DATA), packet, length);
    } 
    else 
    {
        /* NE2000s are a bit trickier.   */
        /* Output contiguous words.      */
        if (length > 1) 
        {
            outsw((IOADDRESS) REF_ASIC_ADDR(asic_addr_NE2000_NOVELL_DATA), (unsigned short KS_FAR *) packet, length >> 1);
            packet += length;
            length &= 1;
            if (length)
                packet--;
        }
        /* If odd number of bytes, output last UINT8 as a UINT16 with a 0 appended   */
        if (length == 1) 
        {
            savebyte[0] = *packet;
            savebyte[1] = 0;
            OUTWORD(REF_ASIC_ADDR(asic_addr_NE2000_NOVELL_DATA), *(UINT16 *)savebyte);
        }
    }
        
    /*
     * Wait for remote DMA complete.  This is necessary because on the
     * transmit side, data is handled internally by the NIC in bursts and
     * we can't start another remote DMA until this one completes.  Not
     * waiting causes really bad things to happen - like the NIC
     * irrecoverably jamming the ISA bus.
     */
#if (NEW_WAIT)
    maxwait = 300;      /* about 360usec */
#else
    maxwait = 1000;
#endif
    while (maxwait--)
    {
        if ( ((INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR)) & NE2000_ISR_RDC) == NE2000_ISR_RDC))
            break;
    }

    /* If pi is zero we are probing so don't reset   */
    if (!maxwait) 
    {
#if (NEW_WAIT)
		#define ks_msec_p_tick() (1000/NU_PLUS_Ticks_Per_Second)
		#define ks_sleep(x)	NU_Sleep(x)
		//DEBUG_ERROR("NE2000: sleep in xmit", NOVAR, 0, 0);
        /* the while() above was not enough.  Cannot afford to tie up the   */
        /* CPU longer than .5 msec, so sleep 20 msecs longer now.           */
        if (ks_msec_p_tick() >= 20)
            ks_sleep(1);
        else
            ks_sleep((UINT16)((20+ks_msec_p_tick()-1)/ks_msec_p_tick()));

        ++sc->stats.tx_delayed;
#endif
#if (NEW_WAIT)
        if ((INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR)) & NE2000_ISR_RDC) != NE2000_ISR_RDC)
#endif
        {
            //DEBUG_ERROR("remote transmit DMA failed to complete", NOVAR, 0, 0);
            sc->stats.errors_out++;
            sc->stats.tx_other_errors++;
            ne2000_reset(sc);
            ret_val = FALSE;
        }
    }
    
    
    return(ret_val);
}


/*********************************************************************/
/*                                                                   */
/*     					NUCLEUS NET FUNCTION                         */
/*                                                                   */
/*********************************************************************/

VOID MAC_TxHisr(DV_DEVICE_ENTRY* device)
{
    STATUS  previous_int_value;

    if (device == NU_NULL)
        return;
    
    /*  Lock out interrupts.  */
    previous_int_value = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);

    DEV_Recover_TX_Buffers (device);

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

        /* Transmit the next packet. */
        Rtl8019_Transmit(device, device->dev_transq.head);
    }

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

}  /* MAC_TxHisr */

VOID Rtl8019_TxHisr()
{
    DV_DEVICE_ENTRY     *device;

    /* Get a pointer to the device. */
#if RTL8019_LOOPBACK_TEST
	device = DEV_Get_Dev_By_Name("loopback");
#else
    	device = DEV_Get_Dev_By_Name("RTL8019");
#endif	
	
	MAC_TxHisr(device);
}

void Rtl8019_RxHisr ()
{
    /* Let the upper layer know a good packet is here. */
    NU_Set_Events(&Buffers_Available, (UNSIGNED)2, NU_OR);

    Hisr_Activated = 0;
}  /* END */

/************************************************************************
* FUNCTION                                                             
*                                                                      
*        Rtl8019_Initialize                                        
*                                                                      
* DESCRIPTION                                                          
*                                                                      
*        This function intializes the media layer of the protocol stack. 
*                                                                      
* AUTHOR                                                               
*                                                                      
*        MeterChen                                      
*                                                                      
* INPUTS                                                               
*                                                                      
*        DV_DEVICE_ENTRY       *dev_ptr      Pointer to the device 
*                                            structure for this device.
*                                                                      
* OUTPUTS                                                              
*                                                                      
*        STATUS                              Returns NU_SUCCESS if
*                                            initialization is successful,
*                                            else a value less than 0 is
*                                            returned.
*                                                                      
************************************************************************/

STATUS Rtl8019_Initialize(DV_DEVICE_ENTRY *dev_ptr)
{
STATUS  status;
VOID    *pointer;

    /* Fill in the device table */
    dev_ptr->dev_output     = NET_Ether_Send;   /* net.c */
    dev_ptr->dev_input      = NET_Ether_Input;  /* net.c */
    dev_ptr->dev_start      = Rtl8019_Transmit;
    dev_ptr->dev_receive    = Rtl8019_Receive;
    dev_ptr->dev_addrlen    = HW_Address_Size;
    dev_ptr->dev_hdrlen     = ETH_HeaderSize;
    dev_ptr->dev_mtu        = MTU_Size;         /* 1500 */
    dev_ptr->dev_ioctl      = Rtl8019_Ioctl;

    /* Get the hardware address from the device structure and */
    /* set it into the CAM filter.                            */
    //Rtl8019_SetMacAddr(dev_ptr);

    /* Initialize the MAC. */
    if (ne2000_open() != TRUE)
    {
    	return (-1);
    }
	
    /* Allow reception of broadcast and multicast packets. */
    dev_ptr->dev_flags |= (DV_BROADCAST | DV_MULTICAST);

    /* CAM filter setting is done in api_MacHWInit routine */
    memcpy(dev_ptr->dev_mac_addr, (UINT8*)dev_ptr->dev_driver_options, 6);

    /* Set the input MAC ADDRESS */
    if (ne2000_set_mac_addr(dev_ptr->dev_mac_addr) != TRUE)
    {
    	return (-1);
    }

    /* Init the basic interface information. */
    SNMP_ifDescr(device->dev_unit + 1, "Realtek 8019as Ethernet: Software revision 1.2");
    SNMP_ifType(device->dev_unit + 1, 6);
    SNMP_ifMtu(device->dev_unit + 1, device->dev_mtu);

    /* Create the HISR for receiving packets from the MAC */
    status = NU_Allocate_Memory (&System_Memory,
                                 &pointer,
                                 2000,
                                 NU_NO_SUSPEND);
    if (status != NU_SUCCESS)
    {
        return (-2);
    }

    status = NU_Create_HISR (&Ether_Rcv, "ETH_RX_HISR",
                             Rtl8019_RxHisr,
                             0, pointer, 2000);
   
    if (status != NU_SUCCESS)
    {
        return (-3);
    }

    /* Create the HISR for transmitting packets */
    status = NU_Allocate_Memory (&System_Memory,
                                 &pointer,
                                 2000,
                                 NU_NO_SUSPEND);
    if (status != NU_SUCCESS)
    {
        return (-4);
    }

    status = NU_Create_HISR (&Ether_Xmit, "ETH_TX_HISR",
                              Rtl8019_TxHisr,
                              0, pointer, 2000);
    if (status != NU_SUCCESS)
    {
        return (-5);
    }

    /* Set the current status to operational. */
    SNMP_ifAdminStatus(device->dev_unit + 1, 1);
    SNMP_ifOperStatus(device->dev_unit + 1, 1);


	enable_ne2000_irq();//pessia

    return (NU_SUCCESS);
} 

/************************************************************************
* FUNCTION                                                             
*                                                                      
*        Rtl8019_Transmit                                        
*                                                                      
* DESCRIPTION                                                          
*                                                                      
*        Accepts a packet from the upper layers and generates an
*        ethernet frame for transmission.
*                                                                      
* AUTHOR                                                               
*                                                                      
*        Meterchen                                      
*                                                                      
* INPUTS                                                               
*                                                                      
*        DV_DEVICE_ENTRY    *dev        Pointer to the device structure.
*        NET_BUFFER         *buf_ptr    Pointer to the data we want to
*                                         send.
*                                                                      
* OUTPUTS                                                              
*                                                                      
*        STATUS             (0) NU_SUCCESS 
*                                                                      
************************************************************************/

CHAR    TEMP_BUF_T[2000];

STATUS Rtl8019_Transmit(DV_DEVICE_ENTRY *dev, NET_BUFFER *buf_ptr) 
{
PNE2000_SOFTC sc;
STATUS  previous_int_value;    /* We'll be push/popping interupt flags */
int 	ret_val;	
UINT32  length;	  /* This is needed to handle packets that are bigger than one NET Buffer can hold. */
CHAR	*FramePtr;
	
	FramePtr = TEMP_BUF_T;
    
    sc = iface_to_softc();
    //if (!sc)
    //    return(ENUMDEVICE); 
    //if (sc->do_recovery)
    //    return(ENETDOWN);

#if INCLUDE_SNMP
    /* Find out if this is a unicast or non-unicast packet, and update MIB. */
    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

    length = 0;

⌨️ 快捷键说明

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