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

📄 ne2000.c

📁 最近在國外網站抓到的作業系統 以Arm為基礎去開發的
💻 C
📖 第 1 页 / 共 5 页
字号:
/*********************************************************************** 
 * $Workfile:   net2000.c  $ 
 * $Revision: 1.1.1.1 $ 
 * $Author: meterchen $ 
 * $Date: 2003/11/10 17:00:55 $ 
 * 
 * Project:     Shenzhen-Nucleus-Net
 * 
 * Description: 
 *     ne2000 driver   
 *
 * Revision History: 
 * 
 *********************************************************************** 
 * 
 *  Copyright (c) 2003 CHENMENG
 * 
 *  All rights reserved 
 * 
 **********************************************************************/

#define CFG_NE2000_IOBASE 0x2c000400
#define CFG_NE2000_IRQ    15

#include "net/nettypes.h"
//#include "44b.h"
#include "net/inc/externs.h"
//#include "net/inc/ethernet.h"
#include "ethernet.h"

#include "ostype.h"
#include "ne2000.h"
#include "hardware_reg.h"  
#include "hardware.h"  

#define IP_ALEN  4              /* number of bytes in an IP address */
#define ETH_ALEN 6              /* number of bytes in an ETHERNET address */
#define TOK_ALEN 6              /* number of bytes in a Token Ring address */
#define LL_ALEN  6              /* number of bytes in a Link Layer address */
                                /* (token ring or ethernet)   */
#define ETHERSIZE  1514   /* maximum number of bytes in ETHERNET packet */
                          /* (used by ethernet drivers)   */
                          
struct _ether 
{
    UINT8 eth_dest[ETH_ALEN];    /* where the packet is going  */
    UINT8 eth_source[ETH_ALEN];  /* who it came from           */
    UINT16 eth_type;              /* Ethernet packet type for 802.3 */
                                /* or length of (IP layer + LLC,SNAP) if 802.2   */
};

#define HW_Address_Size     6     /* Length of Ethernet Addresses           */
#define TYPE_LENGTH         2     /* Length of Header Type/Length Field     */  
#define MTU_Size            1500  /* MAX Transmission Unit, excluding media */
                                  /*  header length for ethernet            */

/* Ethernet header size:  dest addr, source addr, Type/Length               */
#define ETH_HeaderSize      ((HW_Address_Size * 2) + TYPE_LENGTH)

/* About Garfield chip, pessia */
#if 0
#define GPIO_MAC_RESET			(0x01UL<<12)   //PE12
#define GPIO_MAC_IRQ			(0x01UL<<9)   //PE9
#else
#define GPIO_MAC_RESET			(0x01UL<<8)		//PB8
#define GPIO_MAC_IRQ			(0x01UL<<2)		//PH2
#endif

#define setbit_gpio(addr, value)	*((volatile unsigned long*)addr) |= (unsigned long)(value)
#define clearbit_gpio(addr, value)	*((volatile unsigned long*)addr) &= ~((unsigned long)value)

NU_HISR  Ether_Xmit;
NU_HISR  Ether_Rcv;

volatile UINT32 et_data_ptr;
volatile UINT32 et_data_len;

int      Hisr_Activated = 0;

STATUS Rtl8019_Transmit(DV_DEVICE_ENTRY *dev, NET_BUFFER *buf_ptr);
STATUS Rtl8019_Receive(DV_DEVICE_ENTRY *device);
STATUS  Rtl8019_Ioctl(DV_DEVICE_ENTRY *dev, INT option, DV_REQ *d_req);


/* ********************************************************************   */
/* ********************************************************************   */
/* I/O ROUTINES                                                           */
/* ********************************************************************   */
/* ********************************************************************   */

/* tbd: rep move simulated in 'C'   */
void insw(IOADDRESS ioaddr, PFWORD dst, int n)
{
    while (n--)
        *dst++ = (word)INWORD(ioaddr);
}

void insb(IOADDRESS ioaddr, PFBYTE dst, int n)
{
    while (n--)
        *dst++ = INBYTE(ioaddr);
}

