diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-05-03 20:50:57 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-05-03 20:50:57 +0000 |
commit | 49ba31ab551198f777502220e9f47db815c78e97 (patch) | |
tree | 38b2877564f4d7631cd7e278488ad3493c7e0415 | |
parent | ac3df562c9131e454c0d2be63e8e0e9fa269fc63 (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.c | 54 | ||||
-rw-r--r-- | sys/dev/pci/if_nxreg.h | 77 |
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 */ |