summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2007-05-03 20:50:57 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2007-05-03 20:50:57 +0000
commit49ba31ab551198f777502220e9f47db815c78e97 (patch)
tree38b2877564f4d7631cd7e278488ad3493c7e0415
parentac3df562c9131e454c0d2be63e8e0e9fa269fc63 (diff)
a nxb NIC can have up to 4 nx ports and the latest firmware uses some
port-specific registers, for the NIU (phy) and the CRB (~mac). fine. but i have to use an ugly mapping table for the port-specific crb registers because their offsets are not consistent and do not allow to use a subregion per port. ugh.
-rw-r--r--sys/dev/pci/if_nx.c54
-rw-r--r--sys/dev/pci/if_nxreg.h77
2 files changed, 106 insertions, 25 deletions
diff --git a/sys/dev/pci/if_nx.c b/sys/dev/pci/if_nx.c
index bb293580cde..4c5cf03988f 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.37 2007/05/02 19:57:44 reyk Exp $ */
+/* $OpenBSD: if_nx.c,v 1.38 2007/05/03 20:50:56 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org>
@@ -107,7 +107,7 @@ struct nxb_port {
u_int8_t nxp_mode;
u_int8_t nxp_phy;
u_int8_t nxp_lladdr[ETHER_ADDR_LEN];
- bus_size_t nxp_region;
+ bus_size_t nxp_phyregion;
struct nx_softc *nxp_nx;
};
@@ -165,7 +165,7 @@ struct nx_softc {
struct mii_data nx_mii;
bus_space_tag_t nx_memt; /* pointer to sc_memt */
- bus_space_handle_t nx_memh; /* port subregion */
+ bus_space_handle_t nx_memh; /* port phy subregion */
struct nxb_softc *nx_sc; /* The nxb board */
struct nxb_port *nx_port; /* Port information */
@@ -214,8 +214,10 @@ void nx_iff(struct nx_softc *);
void nx_tick(void *);
int nx_intr(void *);
void nx_setlladdr(struct nx_softc *, u_int8_t *);
-u_int32_t nx_read(struct nx_softc *, bus_size_t);
-void nx_write(struct nx_softc *, bus_size_t, u_int32_t);
+u_int32_t nx_readphy(struct nx_softc *, bus_size_t);
+void nx_writephy(struct nx_softc *, bus_size_t, u_int32_t);
+u_int32_t nx_readcrb(struct nx_softc *, enum nxsw_portreg);
+void nx_writecrb(struct nx_softc *, enum nxsw_portreg, u_int32_t);
struct cfdriver nxb_cd = {
0, "nxb", DV_DULL
@@ -488,13 +490,13 @@ nxb_query(struct nxb_softc *sc)
sc->sc_nxp[i].nxp_phy = board->brd_phy;
switch (board->brd_mode) {
case NXNIU_MODE_XGE:
- sc->sc_nxp[i].nxp_region = NXNIU_XGE(i);
+ sc->sc_nxp[i].nxp_phyregion = NXNIU_XGE(i);
break;
case NXNIU_MODE_GBE:
- sc->sc_nxp[i].nxp_region = NXNIU_GBE(i);
+ sc->sc_nxp[i].nxp_phyregion = NXNIU_GBE(i);
break;
case NXNIU_MODE_FC:
- sc->sc_nxp[i].nxp_region = NXNIU_FC(i);
+ sc->sc_nxp[i].nxp_phyregion = NXNIU_FC(i);
break;
}
}
@@ -961,7 +963,7 @@ 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[] = {
+ static const u_int16_t hwtrans[] = {
0x29a0, 0x7730, 0x2950, 0x2a50, 0x0000, 0x0d00,
0x1b10, 0x0e60, 0x0e00, 0x0e10, 0x0e20, 0x0e30,
0x7000, 0x7010, 0x7020, 0x7030, 0x7040, 0x3400,
@@ -1237,7 +1239,7 @@ nx_attach(struct device *parent, struct device *self, void *aux)
nxp->nxp_nx = nx;
if (bus_space_subregion(sc->sc_memt, sc->sc_memh,
- nxp->nxp_region, NXNIU_PORT_SIZE, &nx->nx_memh) != 0) {
+ nxp->nxp_phyregion, NXNIU_PORT_SIZE, &nx->nx_memh) != 0) {
printf(": unable to map port subregion\n");
return;
}
@@ -1524,7 +1526,7 @@ nx_setlladdr(struct nx_softc *nx, u_int8_t *lladdr)
}
u_int32_t
-nx_read(struct nx_softc *nx, bus_size_t reg)
+nx_readphy(struct nx_softc *nx, bus_size_t reg)
{
nxb_set_crbwindow(nx->nx_sc, NXMEMMAP_WINDOW0_START);
bus_space_barrier(nx->nx_memt, nx->nx_memh, reg, 4,
@@ -1533,7 +1535,7 @@ nx_read(struct nx_softc *nx, bus_size_t reg)
}
void
-nx_write(struct nx_softc *nx, bus_size_t reg, u_int32_t val)
+nx_writephy(struct nx_softc *nx, bus_size_t reg, u_int32_t val)
{
nxb_set_crbwindow(nx->nx_sc, NXMEMMAP_WINDOW0_START);
bus_space_write_4(nx->nx_memt, nx->nx_memh, reg, val);
@@ -1541,3 +1543,31 @@ nx_write(struct nx_softc *nx, bus_size_t reg, u_int32_t val)
BUS_SPACE_BARRIER_WRITE);
}
+/* Use mapping table, see if_nxreg.h for details */
+const u_int32_t nx_swportreg[NX_MAX_PORTS][NXSW_PORTREG_MAX] = NXSW_PORTREGS;
+
+u_int32_t
+nx_readcrb(struct nx_softc *nx, enum nxsw_portreg n)
+{
+ struct nxb_port *nxp = nx->nx_port;
+ u_int32_t reg;
+
+ reg = nx_swportreg[nxp->nxp_id][n];
+ nxb_set_crbwindow(nx->nx_sc, NXMEMMAP_WINDOW1_START);
+ bus_space_barrier(nx->nx_memt, nx->nx_memh, reg, 4,
+ BUS_SPACE_BARRIER_READ);
+ return (bus_space_read_4(nx->nx_memt, nx->nx_memh, reg));
+}
+
+void
+nx_writecrb(struct nx_softc *nx, enum nxsw_portreg n, u_int32_t val)
+{
+ struct nxb_port *nxp = nx->nx_port;
+ u_int32_t reg;
+
+ reg = nx_swportreg[nxp->nxp_id][n];
+ nxb_set_crbwindow(nx->nx_sc, NXMEMMAP_WINDOW1_START);
+ bus_space_write_4(nx->nx_memt, nx->nx_memh, reg, val);
+ bus_space_barrier(nx->nx_memt, nx->nx_memh, reg, 4,
+ BUS_SPACE_BARRIER_WRITE);
+}
diff --git a/sys/dev/pci/if_nxreg.h b/sys/dev/pci/if_nxreg.h
index d5329197db0..82cee19e4a0 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.20 2007/05/02 19:57:44 reyk Exp $ */
+/* $OpenBSD: if_nxreg.h,v 1.21 2007/05/03 20:50:56 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org>
@@ -381,18 +381,9 @@ struct nx_statusdesc {
/* Misc SW registers */
#define NXSW_CMD_PRODUCER_OFF NXSW(0x2208) /* Producer CMD ring index */
#define NXSW_CMD_CONSUMER_OFF NXSW(0x220c) /* Consumer CMD ring index */
-#define NXSW_RCV_PRODUCER_OFF NXSW(0x2300) /* Producer Rx ring index */
-#define NXSW_RCV_CONSUMER_OFF NXSW(0x2304) /* Consumer Rx ring index */
-#define NXSW_RCV_GLOBAL_RING NXSW(0x2308) /* Address of Rx buffer */
-#define NXSW_RCV_STATUS_RING NXSW(0x2360) /* Address of Rx status ring */
-#define NXSW_RCV_STATUS_PROD NXSW(0x2364) /* Producer Rx status index */
-#define NXSW_RCV_STATUS_CONS NXSW(0x2368) /* Consumer Rx status index */
#define NXSW_CMD_ADDR_HI NXSW(0x2218) /* CMD ring phys address */
#define NXSW_CMD_ADDR_LO NXSW(0x221c) /* CMD ring phys address */
#define NXSW_CMD_RING_SIZE NXSW(0x22c8) /* Entries in the CMD ring */
-#define NXSW_RCV_RING_SIZE NXSW(0x230c) /* Entries in the Rx ring */
-#define NXSW_JRCV_RING_SIZE NXSW(0x230c) /* Entries in the jumbo ring */
-#define NXSW_RCVPEG_STATE NXSW(0x236c) /* State of the NX2031 */
#define NXSW_CMDPEG_STATE NXSW(0x2250) /* State of the firmware */
#define NXSW_CMDPEG_STATE_M 0xffff /* State mask */
#define NXSW_CMDPEG_INIT_START 0xff00 /* Start of initialization */
@@ -410,9 +401,7 @@ struct nx_statusdesc {
#define NXSW_XG_STATE NXSW(0x2294) /* PHY state register */
#define NXSW_XG_LINK_UP (1<<4) /* 10G PHY state up */
#define NXSW_XG_LINK_DOWN (1<<5) /* 10G PHY state down */
-#define NXSW_JRCV_PRODUCER_OFF NXSW(0x22f4) /* Producer jumbo ring index */
-#define NXSW_JRCV_CONSUMER_OFF NXSW(0x22f8) /* Consumer jumbo ring index */
-#define NXSW_JRCV_GLOBAL_RING NXSW(0x2308) /* Address of jumbo buffer */
+
#define NXSW_TEMP NXSW(0x23b4) /* Temperature sensor */
#define NXSW_TEMP_STATE_M 0x0000ffff /* Temp state mask */
#define NXSW_TEMP_STATE_S 0 /* Temp state shift */
@@ -425,6 +414,68 @@ struct nx_statusdesc {
#define NXSW_DRIVER_VER NXSW(0x24a0) /* Host driver version */
/*
+ * Port-specific SW registers, cannot be mapped to a subregion because
+ * they're using different offsets between the registers. Ugh, we have to
+ * define a mapping table to avoid a ton of ugly if's in the code.
+ */
+
+enum nxsw_portreg {
+ NXSW_RCV_PRODUCER_OFF = 0, /* Producer Rx ring index */
+ NXSW_RCV_CONSUMER_OFF, /* Consumer Rx ring index */
+ NXSW_GLOBALRCV_RING, /* Address of Rx buffer */
+ NXSW_RCV_RING_SIZE, /* Entries in the Rx ring */
+
+ NXSW_JRCV_PRODUCER_OFF, /* Producer jumbo ring index */
+ NXSW_JRCV_CONSUMER_OFF, /* Consumer jumbo ring index */
+ NXSW_GLOBALJRCV_RING, /* Address of jumbo buffer */
+ NXSW_JRCV_RING_SIZE, /* Entries in the jumbo ring */
+
+ NXSW_TSO_PRODUCER_OFF, /* Producer TSO ring index */
+ NXSW_TSO_CONSUMER_OFF, /* Consumer TSO ring index */
+ NXSW_GLOBALOTSO_RING, /* Address of TSO buffer */
+ NXSW_TSO_RING_SIZE, /* Entries in the TSO ring */
+
+ NXSW_STATUS_RING, /* Address of status ring */
+ NXSW_STATUS_PROD, /* Producer status index */
+ NXSW_STATUS_CONS, /* Consumer status index */
+ NXSW_RCVPEG_STATE, /* State of the NX2031 */
+ NXSW_STATUS_RING_SIZE, /* Entries in the status ring */
+
+ NXSW_PORTREG_MAX
+};
+#define NXSW_PORTREGS { \
+ { \
+ NXSW(0x2300), NXSW(0x2304), NXSW(0x2308), NXSW(0x230c), \
+ NXSW(0x2310), NXSW(0x2314), NXSW(0x2318), NXSW(0x231c), \
+ NXSW(0x2320), NXSW(0x2324), NXSW(0x2328), NXSW(0x232c), \
+ NXSW(0x2320), NXSW(0x2324), NXSW(0x2328), NXSW(0x232c), \
+ NXSW(0x2340) \
+ }, { \
+ NXSW(0x2344), NXSW(0x2348), NXSW(0x234c), NXSW(0x2350), \
+ NXSW(0x2354), NXSW(0x2358), NXSW(0x235c), NXSW(0x2360), \
+ NXSW(0x2364), NXSW(0x2368), NXSW(0x236c), NXSW(0x2370), \
+ NXSW(0x2374), NXSW(0x2378), NXSW(0x237c), NXSW(0x2380), \
+ NXSW(0x2384) \
+ }, { \
+ NXSW(0x23d8), NXSW(0x23dc), NXSW(0x23f0), NXSW(0x23f4), \
+ NXSW(0x23f8), NXSW(0x23fc), NXSW(0x2400), NXSW(0x2404), \
+ NXSW(0x2408), NXSW(0x240c), NXSW(0x2410), NXSW(0x2414), \
+ NXSW(0x2418), NXSW(0x241c), NXSW(0x2420), NXSW(0x2424), \
+ NXSW(0x2428) \
+ }, { \
+ NXSW(0x242c), NXSW(0x2430), NXSW(0x2434), NXSW(0x2438), \
+ NXSW(0x243c), NXSW(0x2440), NXSW(0x2444), NXSW(0x2448), \
+ NXSW(0x244c), NXSW(0x2450), NXSW(0x2454), NXSW(0x2458), \
+ NXSW(0x245c), NXSW(0x2460), NXSW(0x2464), NXSW(0x2468), \
+ NXSW(0x246c) \
+ } \
+}
+
+/*
+ * Port-specific SW registers, will be mapped to a subregion
+ */
+
+/*
* Secondary Interrupt Registers
*/