void outsw(IOADDRESS ioaddr, PFWORD src, int n)
{
    while (n--)
        OUTWORD(ioaddr, *src++);
}

void outsb(IOADDRESS ioaddr, PFCBYTE src, int n)
{
    while (n--)
        OUTBYTE(ioaddr, *src++);
}


#define NEW_WAIT 1

#define DISPLAY_ERROR   0   /* display error during interrupt */
#define DEBUG_RING      0
#define DEBUG_NIC       1

#if (DEBUG_RING)
int recovery_count = 0;     /* count of ring buffer overflows */
#endif

/* ********************************************************************   */
#define ETHER_MIN_LEN   64                  /* includes header */
#define ETHER_MAX_LEN   (ETHERSIZE+4)       /* includes header */
#define CRC_LEN         4

#define EROUND  ((sizeof(struct _ether) + 3) & ~3)
#define EOFF    (EROUND - sizeof(struct _ether))

NE2000_SOFTC KS_FAR ne2000softc[1];
extern KS_CONSTANT UINT8 KS_FAR test_pattern[32];

/* ********************************************************************   */
void ne2000_getmcaf(PFBYTE mclist, int bytesmclist, PFBYTE af);
void ne2000_reset(/*PIFACE pi, */PNE2000_SOFTC sc);
void ne2000_interrupt(int minor_no);

int  ne2000_probe_Novell(/*PIFACE pi, */PNE2000_SOFTC sc);
void ne2000_stop(PNE2000_SOFTC sc);

int ne2000_set_mac_addr (UINT8 *mac_addr);

void    ne2000_init(/*PIFACE pi, */PNE2000_SOFTC sc);
void    ne2000_pio_readmem(PNE2000_SOFTC sc, UINT16 src, PFBYTE dst, int amount);
BOOLEAN ne2000_pio_write_pkt(/*PIFACE pi, */PNE2000_SOFTC sc, PFCBYTE packet, int length, UINT16 dst);
UINT16    ne2000_ring_copy(PNE2000_SOFTC sc, UINT16 src, PFBYTE dst, UINT16 amount);
void    ne2000_ring_overflow_recovery2(void);
void    ne2000_get_packet(/*PIFACE pi, */PNE2000_SOFTC sc, UINT16 nic_buf, int len, BOOLEAN rint);
void    ne2000_read_ring_pkt(/*PIFACE pi, */PNE2000_SOFTC sc, BOOLEAN rint);

/* ********************************************************************   */
/* MEMORY MANAGMENT                                                       */
/* ********************************************************************   */ 
#define iface_to_softc() (PNE2000_SOFTC) &ne2000softc[0]
#define off_to_softc()   (PNE2000_SOFTC) &ne2000softc[0]

/*
 * Probe and vendor-specific initialization routine for NE1000/2000 boards.
 */
