Updated NE2000 driver (cleaned up, especially PCI), new location for ROM files! Cross-tested with SLiRP and PCap for NE2000 and RTL8029 on DOS, NT 3.51.5, W2K.4, Debian 3.1 and 7.6. NT and Deb 3.1 don't like the RTL, and never will.
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Try to load a support DLL.
|
* Try to load a support DLL.
|
||||||
*
|
*
|
||||||
* Version: @(#)win_dynld.c 1.0.1 2017/05/21
|
* Version: @(#)win_dynld.c 1.0.2 2017/05/24
|
||||||
*
|
*
|
||||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
* Copyright 2017 Fred N. van Kempen
|
* Copyright 2017 Fred N. van Kempen
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
void *
|
void *
|
||||||
dynld_module(const char *name, dllimp_t *table)
|
dynld_module(const char *name, dllimp_t *table)
|
||||||
{
|
{
|
||||||
HANDLE h;
|
HMODULE h;
|
||||||
dllimp_t *imp;
|
dllimp_t *imp;
|
||||||
void *func;
|
void *func;
|
||||||
char **foo;
|
char **foo;
|
||||||
@@ -60,5 +60,5 @@ void
|
|||||||
dynld_close(void *handle)
|
dynld_close(void *handle)
|
||||||
{
|
{
|
||||||
if (handle != NULL)
|
if (handle != NULL)
|
||||||
CloseHandle((HANDLE *)handle);
|
FreeLibrary((HMODULE)handle);
|
||||||
}
|
}
|
||||||
|
|||||||
543
src/net_ne2000.c
543
src/net_ne2000.c
@@ -11,7 +11,7 @@
|
|||||||
* NOTE: Its still a mess, but we're getting there. The file will
|
* NOTE: Its still a mess, but we're getting there. The file will
|
||||||
* also implement an NE1000 for 8-bit ISA systems.
|
* also implement an NE1000 for 8-bit ISA systems.
|
||||||
*
|
*
|
||||||
* Version: @(#)net_ne2000.c 1.0.6 2017/05/23
|
* Version: @(#)net_ne2000.c 1.0.7 2017/05/25
|
||||||
*
|
*
|
||||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
* Peter Grehan, grehan@iprg.nokia.com>
|
* Peter Grehan, grehan@iprg.nokia.com>
|
||||||
@@ -38,11 +38,23 @@
|
|||||||
#include "net_ne2000.h"
|
#include "net_ne2000.h"
|
||||||
#include "bswap.h"
|
#include "bswap.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef WALTJE
|
#ifdef WALTJE
|
||||||
# define ENABLE_NE2000_LOG 2
|
# define ENABLE_NE2000_LOG 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ROM BIOS file paths. */
|
||||||
|
#define ROM_PATH_NE1000 L"roms/network/ne1000/ne1000.rom"
|
||||||
|
#define ROM_PATH_NE2000 L"roms/network/ne2000/ne2000.rom"
|
||||||
|
#define ROM_PATH_RTL8029 L"roms/network/rtl8029as/rtl8029as.rom"
|
||||||
|
|
||||||
|
/* PCI info. */
|
||||||
|
#define PCI_VENDID 0x10ec /* Realtek, Inc */
|
||||||
|
#define PCI_DEVID 0x8029 /* RTL8029AS */
|
||||||
|
#define PCI_REGSIZE 256 /* size of PCI space */
|
||||||
|
|
||||||
|
|
||||||
/* For PCI. */
|
/* For PCI. */
|
||||||
typedef union {
|
typedef union {
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
@@ -211,7 +223,7 @@ typedef struct {
|
|||||||
bios_size,
|
bios_size,
|
||||||
bios_mask;
|
bios_mask;
|
||||||
bar_t pci_bar[2];
|
bar_t pci_bar[2];
|
||||||
uint8_t pci_regs[256];
|
uint8_t pci_regs[PCI_REGSIZE];
|
||||||
int tx_timer_index;
|
int tx_timer_index;
|
||||||
int tx_timer_active;
|
int tx_timer_active;
|
||||||
uint8_t maclocal[6]; /* configured MAC (local) address */
|
uint8_t maclocal[6]; /* configured MAC (local) address */
|
||||||
@@ -242,7 +254,7 @@ nelog(int lvl, const char *fmt, ...)
|
|||||||
|
|
||||||
/* reset - restore state to power-up, cancelling all i/o */
|
/* reset - restore state to power-up, cancelling all i/o */
|
||||||
static void
|
static void
|
||||||
nic_reset(void *priv, int reset)
|
nic_reset(void *priv)
|
||||||
{
|
{
|
||||||
nic_t *dev = (nic_t *)priv;
|
nic_t *dev = (nic_t *)priv;
|
||||||
int i;
|
int i;
|
||||||
@@ -310,12 +322,24 @@ nic_reset(void *priv, int reset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* chipmem_read/chipmem_write - access the 64K private RAM.
|
static void
|
||||||
The ne2000 memory is accessed through the data port of
|
nic_soft_reset(void *priv)
|
||||||
the asic (offset 0) after setting up a remote-DMA transfer.
|
{
|
||||||
Both byte and word accesses are allowed.
|
nic_t *dev = (nic_t *)priv;
|
||||||
The first 16 bytes contains the MAC address at even locations,
|
|
||||||
and there is 16K of buffer memory starting at 16K
|
memset(&(dev->ISR), 0x00, sizeof(dev->ISR));
|
||||||
|
dev->ISR.reset = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access the 32K private RAM.
|
||||||
|
*
|
||||||
|
* The NE2000 memory is accessed through the data port of the
|
||||||
|
* ASIC (offset 0) after setting up a remote-DMA transfer.
|
||||||
|
* Both byte and word accesses are allowed.
|
||||||
|
* The first 16 bytes contains the MAC address at even locations,
|
||||||
|
* and there is 16K of buffer memory starting at 16K.
|
||||||
*/
|
*/
|
||||||
static uint32_t
|
static uint32_t
|
||||||
chipmem_read(nic_t *dev, uint32_t addr, unsigned int len)
|
chipmem_read(nic_t *dev, uint32_t addr, unsigned int len)
|
||||||
@@ -390,14 +414,18 @@ chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* asic_read/asic_write - This is the high 16 bytes of i/o space
|
/*
|
||||||
(the lower 16 bytes is for the DS8390). Only two locations
|
* Access the ASIC I/O space.
|
||||||
are used: offset 0, which is used for data transfer, and
|
*
|
||||||
offset 0xf, which is used to reset the device.
|
* This is the high 16 bytes of i/o space (the lower 16 bytes
|
||||||
The data transfer port is used to as 'external' DMA to the
|
* is for the DS8390). Only two locations are used: offset 0,
|
||||||
DS8390. The chip has to have the DMA registers set up, and
|
* which is used for data transfer, and offset 0x0f, which is
|
||||||
after that, insw/outsw instructions can be used to move
|
* used to reset the device.
|
||||||
the appropriate number of bytes to/from the device.
|
*
|
||||||
|
* The data transfer port is used to as 'external' DMA to the
|
||||||
|
* DS8390. The chip has to have the DMA registers set up, and
|
||||||
|
* after that, insw/outsw instructions can be used to move
|
||||||
|
* the appropriate number of bytes to/from the device.
|
||||||
*/
|
*/
|
||||||
static uint32_t
|
static uint32_t
|
||||||
asic_read(nic_t *dev, uint32_t off, unsigned int len)
|
asic_read(nic_t *dev, uint32_t off, unsigned int len)
|
||||||
@@ -452,7 +480,7 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0f: /* Reset register */
|
case 0x0f: /* Reset register */
|
||||||
nic_reset(dev, 1);
|
nic_soft_reset(dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -468,7 +496,7 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len)
|
|||||||
static void
|
static void
|
||||||
asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len)
|
asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len)
|
||||||
{
|
{
|
||||||
nelog(3, "%s: asic write addr=0x%02x, value=0x%04x\n",
|
nelog(3, "%s: ASIC write addr=0x%02x, value=0x%04x\n",
|
||||||
dev->name, (unsigned)off, (unsigned) val);
|
dev->name, (unsigned)off, (unsigned) val);
|
||||||
switch(off) {
|
switch(off) {
|
||||||
case 0x00: /* Data register - see asic_read for a description */
|
case 0x00: /* Data register - see asic_read for a description */
|
||||||
@@ -523,8 +551,7 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* page0_read/page0_write - These routines handle reads/writes to
|
/* Handle reads/writes to the 'zeroth' page of the DS8390 register file. */
|
||||||
the 'zeroth' page of the DS8390 register file */
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
page0_read(nic_t *dev, uint32_t off, unsigned int len)
|
page0_read(nic_t *dev, uint32_t off, unsigned int len)
|
||||||
{
|
{
|
||||||
@@ -849,8 +876,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* page1_read/page1_write - These routines handle reads/writes to
|
/* Handle reads/writes to the first page of the DS8390 register file. */
|
||||||
the first page of the DS8390 register file */
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
page1_read(nic_t *dev, uint32_t off, unsigned int len)
|
page1_read(nic_t *dev, uint32_t off, unsigned int len)
|
||||||
{
|
{
|
||||||
@@ -934,8 +960,7 @@ page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* page2_read/page2_write - These routines handle reads/writes to
|
/* Handle reads/writes to the second page of the DS8390 register file. */
|
||||||
the second page of the DS8390 register file */
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
page2_read(nic_t *dev, uint32_t off, unsigned int len)
|
page2_read(nic_t *dev, uint32_t off, unsigned int len)
|
||||||
{
|
{
|
||||||
@@ -1078,7 +1103,7 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* page3_read/page3_write - writes to this page are illegal */
|
/* Writes to this page are illegal. */
|
||||||
static uint32_t
|
static uint32_t
|
||||||
page3_read(nic_t *dev, uint32_t off, unsigned int len)
|
page3_read(nic_t *dev, uint32_t off, unsigned int len)
|
||||||
{
|
{
|
||||||
@@ -1108,8 +1133,7 @@ page3_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* read_cr/write_cr - utility routines for handling reads/writes to
|
/* Routines for handling reads/writes to the Command Register. */
|
||||||
the Command Register */
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
read_cr(nic_t *dev)
|
read_cr(nic_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1410,7 +1434,9 @@ nic_update_bios(nic_t *dev)
|
|||||||
dev->bios_addr, dev->bios_size);
|
dev->bios_addr, dev->bios_size);
|
||||||
nelog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr);
|
nelog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr);
|
||||||
} else {
|
} else {
|
||||||
|
nelog(1, "%s: BIOS disabled\n", dev->name);
|
||||||
mem_mapping_disable(&dev->bios_rom.mapping);
|
mem_mapping_disable(&dev->bios_rom.mapping);
|
||||||
|
dev->bios_addr = 0;
|
||||||
if (dev->is_pci)
|
if (dev->is_pci)
|
||||||
dev->pci_bar[1].addr = 0;
|
dev->pci_bar[1].addr = 0;
|
||||||
}
|
}
|
||||||
@@ -1421,68 +1447,105 @@ static uint8_t
|
|||||||
nic_pci_read(int func, int addr, void *priv)
|
nic_pci_read(int func, int addr, void *priv)
|
||||||
{
|
{
|
||||||
nic_t *dev = (nic_t *)priv;
|
nic_t *dev = (nic_t *)priv;
|
||||||
|
uint8_t ret = 0x00;
|
||||||
|
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x00:
|
case 0x00: /* PCI_VID_LO */
|
||||||
return 0xec;
|
case 0x01: /* PCI_VID_HI */
|
||||||
case 0x01:
|
ret = dev->pci_regs[addr];
|
||||||
return 0x10;
|
break;
|
||||||
|
|
||||||
case 0x02:
|
case 0x02: /* PCI_DID_LO */
|
||||||
return 0x29;
|
case 0x03: /* PCI_DID_HI */
|
||||||
case 0x03:
|
ret = dev->pci_regs[addr];
|
||||||
return 0x80;
|
break;
|
||||||
|
|
||||||
case 0x2C:
|
case 0x04: /* PCI_COMMAND_LO */
|
||||||
return 0xF4;
|
case 0x05: /* PCI_COMMAND_HI */
|
||||||
case 0x2D:
|
ret = dev->pci_regs[addr];
|
||||||
return 0x1A;
|
break;
|
||||||
case 0x2E:
|
|
||||||
return 0x00;
|
|
||||||
case 0x2F:
|
|
||||||
return 0x11;
|
|
||||||
|
|
||||||
case 0x04:
|
case 0x06: /* PCI_STATUS_LO */
|
||||||
return dev->pci_regs[0x04]; /*Respond to IO and memory accesses*/
|
case 0x07: /* PCI_STATUS_HI */
|
||||||
case 0x05:
|
ret = dev->pci_regs[addr];
|
||||||
return dev->pci_regs[0x05];
|
break;
|
||||||
|
|
||||||
case 0x07:
|
case 0x08: /* PCI_REVID */
|
||||||
return 2;
|
ret = 0x00; /* Rev. 00 */
|
||||||
|
break;
|
||||||
|
case 0x09: /* PCI_PIFR */
|
||||||
|
ret = 0x00; /* Rev. 00 */
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x08:
|
case 0x0A: /* PCI_SCR */
|
||||||
return 0; /*Revision ID*/
|
ret = dev->pci_regs[addr];
|
||||||
case 0x09:
|
break;
|
||||||
return 0; /*Programming interface*/
|
|
||||||
|
|
||||||
case 0x0B:
|
case 0x0B: /* PCI_BCR */
|
||||||
return dev->pci_regs[0x0B];
|
ret = dev->pci_regs[addr];
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x10:
|
case 0x0C: /* (reserved) */
|
||||||
return 1; /*I/O space*/
|
ret = dev->pci_regs[addr];
|
||||||
case 0x11:
|
break;
|
||||||
return dev->pci_bar[0].addr_regs[1];
|
|
||||||
case 0x12:
|
|
||||||
return dev->pci_bar[0].addr_regs[2];
|
|
||||||
case 0x13:
|
|
||||||
return dev->pci_bar[0].addr_regs[3];
|
|
||||||
|
|
||||||
case 0x30:
|
case 0x0D: /* PCI_LTR */
|
||||||
return dev->pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/
|
case 0x0E: /* PCI_HTR */
|
||||||
case 0x31:
|
ret = dev->pci_regs[addr];
|
||||||
return (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18;
|
break;
|
||||||
case 0x32:
|
|
||||||
return dev->pci_bar[1].addr_regs[2];
|
|
||||||
case 0x33:
|
|
||||||
return dev->pci_bar[1].addr_regs[3];
|
|
||||||
|
|
||||||
case 0x3C:
|
case 0x0F: /* (reserved) */
|
||||||
return dev->pci_regs[0x3C];
|
ret = dev->pci_regs[addr];
|
||||||
case 0x3D:
|
break;
|
||||||
return dev->pci_regs[0x3D];
|
|
||||||
|
case 0x10: /* PCI_BAR 7:5 */
|
||||||
|
ret = (dev->pci_bar[0].addr_regs[1] & 0xe0) | 0x01;
|
||||||
|
break;
|
||||||
|
case 0x11: /* PCI_BAR 15:8 */
|
||||||
|
ret = dev->pci_bar[0].addr_regs[1];
|
||||||
|
break;
|
||||||
|
case 0x12: /* PCI_BAR 23:16 */
|
||||||
|
ret = dev->pci_bar[0].addr_regs[2];
|
||||||
|
break;
|
||||||
|
case 0x13: /* PCI_BAR 31:24 */
|
||||||
|
ret = dev->pci_bar[0].addr_regs[3];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x2C: /* PCI_SVID_LO */
|
||||||
|
case 0x2D: /* PCI_SVID_HI */
|
||||||
|
ret = dev->pci_regs[addr];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x2E: /* PCI_SID_LO */
|
||||||
|
case 0x2F: /* PCI_SID_HI */
|
||||||
|
ret = dev->pci_regs[addr];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x30: /* PCI_ROMBAR */
|
||||||
|
ret = dev->pci_bar[1].addr_regs[0] & 0x01;
|
||||||
|
break;
|
||||||
|
case 0x31: /* PCI_ROMBAR 15:11 */
|
||||||
|
ret = (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18;
|
||||||
|
break;
|
||||||
|
case 0x32: /* PCI_ROMBAR 23:16 */
|
||||||
|
ret = dev->pci_bar[1].addr_regs[2];
|
||||||
|
break;
|
||||||
|
case 0x33: /* PCI_ROMBAR 31:24 */
|
||||||
|
ret = dev->pci_bar[1].addr_regs[3];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3C: /* PCI_ILR */
|
||||||
|
ret = dev->pci_regs[addr];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3D: /* PCI_IPR */
|
||||||
|
ret = dev->pci_regs[addr];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
nelog(2, "%s: PCI_Read(%d, %04x) = %02x\n", dev->name, func, addr, ret);
|
||||||
|
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1491,28 +1554,54 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
{
|
{
|
||||||
nic_t *dev = (nic_t *)priv;
|
nic_t *dev = (nic_t *)priv;
|
||||||
|
|
||||||
|
nelog(2, "%s: PCI_Write(%d, %04x, %02x)\n", dev->name, func, addr, val);
|
||||||
|
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x04:
|
case 0x04: /* PCI_COMMAND_LO */
|
||||||
|
val &= 0x03;
|
||||||
nic_ioremove(dev, dev->base_address);
|
nic_ioremove(dev, dev->base_address);
|
||||||
if (val & PCI_COMMAND_IO) {
|
if (val & PCI_COMMAND_IO)
|
||||||
nic_ioset(dev, dev->base_address);
|
nic_ioset(dev, dev->base_address);
|
||||||
|
#if 0
|
||||||
|
if (val & PCI_COMMAND_MEMORY) {
|
||||||
|
...
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
dev->pci_regs[addr] = val;
|
dev->pci_regs[addr] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10:
|
case 0x0C: /* (reserved) */
|
||||||
val &= 0xfc;
|
dev->pci_regs[addr] = val;
|
||||||
val |= 1;
|
break;
|
||||||
case 0x11: case 0x12: case 0x13:
|
|
||||||
/* I/O Base set. */
|
case 0x0D: /* PCI_LTR */
|
||||||
/* First, remove the old I/O, if old base was >= 0x280. */
|
dev->pci_regs[addr] = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0E: /* PCI_HTR */
|
||||||
|
dev->pci_regs[addr] = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0F: /* (reserved) */
|
||||||
|
dev->pci_regs[addr] = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x10: /* PCI_BAR */
|
||||||
|
val &= 0xfc; /* 0xe0 acc to RTL DS */
|
||||||
|
val |= 0x01; /* re-enable IOIN bit */
|
||||||
|
/*FALLTHROUGH*/
|
||||||
|
|
||||||
|
case 0x11: /* PCI_BAR
|
||||||
|
case 0x12: /* PCI_BAR
|
||||||
|
case 0x13: /* PCI_BAR */
|
||||||
|
/* Remove old I/O. */
|
||||||
nic_ioremove(dev, dev->base_address);
|
nic_ioremove(dev, dev->base_address);
|
||||||
|
|
||||||
/* Then let's set the PCI regs. */
|
/* Set new I/O as per PCI request. */
|
||||||
dev->pci_bar[0].addr_regs[addr & 3] = val;
|
dev->pci_bar[0].addr_regs[addr & 3] = val;
|
||||||
|
|
||||||
/* Then let's calculate the new I/O base. */
|
/* Then let's calculate the new I/O base. */
|
||||||
dev->base_address = dev->pci_bar[0].addr & 0xff00;
|
dev->base_address = dev->pci_bar[0].addr & 0xffe0;
|
||||||
|
|
||||||
/* Log the new base. */
|
/* Log the new base. */
|
||||||
nelog(1, "%s: PCI: new I/O base is %04X\n",
|
nelog(1, "%s: PCI: new I/O base is %04X\n",
|
||||||
@@ -1520,9 +1609,12 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
/* We're done, so get out of the here. */
|
/* We're done, so get out of the here. */
|
||||||
if (val & PCI_COMMAND_IO)
|
if (val & PCI_COMMAND_IO)
|
||||||
nic_ioset(dev, dev->base_address);
|
nic_ioset(dev, dev->base_address);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case 0x30: case 0x31: case 0x32: case 0x33:
|
case 0x30: /* PCI_ROMBAR */
|
||||||
|
case 0x31: /* PCI_ROMBAR */
|
||||||
|
case 0x32: /* PCI_ROMBAR */
|
||||||
|
case 0x33: /* PCI_ROMBAR */
|
||||||
dev->pci_bar[1].addr_regs[addr & 3] = val;
|
dev->pci_bar[1].addr_regs[addr & 3] = val;
|
||||||
dev->pci_bar[1].addr_regs[1] &= dev->bios_mask;
|
dev->pci_bar[1].addr_regs[1] &= dev->bios_mask;
|
||||||
dev->pci_bar[1].addr &= 0xffffe000;
|
dev->pci_bar[1].addr &= 0xffffe000;
|
||||||
@@ -1531,38 +1623,29 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
nic_update_bios(dev);
|
nic_update_bios(dev);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if 0
|
case 0x3C: /* PCI_ILR */
|
||||||
/* Commented out until an APIC controller is emulated for
|
|
||||||
* the PIIX3, otherwise the RTL-8029/AS will not get an IRQ
|
|
||||||
* on boards using the PIIX3. */
|
|
||||||
case 0x3C:
|
|
||||||
dev->pci_regs[addr] = val;
|
|
||||||
if (val != 0xFF) {
|
if (val != 0xFF) {
|
||||||
|
#if 1
|
||||||
|
/*
|
||||||
|
* Commented out until an APIC controller is
|
||||||
|
* emulated for the PIIX3, otherwise the
|
||||||
|
* RTL-8029/AS will not get an IRQ on boards
|
||||||
|
* using the PIIX3.
|
||||||
|
*/
|
||||||
|
nelog(1, "%s: IRQ now: %i (IGNORED)\n", dev->name, val);
|
||||||
|
#else
|
||||||
nelog(1, "%s: IRQ now: %i\n", dev->name, val);
|
nelog(1, "%s: IRQ now: %i\n", dev->name, val);
|
||||||
dev->base_irq = irq;
|
dev->base_irq = val;
|
||||||
}
|
|
||||||
return;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
dev->pci_regs[addr] = dev->base_irq;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nic_tx(nic_t *dev, uint32_t val)
|
|
||||||
{
|
|
||||||
dev->CR.tx_packet = 0;
|
|
||||||
dev->TSR.tx_ok = 1;
|
|
||||||
dev->ISR.pkt_tx = 1;
|
|
||||||
|
|
||||||
/* Generate an interrupt if not masked */
|
|
||||||
if (dev->IMR.tx_inte)
|
|
||||||
picint(1 << dev->base_irq);
|
|
||||||
dev->tx_timer_active = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mcast_index() - return the 6-bit index into the multicast
|
* Return the 6-bit index into the multicast
|
||||||
* table. Stolen unashamedly from FreeBSD's if_ed.c
|
* table. Stolen unashamedly from FreeBSD's if_ed.c
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@@ -1593,12 +1676,25 @@ mcast_index(const void *dst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nic_tx(nic_t *dev, uint32_t val)
|
||||||
|
{
|
||||||
|
dev->CR.tx_packet = 0;
|
||||||
|
dev->TSR.tx_ok = 1;
|
||||||
|
dev->ISR.pkt_tx = 1;
|
||||||
|
|
||||||
|
/* Generate an interrupt if not masked */
|
||||||
|
if (dev->IMR.tx_inte)
|
||||||
|
picint(1 << dev->base_irq);
|
||||||
|
dev->tx_timer_active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rx_frame() - called by the platform-specific code when an
|
* Called by the platform-specific code when an Ethernet frame
|
||||||
* ethernet frame has been received. The destination address
|
* has been received. The destination address is tested to see
|
||||||
* is tested to see if it should be accepted, and if the
|
* if it should be accepted, and if the RX ring has enough room,
|
||||||
* rx ring has enough room, it is copied into it and
|
* it is copied into it and the receive process is updated.
|
||||||
* the receive process is updated
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
nic_rx(void *priv, uint8_t *buf, int io_len)
|
nic_rx(void *priv, uint8_t *buf, int io_len)
|
||||||
@@ -1616,8 +1712,10 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
|
|
||||||
if ((dev->CR.stop != 0) || (dev->page_start == 0)) return;
|
if ((dev->CR.stop != 0) || (dev->page_start == 0)) return;
|
||||||
|
|
||||||
/* Add the pkt header + CRC to the length, and work
|
/*
|
||||||
out how many 256-byte pages the frame would occupy */
|
* Add the pkt header + CRC to the length, and work
|
||||||
|
* out how many 256-byte pages the frame would occupy.
|
||||||
|
*/
|
||||||
pages = (io_len + sizeof(pkthdr) + sizeof(uint32_t) + 255)/256;
|
pages = (io_len + sizeof(pkthdr) + sizeof(uint32_t) + 255)/256;
|
||||||
if (dev->curr_page < dev->bound_ptr) {
|
if (dev->curr_page < dev->bound_ptr) {
|
||||||
avail = dev->bound_ptr - dev->curr_page;
|
avail = dev->bound_ptr - dev->curr_page;
|
||||||
@@ -1626,9 +1724,11 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
(dev->curr_page - dev->bound_ptr);
|
(dev->curr_page - dev->bound_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avoid getting into a buffer overflow condition by not attempting
|
/*
|
||||||
to do partial receives. The emulation to handle this condition
|
* Avoid getting into a buffer overflow condition by
|
||||||
seems particularly painful. */
|
* not attempting to do partial receives. The emulation
|
||||||
|
* to handle this condition seems particularly painful.
|
||||||
|
*/
|
||||||
if ((avail < pages)
|
if ((avail < pages)
|
||||||
#if NE2K_NEVER_FULL_RING
|
#if NE2K_NEVER_FULL_RING
|
||||||
|| (avail == pages)
|
|| (avail == pages)
|
||||||
@@ -1647,7 +1747,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
if (io_len < 60)
|
if (io_len < 60)
|
||||||
io_len = 60;
|
io_len = 60;
|
||||||
|
|
||||||
nelog(2, "%s: rx_frame %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n",
|
nelog(2, "%s: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n",
|
||||||
dev->name,
|
dev->name,
|
||||||
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
|
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
|
||||||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
|
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
|
||||||
@@ -1659,7 +1759,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
if (! memcmp(buf, bcast_addr, 6)) {
|
if (! memcmp(buf, bcast_addr, 6)) {
|
||||||
/* Broadcast not enabled, we're done. */
|
/* Broadcast not enabled, we're done. */
|
||||||
if (! dev->RCR.broadcast) {
|
if (! dev->RCR.broadcast) {
|
||||||
nelog(2, "%s: rx_frame BC disabled\n", dev->name);
|
nelog(2, "%s: RX BC disabled\n", dev->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1669,7 +1769,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
/* Multicast not enabled, we're done. */
|
/* Multicast not enabled, we're done. */
|
||||||
if (! dev->RCR.multicast) {
|
if (! dev->RCR.multicast) {
|
||||||
#if 1
|
#if 1
|
||||||
nelog(2, "%s: rx_frame MC disabled\n", dev->name);
|
nelog(2, "%s: RX MC disabled\n", dev->name);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1677,7 +1777,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
/* Are we listening to this multicast address? */
|
/* Are we listening to this multicast address? */
|
||||||
idx = mcast_index(buf);
|
idx = mcast_index(buf);
|
||||||
if (! (dev->mchash[idx>>3] & (1<<(idx&0x7)))) {
|
if (! (dev->mchash[idx>>3] & (1<<(idx&0x7)))) {
|
||||||
nelog(2, "%s: rx_frame MC not listed\n", dev->name);
|
nelog(2, "%s: RX MC not listed\n", dev->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1685,7 +1785,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
/* Unicast, must be for us.. */
|
/* Unicast, must be for us.. */
|
||||||
else if (memcmp(buf, dev->physaddr, 6)) return;
|
else if (memcmp(buf, dev->physaddr, 6)) return;
|
||||||
} else {
|
} else {
|
||||||
nelog(2, "%s: rx_frame promiscuous receive\n", dev->name);
|
nelog(2, "%s: RX promiscuous receive\n", dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextpage = dev->curr_page + pages;
|
nextpage = dev->curr_page + pages;
|
||||||
@@ -1699,7 +1799,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
pkthdr[1] = nextpage; /* ptr to next packet */
|
pkthdr[1] = nextpage; /* ptr to next packet */
|
||||||
pkthdr[2] = (io_len + sizeof(pkthdr))&0xff; /* length-low */
|
pkthdr[2] = (io_len + sizeof(pkthdr))&0xff; /* length-low */
|
||||||
pkthdr[3] = (io_len + sizeof(pkthdr))>>8; /* length-hi */
|
pkthdr[3] = (io_len + sizeof(pkthdr))>>8; /* length-hi */
|
||||||
nelog(2, "%s: rx_frame pkthdr [%02x %02x %02x %02x]\n",
|
nelog(2, "%s: RX pkthdr [%02x %02x %02x %02x]\n",
|
||||||
dev->name, pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]);
|
dev->name, pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]);
|
||||||
|
|
||||||
/* Copy into buffer, update curpage, and signal interrupt if config'd */
|
/* Copy into buffer, update curpage, and signal interrupt if config'd */
|
||||||
@@ -1717,8 +1817,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
dev->curr_page = nextpage;
|
dev->curr_page = nextpage;
|
||||||
|
|
||||||
dev->RSR.rx_ok = 1;
|
dev->RSR.rx_ok = 1;
|
||||||
if (buf[0] & 0x80)
|
dev->RSR.rx_mbit = (buf[0] & 0x01) ? 1 : 0;
|
||||||
dev->RSR.rx_mbit = 1;
|
|
||||||
dev->ISR.pkt_rx = 1;
|
dev->ISR.pkt_rx = 1;
|
||||||
|
|
||||||
if (dev->IMR.rx_inte)
|
if (dev->IMR.rx_inte)
|
||||||
@@ -1729,15 +1828,12 @@ nic_rx(void *priv, uint8_t *buf, int io_len)
|
|||||||
static void
|
static void
|
||||||
nic_rom_init(nic_t *dev, wchar_t *s)
|
nic_rom_init(nic_t *dev, wchar_t *s)
|
||||||
{
|
{
|
||||||
FILE *f = romfopen(s, L"rb");
|
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
if (f == NULL) {
|
if (dev->bios_addr > 0) {
|
||||||
dev->bios_addr = 0x00000;
|
if ((f = romfopen(s, L"rb")) != NULL) {
|
||||||
nic_update_bios(dev);
|
fseek(f, 0L, SEEK_END);
|
||||||
return;
|
|
||||||
}
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
temp = ftell(f);
|
temp = ftell(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
dev->bios_size = 0x10000;
|
dev->bios_size = 0x10000;
|
||||||
@@ -1749,26 +1845,19 @@ nic_rom_init(nic_t *dev, wchar_t *s)
|
|||||||
dev->bios_size = 0x2000;
|
dev->bios_size = 0x2000;
|
||||||
dev->bios_mask = (dev->bios_size >> 8) & 0xff;
|
dev->bios_mask = (dev->bios_size >> 8) & 0xff;
|
||||||
dev->bios_mask = (0x100 - dev->bios_mask) & 0xff;
|
dev->bios_mask = (0x100 - dev->bios_mask) & 0xff;
|
||||||
|
} else {
|
||||||
rom_init(&dev->bios_rom, s, dev->bios_addr,
|
dev->bios_addr = 0x00000;
|
||||||
dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL);
|
dev->bios_size = 0;
|
||||||
|
return;
|
||||||
nelog(1, "%s: BIOS enabled at %06lX (size %ld)\n",
|
|
||||||
dev->name, dev->bios_addr, dev->bios_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a memory mapping for the space. */
|
||||||
|
rom_init(&dev->bios_rom, s, dev->bios_addr,
|
||||||
|
dev->bios_size, dev->bios_size-1, 0, MEM_MAPPING_EXTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the 'local' part of our configured MAC address. */
|
nelog(1, "%s: BIOS configured at %06lX (size %ld)\n",
|
||||||
static uint32_t
|
dev->name, dev->bios_addr, dev->bios_size);
|
||||||
nic_get_maclocal(nic_t *dev)
|
|
||||||
{
|
|
||||||
uint32_t temp;
|
|
||||||
|
|
||||||
temp = (((int) dev->maclocal[3]) << 16);
|
|
||||||
temp |= (((int) dev->maclocal[4]) << 8);
|
|
||||||
temp |= ((int) dev->maclocal[5]);
|
|
||||||
|
|
||||||
return(temp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1776,7 +1865,13 @@ static void *
|
|||||||
nic_init(int board)
|
nic_init(int board)
|
||||||
{
|
{
|
||||||
uint32_t mac;
|
uint32_t mac;
|
||||||
|
wchar_t *rom;
|
||||||
nic_t *dev;
|
nic_t *dev;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Get the desired debug level. */
|
||||||
|
i = device_get_config_int("debug");
|
||||||
|
if (i > 0) nic_do_log = i;
|
||||||
|
|
||||||
dev = malloc(sizeof(nic_t));
|
dev = malloc(sizeof(nic_t));
|
||||||
memset(dev, 0x00, sizeof(nic_t));
|
memset(dev, 0x00, sizeof(nic_t));
|
||||||
@@ -1787,6 +1882,7 @@ nic_init(int board)
|
|||||||
dev->maclocal[0] = 0x00; /* 00:00:D8 (NE1000 ISA OID) */
|
dev->maclocal[0] = 0x00; /* 00:00:D8 (NE1000 ISA OID) */
|
||||||
dev->maclocal[1] = 0x00;
|
dev->maclocal[1] = 0x00;
|
||||||
dev->maclocal[2] = 0xD8;
|
dev->maclocal[2] = 0xD8;
|
||||||
|
rom = ROM_PATH_NE1000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NE2K_NE2000:
|
case NE2K_NE2000:
|
||||||
@@ -1794,6 +1890,7 @@ nic_init(int board)
|
|||||||
dev->maclocal[0] = 0x00; /* 00:A0:0C (NE2000 compatible OID) */
|
dev->maclocal[0] = 0x00; /* 00:A0:0C (NE2000 compatible OID) */
|
||||||
dev->maclocal[1] = 0xA0;
|
dev->maclocal[1] = 0xA0;
|
||||||
dev->maclocal[2] = 0x0C;
|
dev->maclocal[2] = 0x0C;
|
||||||
|
rom = ROM_PATH_NE2000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NE2K_RTL8029AS:
|
case NE2K_RTL8029AS:
|
||||||
@@ -1802,43 +1899,112 @@ nic_init(int board)
|
|||||||
dev->maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI OID) */
|
dev->maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI OID) */
|
||||||
dev->maclocal[1] = 0x20;
|
dev->maclocal[1] = 0x20;
|
||||||
dev->maclocal[2] = 0x18;
|
dev->maclocal[2] = 0x18;
|
||||||
|
rom = ROM_PATH_RTL8029;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->base_irq = device_get_config_int("irq");
|
if (dev->is_pci) {
|
||||||
if (dev->is_pci)
|
|
||||||
dev->base_address = 0x340;
|
dev->base_address = 0x340;
|
||||||
else
|
} else {
|
||||||
dev->base_address = device_get_config_int("addr");
|
dev->base_address = device_get_config_int("addr");
|
||||||
dev->bios_addr = device_get_config_int("bios_addr");
|
dev->bios_addr = device_get_config_int("bios_addr");
|
||||||
|
}
|
||||||
|
dev->base_irq = device_get_config_int("irq");
|
||||||
|
|
||||||
/* See if we have a local MAC address configured. */
|
/* See if we have a local MAC address configured. */
|
||||||
mac = device_get_config_int_ex("mac", -1);
|
mac = device_get_config_int_ex("mac", -1);
|
||||||
|
|
||||||
|
/* Make this device known to the I/O system. */
|
||||||
|
nic_ioset(dev, dev->base_address);
|
||||||
|
|
||||||
|
/* Set up our BIOS ROM space, if any. */
|
||||||
|
nic_rom_init(dev, rom);
|
||||||
|
|
||||||
|
if (dev->is_pci) {
|
||||||
|
/*
|
||||||
|
* Configure the PCI space registers.
|
||||||
|
*
|
||||||
|
* We do this here, so the I/O routines are generic.
|
||||||
|
*/
|
||||||
|
dev->pci_regs[0x00] = (PCI_VENDID&0xff);
|
||||||
|
dev->pci_regs[0x01] = (PCI_VENDID>>8);
|
||||||
|
dev->pci_regs[0x02] = (PCI_DEVID&0xff);
|
||||||
|
dev->pci_regs[0x03] = (PCI_DEVID>>8);
|
||||||
|
|
||||||
|
dev->pci_regs[0x04] = 0x01; /* IOEN */
|
||||||
|
dev->pci_regs[0x05] = 0x00;
|
||||||
|
dev->pci_regs[0x07] = 0x02; /* DST0, medium devsel */
|
||||||
|
|
||||||
|
dev->pci_regs[0x0B] = 0x02; /* BCR: Network Controller */
|
||||||
|
dev->pci_regs[0x0A] = 0x00; /* SCR: Ethernet */
|
||||||
|
|
||||||
|
dev->pci_regs[0x2C] = (PCI_VENDID&0xff);
|
||||||
|
dev->pci_regs[0x2D] = (PCI_VENDID>>8);
|
||||||
|
dev->pci_regs[0x2E] = (PCI_DEVID&0xff);
|
||||||
|
dev->pci_regs[0x2F] = (PCI_DEVID>>8);
|
||||||
|
|
||||||
|
dev->pci_regs[0x3C] = dev->base_irq; /* PCI_ILR */
|
||||||
|
dev->pci_regs[0x3D] = 0x01; /* PCI_IPR */
|
||||||
|
|
||||||
|
/* Enable our address space in PCI. */
|
||||||
|
dev->pci_bar[0].addr_regs[0] = 0x01;
|
||||||
|
|
||||||
|
/* Enable our BIOS space in PCI, if needed. */
|
||||||
|
if (dev->bios_addr > 0) {
|
||||||
|
dev->pci_bar[1].addr = 0x000F8000;
|
||||||
|
dev->pci_bar[1].addr_regs[1] = dev->bios_mask;
|
||||||
|
dev->pci_bar[1].addr |= 0x1801;
|
||||||
|
} else {
|
||||||
|
dev->pci_bar[1].addr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the RTL8029 EEPROM. */
|
||||||
|
memset(dev->eeprom, 0x00, sizeof(dev->eeprom));
|
||||||
|
dev->eeprom[0x76] =
|
||||||
|
dev->eeprom[0x7A] =
|
||||||
|
dev->eeprom[0x7E] = (PCI_DEVID&0xff);
|
||||||
|
dev->eeprom[0x77] =
|
||||||
|
dev->eeprom[0x7B] =
|
||||||
|
dev->eeprom[0x7F] = (PCI_DEVID>>8);
|
||||||
|
dev->eeprom[0x78] =
|
||||||
|
dev->eeprom[0x7C] = (PCI_VENDID&0xff);
|
||||||
|
dev->eeprom[0x79] =
|
||||||
|
dev->eeprom[0x7D] = (PCI_VENDID>>8);
|
||||||
|
|
||||||
|
/* Make this device known to the PCI bus. */
|
||||||
|
pci_add(nic_pci_read, nic_pci_write, dev);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up our BIA. */
|
/* Set up our BIA. */
|
||||||
if (mac & 0xff000000) {
|
if (mac & 0xff000000) {
|
||||||
/* Generating new MAC. */
|
/* Generate new local MAC. */
|
||||||
dev->maclocal[3] = disc_random_generate();
|
dev->maclocal[3] = disc_random_generate();
|
||||||
dev->maclocal[4] = disc_random_generate();
|
dev->maclocal[4] = disc_random_generate();
|
||||||
dev->maclocal[5] = disc_random_generate() | 1;
|
dev->maclocal[5] = disc_random_generate();
|
||||||
device_set_config_int("mac", nic_get_maclocal(dev));
|
mac = (((int) dev->maclocal[3]) << 16);
|
||||||
|
mac |= (((int) dev->maclocal[4]) << 8);
|
||||||
|
mac |= ((int) dev->maclocal[5]);
|
||||||
|
device_set_config_int("mac", mac);
|
||||||
} else {
|
} else {
|
||||||
dev->maclocal[3] = (mac>>16) & 0xff;
|
dev->maclocal[3] = (mac>>16) & 0xff;
|
||||||
dev->maclocal[4] = (mac>>8) & 0xff;
|
dev->maclocal[4] = (mac>>8) & 0xff;
|
||||||
dev->maclocal[5] = (mac & 0xfe);
|
dev->maclocal[5] = (mac & 0xff);
|
||||||
}
|
}
|
||||||
memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal));
|
memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal));
|
||||||
|
|
||||||
nelog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
|
nelog(0, "%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
dev->name, dev->base_address, dev->base_irq,
|
dev->name, dev->base_address, dev->base_irq,
|
||||||
dev->physaddr[0], dev->physaddr[1], dev->physaddr[2],
|
dev->physaddr[0], dev->physaddr[1], dev->physaddr[2],
|
||||||
dev->physaddr[3], dev->physaddr[4], dev->physaddr[5]);
|
dev->physaddr[3], dev->physaddr[4], dev->physaddr[5]);
|
||||||
|
|
||||||
|
/* Reset the board. */
|
||||||
|
nic_reset(dev);
|
||||||
|
|
||||||
if (network_attach(dev, dev->physaddr, nic_rx) < 0) {
|
if (network_attach(dev, dev->physaddr, nic_rx) < 0) {
|
||||||
#if 0
|
#if 0
|
||||||
msgbox_error_wstr(ghwnd, L"Unable to init platform network");
|
msgbox_error_wstr(ghwnd, L"Unable to init platform network");
|
||||||
#endif
|
#endif
|
||||||
nelog(1, "%s: unable to init platform network type %d\n",
|
nelog(0, "%s: unable to init platform network type %d\n",
|
||||||
dev->name, network_type);
|
dev->name, network_type);
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
@@ -1852,56 +2018,7 @@ nic_init(int board)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->is_pci)
|
nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name,
|
||||||
pci_add(nic_pci_read, nic_pci_write, dev);
|
|
||||||
nic_ioset(dev, dev->base_address);
|
|
||||||
|
|
||||||
if (dev->bios_addr > 0) {
|
|
||||||
nic_rom_init(dev, dev->is_pci ? L"roms/rtl8029as.rom"
|
|
||||||
: L"roms/ne2000.rom");
|
|
||||||
if (dev->is_pci)
|
|
||||||
mem_mapping_disable(&dev->bios_rom.mapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->is_pci) {
|
|
||||||
dev->pci_regs[0x04] = 1;
|
|
||||||
dev->pci_regs[0x05] = 0;
|
|
||||||
dev->pci_regs[0x07] = 2;
|
|
||||||
|
|
||||||
/* Network controller. */
|
|
||||||
dev->pci_regs[0x0B] = 2;
|
|
||||||
|
|
||||||
dev->pci_bar[0].addr_regs[0] = 1;
|
|
||||||
|
|
||||||
if (dev->bios_addr > 0) {
|
|
||||||
/* What is it.. F800 or D000 (bios_addr) ? */
|
|
||||||
dev->pci_bar[1].addr = 0x000F8000;
|
|
||||||
dev->pci_bar[1].addr_regs[1] = dev->bios_mask;
|
|
||||||
dev->pci_bar[1].addr |= 0x1801;
|
|
||||||
} else {
|
|
||||||
dev->pci_bar[1].addr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->pci_regs[0x3C] = dev->base_irq;
|
|
||||||
nelog(1, "%s: IRQ=%i\n", dev->name, dev->pci_regs[0x3C]);
|
|
||||||
dev->pci_regs[0x3D] = 1;
|
|
||||||
|
|
||||||
memset(dev->eeprom, 0x00, sizeof(dev->eeprom));
|
|
||||||
dev->eeprom[0x76] =
|
|
||||||
dev->eeprom[0x7A] =
|
|
||||||
dev->eeprom[0x7E] = 0x29;
|
|
||||||
dev->eeprom[0x77] =
|
|
||||||
dev->eeprom[0x7B] =
|
|
||||||
dev->eeprom[0x7F] = 0x80;
|
|
||||||
dev->eeprom[0x78] =
|
|
||||||
dev->eeprom[0x7C] = 0x10;
|
|
||||||
dev->eeprom[0x79] =
|
|
||||||
dev->eeprom[0x7D] = 0xEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
nic_reset(dev, 0);
|
|
||||||
|
|
||||||
nelog(1, "%s: %s init 0x%X %d\n", dev->name,
|
|
||||||
dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq);
|
dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq);
|
||||||
|
|
||||||
return(dev);
|
return(dev);
|
||||||
|
|||||||
Reference in New Issue
Block a user