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

📄 ne2000.c

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

int ne2000_set_mac_addr (UINT8 *mac_addr)
{
	int i;
	UINT8  par[ETH_ALEN];
	
	OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_1 | NE2000_CR_STA);

	/* Write into chip */
	for (i = 0; i < ETH_ALEN; ++i) {
#if DATA_BUS_16BIT		
		OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_PAR0) + i*2, mac_addr[i]);
#else
		OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_PAR0) + i, mac_addr[i]);
#endif
	}

	/* Check it */
	for (i = 0; i < ETH_ALEN; ++i){
		par[i] = 0;
#if DATA_BUS_16BIT		
		par[i] = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_PAR0) + i*2);
#else
		par[i] = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_PAR0) + i);
#endif
		if (par[i] != mac_addr[i])
			return(FALSE);
	}
	
	return(TRUE);
}

int ne2000_test_reg(void)
{
	int i;
	UINT8  par[ETH_ALEN];
	UINT8  hw_addr[ETH_ALEN*2];
	UINT8 RTL8019id0, RTL8019id1;
	PNE2000_SOFTC sc;

	sc = off_to_softc();

	/* read 8019ID0--1 */
	OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_0 | NE2000_CR_STA);
	RTL8019id0 = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RBCR0));
	RTL8019id1 = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RBCR1));

	/* read PAR0---PAR5 */
	OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_1 | NE2000_CR_STA);
	for (i = 0; i < ETH_ALEN; ++i){
		par[i] = 0;
		hw_addr[i] = 0;
#if DATA_BUS_16BIT		
		par[i] = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_PAR0) + i*2);
#else
		par[i] = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_PAR0) + i);
#endif
	}

	/* read the ethernet address saved in SRAM */
	ne2000_pio_readmem(sc, 0, hw_addr, ETH_ALEN*2);

	return i+RTL8019id0+RTL8019id1;
}

/* Reset interface.   */
void ne2000_reset(/*PIFACE pi, */PNE2000_SOFTC sc)
{
STATUS previous_int_value;

    /*  Lock out interrupts.  */
    previous_int_value = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
   
    ne2000_stop(sc);
    ne2000_init(sc);
	ne2000_test_reg();
   
    NU_Control_Interrupts(previous_int_value);
}
 
/* Take interface offline.   */
void ne2000_stop(PNE2000_SOFTC sc)
{
int n = 5000;
//int n = 100000;//pessia

    /* Stop everything on the interface, and select page 0 registers.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_0 | NE2000_CR_STP);

    /*
     * Wait for interface to enter stopped state, but limit # of checks to
     * 'n' (about 5ms).  It shouldn't even take 5us on modern DS8390's, but
     * just in case it's an old one.
     */
    while (((INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR)) & NE2000_ISR_RST) == 0) && --n);
}

/* Initialize device.    */
void ne2000_init(PNE2000_SOFTC sc)
{
int i;
STATUS previous_int_value;
UINT8  mcaf[8];   /* multicast address filter */
UINT8  my_hw_addr[6];

	tc_memset(my_hw_addr, 2, 6);	//set the macaddress is all 2
	tc_memset(mcaf, 1, 8);			//accept all multicast packet
    
    /*
     * Initialize the NIC in the exact order outlined in the NS manual.
     * This init procedure is "mandatory"...don't change what or when
     * things happen.
     */

	/*  Lock out interrupts.  */
    previous_int_value = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
    
    /* This variable is used below - don't move this assignment.   */
    sc->next_packet = (UINT16) (sc->rec_page_start + 1);

    /* Set interface for page 0, remote DMA complete, stopped.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_0 | NE2000_CR_STP);

    if (sc->isa16bit) 
    {
        /*
         * Set FIFO threshold to 8, No auto-init Remote DMA, UINT8
         * order=80x86, UINT16-wide DMA xfers,
         */
#if RTL8019_LOOPBACK_TEST
		OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_DCR), NE2000_DCR_FT1 | NE2000_DCR_WTS | NE2000_DCR_BOS);
#else
    /* Take interface out of loopback.   */
		OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_DCR), NE2000_DCR_FT1 | NE2000_DCR_WTS | NE2000_DCR_LS);
#endif
    } 
    else 
    {
        /* Same as above, but UINT8-wide DMA xfers.   */
#if RTL8019_LOOPBACK_TEST
		OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_DCR), NE2000_DCR_FT1);
#else
    /* Take interface out of loopback.   */
		OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_DCR), NE2000_DCR_FT1 | NE2000_DCR_LS);
#endif
    }

    /* Clear remote UINT8 count registers.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RBCR0), 0);

    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RBCR1), 0);

    /* Tell RCR to do nothing for now.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RCR), NE2000_RCR_MON);

    /* Place NIC in internal loopback mode.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_TCR), NE2000_TCR_LB0);

    /* Initialize transmit/receive (ring-buffer) page start.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_TPSR), sc->tx_page_start);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_PSTART), sc->rec_page_start);

    /* Initialize receiver (ring-buffer) page stop and boundary.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_PSTOP), sc->rec_page_stop);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_BNRY), sc->rec_page_start);

    /*
     * Clear all interrupts.  A '1' in each bit position clears the
     * corresponding flag.
     */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR), 0xff);

    /*
     * Enable the following interrupts: receive/transmit complete,
     * receive/transmit error, and Receiver OverWrite.
     *
     * Counter overflow and Remote DMA complete are *not* enabled.
     */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_IMR), NORMAL_NE2000_INTS);

    /* Program command register for page 1.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_1 | NE2000_CR_STP);

    /* Copy out our station (ethernet) address.   */
    for (i = 0; i < ETH_ALEN; ++i) {
#if DATA_BUS_16BIT		
	OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_PAR0) + i*2, my_hw_addr[i]);