int ne2000_probe_Novell(PNE2000_SOFTC sc)
{
UINT8 tmp;
IOADDRESS nic_addr;
IOADDRESS asic_addr;

    /* meaningless, the asic addr i think maybe used on PC's netcard */
    sc->asic_addr = (IOADDRESS) (sc->ia_iobase + (UINT16) NE2000_NOVELL_ASIC_OFFSET);
    asic_addr = sc->asic_addr; /* used in the macro to calculate register pointers */
    ASSIGN_ASIC_ADDR(NE2000_NOVELL_DATA,  asic_addr_NE2000_NOVELL_DATA)
    ASSIGN_ASIC_ADDR(NE2000_NOVELL_RESET, asic_addr_NE2000_NOVELL_RESET)

    sc->nic_addr = (IOADDRESS)(sc->ia_iobase + NE2000_NOVELL_NIC_OFFSET);
    nic_addr = sc->nic_addr; /* used in the macro to calculate register pointers */

#if 0
    /* Set PE12 output GPIO */
    setbit_gpio(PORTE_SEL, GPIO_MAC_RESET);	//normal GPIO
    clearbit_gpio(PORTE_DATA, GPIO_MAC_RESET);//low level
    clearbit_gpio(PORTE_DIR, GPIO_MAC_RESET);	//output

	/* Hard Reset RTL8019AS chip */
    clearbit_gpio(PORTE_DATA, GPIO_MAC_RESET);//low level
    NU_Sleep(1);    /* 1 ms */
    setbit_gpio(PORTE_DATA, GPIO_MAC_RESET);//high level
    NU_Sleep(10);/* 2 ms */
    clearbit_gpio(PORTE_DATA, GPIO_MAC_RESET);//low level
    NU_Sleep(150);/* 100 ms */
#else
	/* Set PB8 output GPIO */
    setbit_gpio  (PORTB_SEL,  GPIO_MAC_RESET);	//normal GPIO
    clearbit_gpio(PORTB_DATA, GPIO_MAC_RESET);	//low level
    clearbit_gpio(PORTB_DIR,  GPIO_MAC_RESET);	//output

	/* Hard Reset RTL8019AS chip */
    clearbit_gpio(PORTB_DATA, GPIO_MAC_RESET);	//low level
    NU_Sleep(1);    /* 1 ms */
    setbit_gpio  (PORTB_DATA, GPIO_MAC_RESET);	//high level
    NU_Sleep(10);/* 2 ms */
    clearbit_gpio(PORTB_DATA, GPIO_MAC_RESET);	//low level
    NU_Sleep(150);/* 100 ms */
#endif

    /* Soft Reset RTL8019AS chip */
    tmp = INBYTE(REF_ASIC_ADDR(asic_addr_NE2000_NOVELL_RESET));
    OUTBYTE(REF_ASIC_ADDR(asic_addr_NE2000_NOVELL_RESET), tmp);
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_CR), NE2000_CR_RD2 | NE2000_CR_PAGE_0 | NE2000_CR_STP);
    NU_Sleep(100);    /* 10 ms */
	
    /* initialize DCR for byte operations.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_DCR), NE2000_DCR_FT1 | NE2000_DCR_LS); // byte-wide DMA transfer
    /* Set the start/end page address of the receive buffer ring */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_PSTART),8192 / NE2000_PAGE_SIZE);	//this value is overridden in ne2000_init
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_PSTOP), 16384 / NE2000_PAGE_SIZE);

#if DATA_BUS_16BIT
    sc->isa16bit = 1; //   1
#else
/* 8-bit access, which means the DATA bus of 8019 could be 8-line.
  * The endian problem could be ignored by using 8-bit access. */
    sc->isa16bit = 0; 
#endif

#define MEMSIZE  16384	
#define MEMSTART 16384	//0x4000

    sc->mem_start = MEMSTART; // the start page address of SRAM (16K)
    sc->mem_size = MEMSIZE;
    sc->mem_end = (UINT16)((long)MEMSTART + (long)MEMSIZE); // the end page address of SRAM (16K)

    /* XMIT Page offset is the begining of ram to the NE
       RCV Page offset is xmit offset + size of xmite ring 
       RCV End is Begining of ram + size of rem */
    sc->tx_page_start = (UINT16) (MEMSTART / NE2000_PAGE_SIZE); // the start page address of the XMIT buffer ring
    /* The size of the XMIT buffer ring is 6-page, and the remained pages are used by the receive buffer ring */
    sc->rec_page_start = (UINT16)((MEMSTART / NE2000_PAGE_SIZE) + NE2000_TXBUF_SIZE);
    sc->rec_page_stop =  (UINT16) ((MEMSTART / NE2000_PAGE_SIZE) + MEMSIZE / NE2000_PAGE_SIZE);
    /* The real address of the start of the receive buffer ring */
    sc->mem_ring = MEMSTART + NE2000_PAGE_SIZE * NE2000_TXBUF_SIZE;
	
    //ne2000_pio_readmem(sc, 0, romdata, 16);
    //for (n = 0; n < ETH_ALEN; n++)
    //    pi->addr.my_hw_addr[n] = romdata[n*(sc->isa16bit+1)];

    /* Clear any pending interrupts that might have occurred above.   */
    OUTBYTE(REF_REG_ADDR(nic_addr_NE2000_P0_ISR), 0xff);

    return (1);
}

