summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2007-05-01 02:20:15 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2007-05-01 02:20:15 +0000
commit181872746fbd2a17710786c5fd237e0eb4e072c5 (patch)
treebbb6fe5a7da300be1355292cadc44f67b0158b86 /sys
parent590163d65312d46ce50fbc60b432282034b60d53 (diff)
implement the soft reset of the hardware according to section 3.5.6 of
the doc).
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_nx.c123
-rw-r--r--sys/dev/pci/if_nxreg.h32
2 files changed, 142 insertions, 13 deletions
diff --git a/sys/dev/pci/if_nx.c b/sys/dev/pci/if_nx.c
index df6247a5f2a..b9ec2d95f77 100644
--- a/sys/dev/pci/if_nx.c
+++ b/sys/dev/pci/if_nx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nx.c,v 1.30 2007/04/30 22:53:09 reyk Exp $ */
+/* $OpenBSD: if_nx.c,v 1.31 2007/05/01 02:20:13 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org>
@@ -65,6 +65,7 @@
#ifdef NX_DEBUG
#define NXDBG_FLASH (1<<0) /* debug flash access through ROMUSB */
#define NXDBG_WAIT (1<<1) /* poll registers */
+#define NXDBG_CRBINIT (1<<2) /* SW register init from flash */
#define NXDBG_ALL 0xffff /* enable all debugging messages */
int nx_debug = 0;
#define DPRINTF(_lvl, _arg...) do { \
@@ -165,6 +166,7 @@ void nxb_reset(struct nxb_softc *);
u_int32_t nxb_read(struct nxb_softc *, bus_size_t);
void nxb_write(struct nxb_softc *, bus_size_t, u_int32_t);
+int nxb_writehw(struct nxb_softc *, u_int32_t, u_int32_t);
void nxb_set_window(struct nxb_softc *, int);
int nxb_wait(struct nxb_softc *, bus_size_t, u_int32_t, u_int32_t,
int, u_int);
@@ -518,7 +520,12 @@ nxb_newstate(struct nxb_softc *sc, int newstate)
{
int oldstate = sc->sc_state;
+ sc->sc_state = newstate;
+
switch (newstate) {
+ case NX_S_RESET:
+ nxb_reset(sc);
+ break;
case NX_S_BOOT:
/*
* Initialize and bootstrap the device
@@ -526,6 +533,7 @@ nxb_newstate(struct nxb_softc *sc, int newstate)
nxb_write(sc, NXSW_CMD_PRODUCER_OFF, 0);
nxb_write(sc, NXSW_CMD_CONSUMER_OFF, 0);
nxb_write(sc, NXSW_CMD_ADDR_LO, 0);
+ nxb_write(sc, NXSW_DRIVER_VER, NX_FIRMWARE_VER);
nxb_write(sc, NXROMUSB_GLB_PEGTUNE, NXROMUSB_GLB_PEGTUNE_DONE);
break;
case NX_S_LOADED:
@@ -548,7 +556,6 @@ nxb_newstate(struct nxb_softc *sc, int newstate)
/* no action */
break;
}
- sc->sc_state = newstate;
return (0);
}
@@ -580,7 +587,7 @@ nxb_mountroot(void *arg)
NX_FIRMWARE_BUILD);
sc->sc_flags |= NXFLAG_FWINVALID;
- nxb_reset(sc);
+ nxb_newstate(sc, NX_S_RESET);
return;
}
printf("\n");
@@ -669,7 +676,7 @@ nxb_reset(struct nxb_softc *sc)
size_t fwlen = 0;
int bootsz, imagesz;
u_int i;
- u_int32_t *data, addr, val;
+ u_int32_t *data, addr, val, ncrb;
bus_size_t reg;
bzero(&fh, sizeof(fh));
@@ -713,16 +720,56 @@ nxb_reset(struct nxb_softc *sc)
}
/*
- * Initialize the SW registers
+ * Reset the SW registers
*/
+
+ /* 1. Halt the hardware */
+ nxb_write(sc, NXROMUSB_GLB_SW_RESET, NXROMUSB_GLB_SW_RESET_DEF);
+
+ /* 2. Read the CRBINIT area from flash memory */
addr = NXFLASHMAP_CRBINIT_0;
- if (nxb_read_rom(sc, addr, &val) != 0)
+ if (nxb_read_rom(sc, addr, &ncrb) != 0)
goto fail1;
+ ncrb &= NXFLASHMAP_CRBINIT_M;
+ if (ncrb == 0 || ncrb > NXFLASHMAP_CRBINIT_MAX)
+ goto load; /* ignore CRBINIT and skip step */
- /* XXX */
- DPRINTF(NXDBG_FLASH, "%s(%s): ncrb 0x%08x\n",
- sc->sc_dev.dv_xname, __func__, val);
+ /* 3. Write the CRBINIT are to PCI memory */
+ for (i = 0; i < ncrb; i++) {
+ reg = i * 8;
+ reg += 4;
+ nxb_read_rom(sc, reg, &val);
+ reg += 4;
+ nxb_read_rom(sc, reg, &addr);
+
+ if (nxb_writehw(sc, addr, val) != 0)
+ goto fail1;
+ }
+
+ /* 4. Reset the Protocol Processing Engine */
+ nxb_write(sc, NXROMUSB_GLB_SW_RESET,
+ nxb_read(sc, NXROMUSB_GLB_SW_RESET) &
+ ~NXROMUSB_GLB_SW_RESET_PPE);
+
+ /* 5. Reset the D & I caches */
+ nxb_set_window(sc, 0);
+ nxb_write(sc, NXPPE_D(0x0e), 0x1e);
+ nxb_write(sc, NXPPE_D(0x4c), 0x8);
+ nxb_write(sc, NXPPE_I(0x4c), 0x8);
+
+ /* 6. Clear the Protocol Processing Engine */
+ nxb_write(sc, NXPPE_0(0x8), 0);
+ nxb_write(sc, NXPPE_0(0xc), 0);
+ nxb_write(sc, NXPPE_1(0x8), 0);
+ nxb_write(sc, NXPPE_1(0xc), 0);
+ nxb_write(sc, NXPPE_2(0x8), 0);
+ nxb_write(sc, NXPPE_2(0xc), 0);
+ nxb_write(sc, NXPPE_3(0x8), 0);
+ nxb_write(sc, NXPPE_3(0xc), 0);
+ nxb_set_window(sc, 1);
+
+ load:
/*
* Load the images into RAM
*/
@@ -788,6 +835,64 @@ nxb_write(struct nxb_softc *sc, bus_size_t reg, u_int32_t val)
BUS_SPACE_BARRIER_WRITE);
}
+int
+nxb_writehw(struct nxb_softc *sc, u_int32_t addr, u_int32_t val)
+{
+ /* Translation table of NIC addresses to PCI addresses */
+ static u_int16_t hwtrans[] = {
+ 0x29a0, 0x7730, 0x2950, 0x2a50, 0x0000, 0x0d00,
+ 0x1b10, 0x0e60, 0x0e00, 0x0e10, 0x0e20, 0x0e30,
+ 0x7000, 0x7010, 0x7020, 0x7030, 0x7040, 0x3400,
+ 0x3410, 0x3420, 0x3430, 0x3450, 0x3440, 0x3c00,
+ 0x3c10, 0x3c20, 0x3c30, 0x3c50, 0x3c40, 0x4100,
+ 0x0000, 0x0d10, 0x0000, 0x0000, 0x4160, 0x0c60,
+ 0x0c70, 0x0c80, 0x7580, 0x7590, 0x4170, 0x0000,
+ 0x0890, 0x70a0, 0x70b0, 0x70c0, 0x08d0, 0x08e0,
+ 0x70f0, 0x4050, 0x4200, 0x4210, 0x0000, 0x0880,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7180, 0x0000
+ };
+ u_int32_t base = (addr & NXMEMMAP_HWTRANS_M) >> 16;
+ bus_size_t reg = ~0;
+ u_int i, window = 0;
+
+ for (i = 0; i < (sizeof(hwtrans) / sizeof(hwtrans[0])); i++) {
+ if (hwtrans[i] == base) {
+ reg = i << 20;
+ break;
+ }
+ }
+ if (reg == ~0)
+ return (-1); /* Invalid address */
+ reg += (addr & ~NXMEMMAP_HWTRANS_M);
+
+ /* Translate window addresst to PCI memory offset */
+ if (reg >= NXMEMMAP_WINDOW0_START && reg <= NXMEMMAP_WINDOW0_END)
+ window = 0;
+ else if (reg >= NXMEMMAP_WINDOW1_START && reg <= NXMEMMAP_WINDOW1_END) {
+ reg -= NXMEMMAP_WINDOW1_START;
+ window = 1;
+ } else
+ return (-1);
+ reg += NXPCIMAP_CRB;
+
+ /* Write value to the register, enable some workarounds */
+ if (reg == NXSW_BOOTLD_CONFIG)
+ return (0);
+ nxb_set_window(sc, window);
+ nxb_write(sc, reg, val);
+ nxb_set_window(sc, 1);
+ if (reg == NXROMUSB_GLB_SW_RESET)
+ delay(1000);
+ else
+ delay(1);
+
+ DPRINTF(NXDBG_CRBINIT, "%s(%s) addr 0x%08x -> reg 0x%08x, "
+ "val 0x%08x, window %d\n",
+ sc->sc_dev.dv_xname, __func__, addr, reg, val, window);
+
+ return (0);
+}
+
void
nxb_set_window(struct nxb_softc *sc, int window)
{
diff --git a/sys/dev/pci/if_nxreg.h b/sys/dev/pci/if_nxreg.h
index aff4f1809b2..c1c40537e21 100644
--- a/sys/dev/pci/if_nxreg.h
+++ b/sys/dev/pci/if_nxreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nxreg.h,v 1.14 2007/04/30 22:53:09 reyk Exp $ */
+/* $OpenBSD: if_nxreg.h,v 1.15 2007/05/01 02:20:14 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org>
@@ -38,14 +38,16 @@
#define NX_FIRMWARE_MAJOR 3
#define NX_FIRMWARE_MINOR 4
#define NX_FIRMWARE_BUILD 31
+#define NX_FIRMWARE_VER 0x001f0403
/* Used to indicate various states of the NIC and its firmware */
enum nx_state {
NX_S_FAIL = -1, /* Failed to initialize the device */
NX_S_OFFLINE = 0, /* Firmware is not active yet */
- NX_S_BOOT = 1, /* Chipset is booting the firmware */
- NX_S_LOADED = 2, /* Firmware is loaded but not initialized */
- NX_S_READY = 3 /* Device has been initialized and is ready */
+ NX_S_RESET = 1, /* Firmware is in reset state */
+ NX_S_BOOT = 2, /* Chipset is booting the firmware */
+ NX_S_LOADED = 3, /* Firmware is loaded but not initialized */
+ NX_S_READY = 4 /* Device has been initialized and is ready */
};
/*
@@ -142,16 +144,34 @@ struct nx_statusdesc {
#define NXPCIMAP_CRB 0x06000000
/* Offsets inside NXPCIMAP_CRB */
+#define NXMEMMAP_WINDOW0_START 0x00000000
+#define NXMEMMAP_WINDOW0_END 0x01ffffff
#define NXMEMMAP_WINDOW_SIZE 0x02000000
#define NXMEMMAP_PCIE 0x00100000
#define NXMEMMAP_NIU 0x00600000
+#define NXMEMMAP_PPE_0 0x01100000
+#define NXMEMMAP_PPE_1 0x01200000
+#define NXMEMMAP_PPE_2 0x01300000
+#define NXMEMMAP_PPE_3 0x01400000
+#define NXMEMMAP_PPE_D 0x01500000
+#define NXMEMMAP_PPE_I 0x01600000
+#define NXMEMMAP_WINDOW1_START 0x02000000
+#define NXMEMMAP_WINDOW1_END 0x07ffffff
#define NXMEMMAP_SW 0x02200000 /* XXX 0x02400000? */
#define NXMEMMAP_SIR 0x03200000
#define NXMEMMAP_ROMUSB 0x03300000
+#define NXMEMMAP_HWTRANS_M 0xfff00000
+
/* Window 0 register map */
#define NXPCIE(_x) ((_x) + 0x06100000) /* PCI Express */
#define NXNIU(_x) ((_x) + 0x06600000) /* Network Int Unit */
+#define NXPPE_0(_x) ((_x) + 0x07100000) /* PEGNET 0 */
+#define NXPPE_1(_x) ((_x) + 0x07200000) /* PEGNET 0 */
+#define NXPPE_2(_x) ((_x) + 0x07300000) /* PEGNET 0 */
+#define NXPPE_3(_x) ((_x) + 0x07400000) /* PEGNET 0 */
+#define NXPPE_D(_x) ((_x) + 0x07500000) /* PEGNET D-Cache */
+#define NXPPE_I(_x) ((_x) + 0x07600000) /* PEGNET I-Cache */
/* Window 1 register map */
#define NXPCIE_1(_x) ((_x) + 0x06100000) /* PCI Express' */
@@ -164,6 +184,8 @@ struct nx_statusdesc {
/* Flash layout */
#define NXFLASHMAP_CRBINIT_0 0x00000000 /* CRBINIT */
+#define NXFLASHMAP_CRBINIT_M 0x7fffffff /* ROM memory barrier */
+#define NXFLASHMAP_CRBINIT_MAX 1023 /* Max CRBINIT entries */
#define NXFLASHMAP_INFO 0x00004000 /* board configuration */
#define NXFLASHMAP_INITCODE 0x00006000 /* chipset-specific code */
#define NXFLASHMAP_BOOTLOADER 0x00010000 /* boot loader */
@@ -334,6 +356,7 @@ struct nx_statusdesc {
#define NXSW_JRCV_PRODUCER_OFF NXSW(0x2300) /* Producer jumbo ring index */
#define NXSW_JRCV_CONSUMER_OFF NXSW(0x2304) /* Consumer jumbo ring index */
#define NXSW_JRCV_GLOBAL_RING NXSW(0x2220) /* Address of jumbo buffer */
+#define NXSW_DRIVER_VER NXSW(0x24a0) /* Host driver version */
/*
* Secondary Interrupt Registers
@@ -372,6 +395,7 @@ struct nx_statusdesc {
#define NXROMUSB_GLB_SW_RESET_U0PEG2 (1<<8) /* Network Pegasus2 reset */
#define NXROMUSB_GLB_SW_RESET_U0PEG1 (1<<7) /* Network Pegasus1 reset */
#define NXROMUSB_GLB_SW_RESET_U0PEG0 (1<<6) /* Network Pegasus0 reset */
+#define NXROMUSB_GLB_SW_RESET_PPE 0xf0 /* Protocol Processing Engine */
#define NXROMUSB_GLB_SW_RESET_DEF 0xffffffff
/* Casper Reset Register */