#else
	OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_PAR0) + i, my_hw_addr[i]);
#endif
    	}

    /* Set current page pointer to next_packet (initialized above).   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_CURR), sc->next_packet);


    /* Set multicast filter on chip.            */
    /* If none needed lenmclist will be zero    */
    //ne2000_getmcaf((PFBYTE) pi->mcast.mclist, pi->mcast.lenmclist, 
    //            mcaf);

    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_MAR0), mcaf[0]);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_MAR1), mcaf[1]);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_MAR2), mcaf[2]);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_MAR3), mcaf[3]);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_MAR4), mcaf[4]);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_MAR5), mcaf[5]);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_MAR6), mcaf[6]);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_MAR7), mcaf[7]);


    /* ====================                    */
    /* Program command register for page 0.    */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P1_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_0 | NE2000_CR_STP);

    /* set broadcast mode                     */
    /* NOTE: promiscous mode is not supported */
	/*  i = NE2000_RCR_AB;   */

    /* Accept multicasts and broadcasts   */
	//    i = NE2000_RCR_AB | NE2000_RCR_AM;
	i = NE2000_RCR_AB | NE2000_RCR_AM | NE2000_RCR_PRO;
#if RTL8019_LOOPBACK_TEST
	i = 0;
#endif
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_RCR), i);

#if RTL8019_LOOPBACK_TEST
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_TCR), LOOPBACK_TEST_MODE);
#else
    /* Take interface out of loopback.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_TCR), 0);
#endif

    /* Fire up the interface.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_0 | NE2000_CR_STA);

    NU_Control_Interrupts(previous_int_value);
}

/* ********************************************************************   */
/* INTERRUPT routines.                                                    */
/* ********************************************************************   */ 
void ENT_INT_RTL8019AS( void )
{
	ent_int();

	mask_irq(15);
	*((volatile unsigned long*)PORTH_INTRCLR) = 0x6fUL;
	
	ne2000_interrupt(0);
	
	unmask_irq(15);

	ret_int();
}

void Irq_8019_Handler(void)
{
	UINT8 isr;
	
	mask_irq(10);

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

	/* get interrupt status register   */
	isr = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR));

	if ( isr )
		ne2000_interrupt(0);

	unmask_irq(10);
}

/* handle interrupts - this is the interrupt routine   */
void ne2000_interrupt(int minor_no)   /*__fn__*/
{
PNE2000_SOFTC sc;
UINT8          isr;
int           error;

    sc = off_to_softc();
    if (!sc)
        return;

	//ks_enable();  

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

    /* get interrupt status register   */
    isr = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR));

    /* Loop until there are no more new interrupts.   */
    while (isr)
    {
        /*
         * Reset all the bits in the interrupt status register that we 
         * are 'acknowledging' by writing a '1' to each bit position 
         * that was set. (Writing a '1' *clears* the bit.)
         */
        OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR), isr);

        /* ******   */
        /*
         * Handle transmitter interrupts.  Handle these first because
         * the receiver will reset the board under some conditions.
         */
        if (isr & (NE2000_ISR_PTX | NE2000_ISR_TXE)) /* pkt xmit or xmit error */
        {
            int collisions = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_NCR)) & 0x0f;

            /*
             * Check for transmit error.  If a TX completed with an
             * error, we end up throwing the packet away.  Really
             * the only error that is possible is excessive
             * collisions, and in this case it is best to allow the
             * automatic mechanisms of TCP to backoff the flow.  Of
             * course, with UDP we're screwed, but this is expected
             * when a network is heavily loaded.
             */
            error = INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_TSR));
            if ( (isr & NE2000_ISR_TXE) || 
                 (error & (NE2000_TSR_CDH | NE2000_TSR_CRS)) )
            {
                /* if transmit aborted (NE2000_TSR_ABT) due to excessive collisions,   */
                /* if collisions is 0 it really is 16 (excessive collisions)           */
                if (error & NE2000_TSR_ABT)
                {
                    sc->stats.collision_errors++;
                }

                /* Update output errors counter.   */
                sc->stats.errors_out++;

                //pi->xmit_status = ENETDOWN;
            } 
            else        /* no transmit error */
            {
                /* check for out of window collsions   */
                if (INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_TSR)) & NE2000_TSR_OWC)
                    sc->stats.owc_collision++;
                if (collisions == 1)
                    sc->stats.one_collision++;
                else if (collisions >= 1)
                    sc->stats.multiple_collisions++;
                if (INBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_TSR)) & NE2000_TSR_CRS) 
                    sc->stats.tx_carrier_errors++;

⌨️ 快捷键说明

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