/* ********************************************************************   */
/* OPEN and CLOSE routines.                                               */
/* ********************************************************************   */

void ne2000_close(/*PIFACE pi*/)                     /*__fn__*/
{
PNE2000_SOFTC sc;

    sc = iface_to_softc();
    if (!sc)
        return;
    ne2000_stop(sc);
}

void enable_ne2000_irq ( void )
{
#if 0
	setbit_gpio(PORTE_DIR, GPIO_MAC_IRQ);		//input
	setbit_gpio(PORTE_SEL, GPIO_MAC_IRQ);		//common gpio

//	setbit_gpio(PORTE_INTRCTL, 0x1UL<<18);		//falling edge irq
//	setbit_gpio(PORTE_INTRCTL, 0x0UL<<18);		//rising edge irq
	setbit_gpio(PORTE_INTRCTL, 0x2UL<<18);		//high level irq
//	setbit_gpio(PORTE_INTRCTL, 0x3UL<<18);		//low level irq

	setbit_gpio(PORTE_INCTL, GPIO_MAC_IRQ);		//external irq source
	//setbit_gpio(PORTE_INTRCLR, GPIO_MAC_IRQ);	//clear irq
	//setbit_gpio(PORTE_INTRCLR, 0xfffUL);	//clear irq
	*((volatile unsigned long*)PORTE_INTRCLR) = 0xfffUL;
	
	/* Clear mask bit in Interrupt Mask Register */
	unmask_irq(10);		//external IRQ9 is 10th bit

	/* Enable the interrupt in Interrupt Control Register */
	irq_enable(10);		//external IRQ9 is 10th bit
#else
	setbit_gpio(PORTH_DIR, GPIO_MAC_IRQ);		//input
	setbit_gpio(PORTH_SEL, GPIO_MAC_IRQ);		//common gpio
	setbit_gpio(PORTH_INTRCTL, 0x2UL<<4);		//high level irq

	setbit_gpio(PORTH_INCTL, GPIO_MAC_IRQ);		//external irq source
	*((volatile unsigned long*)PORTH_INTRCLR) = 0x6fUL;
	
	/* Clear mask bit in Interrupt Mask Register */
	unmask_irq(15);		//external IRQ9 is 10th bit

	/* Enable the interrupt in Interrupt Control Register */
	irq_enable(15);		//external IRQ9 is 10th bit
#endif
}

/* ********************************************************************   */
/* Install interface into kernel networking data structures.              */
BOOLEAN ne2000_open(VOID)
{
PNE2000_SOFTC sc;
VOID (*oldfptr)(INT);

    sc = iface_to_softc();
    if (!sc)
    {
        //set_errno(ENUMDEVICE);
        return(FALSE);
    }

    tc_memset((PFBYTE) sc, 0, sizeof(*sc));

    /* determine which device and initialize    */
    sc->ia_iobase = (IOADDRESS) CFG_NE2000_IOBASE; 
    sc->ia_irq    = CFG_NE2000_IRQ; 

    if (!(ne2000_probe_Novell(sc)))
    {
        //DEBUG_ERROR("ne2000probe failed", NOVAR, 0, 0);
        //set_errno(EPROBEFAIL);
        return(FALSE);
    }
    
    /* Set interface to stopped condition (reset).   */
    ne2000_stop(sc);

#if 0
    /* Register interrupt lisr   */
    NU_Register_LISR(sc->ia_irq/*22*/, ne2000_interrupt, &oldfptr);
    rI_ISPR |= BIT_EINT1;		//clear pending bit
    rINTMSK &= ~BIT_EINT1;		//enable interrupt bit
#else
	/* Register a physical interrupt handler for Garfield chip. 
	 * pessia 2005/01/12 */
	 
	/* The code has been removed into "Rtl8019_Initialize()" */

#endif

    ne2000_reset(sc);
    

⌨️ 快捷键说明

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