Esempio n. 1
0
void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
                  qemu_irq irq, void* mem_opaque,
                  void (*memory_rw)(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len, int is_write))
{
    dp8393xState *s;

    qemu_check_nic_model(nd, "dp83932");

    s = qemu_mallocz(sizeof(dp8393xState));

    s->mem_opaque = mem_opaque;
    s->memory_rw = memory_rw;
    s->it_shift = it_shift;
    s->irq = irq;
    s->watchdog = qemu_new_timer(vm_clock, dp8393x_watchdog, s);
    s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */

    s->conf.macaddr = nd->macaddr;
    s->conf.vlan = nd->vlan;
    s->conf.peer = nd->netdev;

    s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, nd->model, nd->name, s);

    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
    qemu_register_reset(nic_reset, s);
    nic_reset(s);

    s->mmio_index = cpu_register_io_memory(dp8393x_read, dp8393x_write, s);
    cpu_register_physical_memory(base, 0x40 << it_shift, s->mmio_index);
}
Esempio n. 2
0
void dp83932_init(NICInfo *nd, hwaddr base, int it_shift,
                  MemoryRegion *address_space,
                  qemu_irq irq, void* mem_opaque,
                  void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf, int len, int is_write))
{
    dp8393xState *s;

    qemu_check_nic_model(nd, "dp83932");

    s = g_malloc0(sizeof(dp8393xState));

    s->address_space = address_space;
    s->mem_opaque = mem_opaque;
    s->memory_rw = memory_rw;
    s->it_shift = it_shift;
    s->irq = irq;
    s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
    s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */

    s->conf.macaddr = nd->macaddr;
    s->conf.peers.ncs[0] = nd->netdev;

    s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, nd->model, nd->name, s);

    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
    qemu_register_reset(nic_reset, s);
    nic_reset(s);

    memory_region_init_io(&s->mmio, NULL, &dp8393x_ops, s,
                          "dp8393x", 0x40 << it_shift);
    memory_region_add_subregion(address_space, base, &s->mmio);
}
//************************************
//************************************
//********** INITIALISE NIC **********
//************************************
//************************************
//Call with:
//0 = allow speed 10 / 100 Mbps
//1 = force speed to 10 Mbps
void nic_initialise (BYTE init_config)
{
	WORD data;

	//-----------------------------
	//----- DO HARDWARE RESET -----
	//-----------------------------
	//POWER UP - WAIT 50MS
	nic_delay_ms(50);

	//RESET THE NIC
	nic_reset();

	//WAIT 50MS
	nic_delay_ms(50);

	//-------------------------------------------------
	//----- WRITE THE NIC CONFIGURATION REGISTERS ----- 
	//-------------------------------------------------
	//(The eeprom is not present so the nic defaults to base address 0x0300)

	//----- SEND MMU RESET COMMAND -----
	//Set nic bank 2
	nic_write(NIC_REG_BANK, 0x3302);

	//MMU Command
	//(Reset MMU to initial state)
	nic_write(NIC_REG_MMU_COMMAND, 0x0040);
	
	//Wait for the busy flag to clear
	while (nic_read(NIC_REG_MMU_COMMAND) & 0x0001)
		;

	//----- DO BANK 0 REGISTERS -----
	//Set bank 0
	nic_write(NIC_REG_BANK, 0x3300);

	//Transmit Control (done at end)
	//nic_write(NIC_REG_TCR, 0x0000);

	//EPH Status
	//nic_write(NIC_REG_EPH_STATUS, 0x0000);

	//Receive Control (done at end)
	//nic_write(NIC_REG_RCR, 0x0000);

	//Counter
	//nic_write(NIC_REG_COUNTER, 0x0000);

	//Memory Information
	//nic_write(NIC_REG_MIR, 0x0000);

	//Receive / Phy Control Register
	//(Speed and duplex auto negotiation on, LEDA function, LED B function)
	nic_write(NIC_REG_RPCR, NIC_CONST_PPCR_REGISTER);

	//Reserved
	//nic_write(NIC_REG_RESERVED, 0x0000);

	//----- DO BANK 1 REGISTERS -----
	//Set Bank 1
	nic_write(NIC_REG_BANK, 0x3301);

	//Configuration
	//(No wait states on ARDY except for data reg if not ready, external MII disabled)
	nic_write(NIC_REG_CONFIG, 0xb0b1);

	//Base Address
	//nic_write(NIC_REG_BASE, 0x0000);

	//Individual Address (MAC) 0-1 (Bit 0 is first bit of address on the cable)
	nic_write(NIC_REG_IA0_1, (((WORD)our_mac_address.v[1] << 8) + (WORD)our_mac_address.v[0]));		//(Litle endian)

	//Individual Address (MAC) 2-3
	nic_write(NIC_REG_IA2_3, (((WORD)our_mac_address.v[3] << 8) + (WORD)our_mac_address.v[2]));		//(Litle endian)

	//Individual Address (MAC) 4-5
	nic_write(NIC_REG_IA4_5, (((WORD)our_mac_address.v[5] << 8) + (WORD)our_mac_address.v[4]));		//(Litle endian)

	//General Purpose
	//nic_write(NIC_REG_GEN_PURPOSE, 0x0000);

	//Control
	//(Bad CRC packets are dumped, Auto release TX memory after good TX, Link Irq on, counter roll over irq off, tx error irq off)
	nic_write(NIC_REG_CONTROL, 0x1a90);

	//----- DO BANK 2 REGISTERS -----
	//Set bank 2
	nic_write(NIC_REG_BANK, 0x3302);

	//MMU Command
	//(Reset MMU to initial state - already done above)
	//nic_write(NIC_REG_MMU_COMMAND, 0x0040);
	//Wait for the busy flag to clear
	//while (nic_read(NIC_REG_MMU_COMMAND) & 0x0001)
	//	;

	//Packet Number
	//nic_write(NIC_REG_PNR, 0x0000);		//(Litle endian)

	//Fifo ports
	//nic_write(NIC_REG_FIFO_PORTS, 0x0000);

	//Pointer
	//nic_write(NIC_REG_POINTER, 0x0000);

	//Data
	//nic_write(NIC_REG_DATA, 0x0000);

	//Data High
	//nic_write(NIC_REG_DATA_H, 0x0000);

	//Interrupt Status
	//nic_write(NIC_REG_INTERRUPT, 0x001f);		//(Litle endian)

	//----- DO BANK 3 REGISTERS -----
	//Select bank 3
	nic_write(NIC_REG_BANK, 0x3303);

	//Multicast 0-1
	nic_write(NIC_REG_MT0_1, 0x0000);

	//Multicast 2-3
	nic_write(NIC_REG_MT2_3, 0x0000);

	//Multicast 4-5
	nic_write(NIC_REG_MT4_5, 0x0000);

	//Multicast 6-7
	nic_write(NIC_REG_MT6_7, 0x0000);

	//Management
	//nic_write(NIC_REG_MGMT, 0x0000);

	//Revision
	//nic_write(NIC_REG_REVISION, 0x0000);

	//Early Receive
	//(Receive IRQ Threshold = max)
	nic_write(NIC_REG_ERCV, 0x001f);

	//----------------------------------------------
	//----- WRITE TO THE PHY CONTROL REGISTERS -----
	//----------------------------------------------

	//----- SET 'AUTO NEGOTIATE AVAILABLE SPEEDS AND DUPLEX MODES' -----

	//WE USE HALF DUPLEX MODE
	if (init_config)
	{
		//Only 10Mbps available
		data = 0x0021;
	}
	else
	{
		//10/100Mbps available
		data = 0x00a1;
	}

	nic_write_phy_register(NIC_PHY_AUTO_NEG_ADVERTISEMENT, data);

	//----- TURN OFF ISOLATION MODE SO AUTO NEGOTIATION STARTS -----
	nic_write_phy_register(NIC_PHY_CONTROL, 0x1000);

	//----------------------------
	//----- ENABLE TX AND RX -----
	//----------------------------
	//Set bank 0
	nic_write(NIC_REG_BANK, 0x3300);

	//Transmit Control
	nic_write(NIC_REG_TCR, NIC_CONST_TX_CTRL_REGISTER);

	//Receive Control
	nic_write(NIC_REG_RCR, NIC_CONST_RX_CTRL_REGISTER);

	//Select nic bank 2
	nic_write(NIC_REG_BANK, 0x3302);

	//Interrupt Status
	//(Clear the TX INT bit if set)
	nic_write(NIC_REG_INTERRUPT, (NIC_CONST_IRQ_REGISTER | 0x0002));		//(little endian)
	
	nic_is_linked = 0;
	nic_speed_is_100mbps = 0;
	nic_rx_packet_waiting_to_be_dumped = 0;
}
//************************************
//************************************
//********** INITIALISE NIC **********
//************************************
//************************************
//Call with:
//init_config = don't care (speed configuration options not available with this IC)
void nic_initialise (BYTE init_config)
{

	//-----------------------------
	//----- DO HARDWARE RESET -----
	//-----------------------------
	nic_delay_ms(10);

	//RESET THE NIC
	nic_reset();

	nic_delay_ms(50);

	//Wait for reset bit to be set
	while((nic_read(NIC_REG_ISR) & 0x80) == 0);

	//-------------------------------------------------
	//----- WRITE THE NIC CONFIGURATION REGISTERS ----- 
	//-------------------------------------------------
	//As the nic doesn't have its own eeprom we need to setup the bank3 config registers
	//Note that the DO pin of where the eeprom would be connected must be pulled low.
	//Config 1 and 2 are not altered by the eeprom change as in jumper mode they use the default state of defined pins
	//Config 3 is affected by the eeprom and contains several bits that are read only (i.e. can only be set by the eeprom).  The important pin
	//is the FUDUP pin which must be low, or the nic looses transmissions by assuming that it can tx while rx is active.  This means that the
	//LED control pins also have to be low.  Ideally the LED pins would be high as it gives the more useful 'Link' and 'Active' led outptus,
	//but this is the compromise.

	//Stop DMA and Set page 3
	nic_write(NIC_REG_CR, 0xe1);

	//Enable writing to the config registers
	nic_write(NIC_REG_9346CR, 0xc0);

	//Config 0 is read only
	//nic_write(NIC_REG_CONFIG0, 0x);

	//Disable IRQ's (rest is set by jumpers)
	nic_write(NIC_REG_CONFIG1, 0x00);

	//Set network medium type
	nic_write(NIC_REG_CONFIG2, 0x00);

	//Set not in sleep mode, not in powerdown mode
	nic_write(NIC_REG_CONFIG3, 0x30);

	//Disable writing to the config registers
	nic_write(NIC_REG_9346CR, 0x00);

	nic_delay_ms(50);

	//Set page 0
	nic_write(NIC_REG_CR, 0x21);

	//Setup the the Data Configuration Register (DCR)
	nic_write(NIC_REG_DCR, 0x58);

	//Clear the remote byte count registers
	nic_write(NIC_REG_RBCR0, 0x00);
	nic_write(NIC_REG_RBCR1, 0x00);

	//Initialise the receive configuration register (monitor mode)
	nic_write(NIC_REG_RCR, 0x20);

	//Turn on loopback mode
	nic_write(NIC_REG_TCR, 0x02);

	//Initialise the receive buffer ring
	//RTL8019AS has 16K bytes of ram
	//Tx buffer starts at 0x4000
	//Rx ring starts / tx buffer ends at 0x0x4600 - this gives 1536 bytes to tx, max tx size allowed on ethernet is 1500 bytes.
	//Rx ring ends at 0x6000 - this gives 6656 bytes to rx (used in 256 byte pages by nic)
	nic_write(NIC_REG_BNDRY, NIC_RX_START_LOC_IN_RING);
	nic_write(NIC_REG_PSTART, NIC_RX_START_LOC_IN_RING);
	nic_write(NIC_REG_PSTOP, NIC_RX_END_LOC_IN_RING);

	//Clear the Interrupt Status Register
	nic_write(NIC_REG_ISR, 0xff);

	//Initialise the interrupt mask register (all irq's disabled)
	nic_write(NIC_REG_IMR, 0x00);

	//Stop DMA and Set page 1
	nic_write(NIC_REG_CR, 0x61);

	//Set the MAC address in the nic registers
	nic_write(NIC_REG_PAR0, our_mac_address.v[0]);
	nic_write(NIC_REG_PAR1, our_mac_address.v[1]);
	nic_write(NIC_REG_PAR2, our_mac_address.v[2]);
	nic_write(NIC_REG_PAR3, our_mac_address.v[3]);
	nic_write(NIC_REG_PAR4, our_mac_address.v[4]);
	nic_write(NIC_REG_PAR5, our_mac_address.v[5]);

	//Initialise the multicast address registers
	//Set all MARx to 0 = reject all multicast
	nic_write(NIC_REG_MAR0, 0x00);
	nic_write(NIC_REG_MAR1, 0x00);
	nic_write(NIC_REG_MAR2, 0x00);
	nic_write(NIC_REG_MAR3, 0x00);
	nic_write(NIC_REG_MAR4, 0x00);
	nic_write(NIC_REG_MAR5, 0x00);
	nic_write(NIC_REG_MAR6, 0x00);
	nic_write(NIC_REG_MAR7, 0x00);

	//Initialise the current pointer (to the same addr as the rx buffer start)
	nic_write(NIC_REG_CURR, NIC_RX_START_LOC_IN_RING);

	//Initialize the interface

	//Set page 0
	nic_write(NIC_REG_CR, 0x21);

	//Wait 1.6mS for any tx/rx to complete
	nic_delay_ms(2);

	//Normal operation, initialize remote dma, fifo threshhold 8 bytes
	nic_write(NIC_REG_DCR, 0xd8);

	//Remote dma byte count = 0000h
	nic_write(NIC_REG_RBCR0, 0x00);
	nic_write(NIC_REG_RBCR1, 0x00);

	//Remote dma start address = 4000h
	nic_write(NIC_REG_RSAR0, 0x00);
	nic_write(NIC_REG_RSAR1, NIC_TX_START_LOC_IN_RING);

	//Monitor mode
	nic_write(NIC_REG_RCR, 0x20);

	//Place NIC in loopback
	nic_write(NIC_REG_TCR, 0x02);

	//Clear all interrupt flags
	nic_write(NIC_REG_ISR, 0xff);

	//Unmask all interrupts
	nic_write(NIC_REG_IMR, 0xff);

	//4000h < tx buffer
	nic_write(NIC_REG_TPSR, NIC_TX_START_LOC_IN_RING);

	//Stop nic, change to register page 1
	nic_write(NIC_REG_CR, 0x61);

	//Next place to rx a packet
	nic_write(NIC_REG_CURR, NIC_RX_START_LOC_IN_RING);

	//Start nic, abort remote dma (page 0)
	nic_write(NIC_REG_CR, 0x22);

	//Change from loopback mode to normal op
	nic_write(NIC_REG_TCR, 0x00);

	//Accept broadcast packets
	nic_write(NIC_REG_RCR, 0x04);

	//Clear any pending interrupts
	nic_write(NIC_REG_ISR, 0xff);

	//Put in start mode
	//Start nic and set page 1
	nic_write(NIC_REG_CR, 0x22);

	//Initialise the Transmit Configuration register
	nic_write(NIC_REG_TCR, 0x00);					//Normal tx, CRC appended by transmitter, remote tx disable command disabled (also set in the receive overlflow routine)

	//Accept broadcast packets
	nic_write(NIC_REG_RCR, 0x04);					//Accept broadcast but not multicast, packets with receive errors are rejected

	//----- DO FINAL FLAGS SETUP -----
	nic_is_linked = 0;
	nic_speed_is_100mbps = 0;
	nic_rx_packet_waiting_to_be_dumped = 0;
}