diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-04-16 16:21:12 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-04-16 16:21:12 +0000 |
commit | 3e97976cb9e38faf9a73e7c84b0fc5f610119b1d (patch) | |
tree | 288abe92ebc51ea756ebf29e02b8b074c74ff888 /sys/dev | |
parent | a82ca87a0d33a03ad4f060372b002a725f3ade0c (diff) |
Start a driver for the NetXen Inc. multi port 10Gb and Gigabit
Ethernet devices. The driver attaches as nxb at pci for the
controller/board and nx at nxb for each port.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/files.pci | 9 | ||||
-rw-r--r-- | sys/dev/pci/if_nx.c | 535 | ||||
-rw-r--r-- | sys/dev/pci/if_nxreg.h | 271 |
3 files changed, 814 insertions, 1 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index 511ad5543bc..74692d1d308 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.229 2007/04/16 10:35:29 dlg Exp $ +# $OpenBSD: files.pci,v 1.230 2007/04/16 16:21:11 reyk Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -340,6 +340,13 @@ device xge: ether, ifnet, ifmedia attach xge at pci file dev/pci/if_xge.c xge +# NetXen NX203x 10 Gigabit Ethernet +device nxb {} +attach nxb at pci +device nx: ether, ifnet, mii, ifmedia +attach nx at nxb +file dev/pci/if_nx.c nxb | nx + # Tehuti Networks 10Gb Ethernet device thtc {} attach thtc at pci diff --git a/sys/dev/pci/if_nx.c b/sys/dev/pci/if_nx.c new file mode 100644 index 00000000000..77bc91038d6 --- /dev/null +++ b/sys/dev/pci/if_nx.c @@ -0,0 +1,535 @@ +/* $OpenBSD: if_nx.c,v 1.1 2007/04/16 16:21:11 reyk Exp $ */ + +/* + * Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Driver for the NetXen NX2031/NX2035 10Gb and Gigabit Ethernet chipsets, + * see http://www.netxen.com/. + * + * This driver was made possible because NetXen Inc. donated NX203x + * hardware and provided documentation. Thanks! + * + * (And Puffy Baba spoke the magic words OPEN-SOURCE-AMI...) + */ + +#include "bpfilter.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/sockio.h> +#include <sys/mbuf.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/malloc.h> +#include <sys/timeout.h> +#include <sys/device.h> + +#include <machine/bus.h> +#include <machine/intr.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/if_types.h> + +#if NBPFILTER > 0 +#include <net/bpf.h> +#endif + +#ifdef INET +#include <netinet/in.h> +#include <netinet/if_ether.h> +#endif + +#include <dev/mii/mii.h> +#include <dev/mii/miivar.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/pci/if_nxreg.h> + +struct nx_softc; + +struct nxb_port { + u_int8_t nxp_id; + u_int8_t nxp_mode; + u_int32_t nxp_lladdrid; + + struct nx_softc *nxp_nx; +}; + +struct nxb_softc { + struct device sc_dev; + + pci_chipset_tag_t sc_pc; + pcitag_t sc_tag; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + bus_size_t sc_ios; + bus_dma_tag_t sc_dmat; + + void *sc_ih; + + u_int32_t sc_nrxbuf; + u_int32_t sc_ntxbuf; + volatile u_int sc_txpending; + struct timeout sc_tick; + + struct nxb_port sc_nxp[NX_MAX_PORTS]; /* The nx ports */ +}; + +struct nx_softc { + struct device nx_dev; + struct arpcom nx_ac; + struct mii_data nx_mii; + + struct nxb_softc *nx_sc; /* The nxb board */ + struct nxb_port *nx_port; /* Port information */ + + u_int8_t nx_lladdr[ETHER_ADDR_LEN]; +}; + +int nxb_match(struct device *, void *, void *); +void nxb_attach(struct device *, struct device *, void *); +int nxb_query(struct nxb_softc *sc); +int nxb_map_pci(struct nxb_softc *, struct pci_attach_args *); +int nxb_intr(void *); +void nxb_tick(void *); +void nxb_iterate(struct nxb_softc *, + void (*)(struct nx_softc *, void *), void *); + +int nx_match(struct device *, void *, void *); +void nx_attach(struct device *, struct device *, void *); +int nx_print(void *, const char *); +void nx_getlladdr(struct nx_softc *); +int nx_media_change(struct ifnet *); +void nx_media_status(struct ifnet *, struct ifmediareq *); +void nx_link_state(struct nx_softc *, void *); +void nx_init(struct ifnet *); +void nx_start(struct ifnet *); +void nx_stop(struct ifnet *); +void nx_watchdog(struct ifnet *); +int nx_ioctl(struct ifnet *, u_long, caddr_t); +void nx_iff(struct nx_softc *); + +struct cfdriver nxb_cd = { + 0, "nxb", DV_DULL +}; +struct cfattach nxb_ca = { + sizeof(struct nxb_softc), nxb_match, nxb_attach +}; + +struct cfdriver nx_cd = { + 0, "nx", DV_IFNET +}; +struct cfattach nx_ca = { + sizeof(struct nx_softc), nx_match, nx_attach +}; + +const struct pci_matchid nxb_devices[] = { + { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_10GXxR }, + { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_10GCX4 }, + { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_4GCU }, + { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_10GBCH }, + { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_0005 }, + { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_0024 }, + { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_0025 } +}; + +extern int ifqmaxlen; + +/* + * Routines handling the physical ''nxb'' board + */ + +int +nxb_match(struct device *parent, void *match, void *aux) +{ + return (pci_matchbyid((struct pci_attach_args *)aux, + nxb_devices, sizeof(nxb_devices) / sizeof(nxb_devices[0]))); +} + +void +nxb_attach(struct device *parent, struct device *self, void *aux) +{ + struct nxb_softc *sc = (struct nxb_softc *)self; + struct pci_attach_args *pa = aux; + int i; + + if (nxb_map_pci(sc, pa) != 0) + return; + if (nxb_query(sc) != 0) + return; +#if 0 + if (nxb_alloc_data(sc) != 0) + return; +#endif + + for (i = 0; i < NX_MAX_PORTS; i++) + config_found(&sc->sc_dev, &sc->sc_nxp[i], nx_print); + + timeout_set(&sc->sc_tick, nxb_tick, sc); +} + +int +nxb_map_pci(struct nxb_softc *sc, struct pci_attach_args *pa) +{ + pcireg_t memtype; + pci_intr_handle_t ih; + const char *intrstr; + + sc->sc_pc = pa->pa_pc; + sc->sc_tag = pa->pa_tag; + sc->sc_dmat = pa->pa_dmat; + + memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, PCI_MAPREG_START); + switch (memtype) { + case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: + case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: + break; + default: + printf(": invalid memory type\n"); + return (1); + } + if (pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0, &sc->sc_iot, + &sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) { + printf(": unable to map system interface register\n"); + return (1); + } + + if (pci_intr_map(pa, &ih) != 0) { + printf(": unable to map interrupt\n"); + goto unmap; + } + + intrstr = pci_intr_string(pa->pa_pc, ih); + sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, + nxb_intr, sc, sc->sc_dev.dv_xname); + if (sc->sc_ih == NULL) { + printf(": unable to map interrupt%s%s\n", + intrstr == NULL ? "" : " at ", + intrstr == NULL ? "" : intrstr); + goto unmap; + } + printf(": %s\n", intrstr); + + return (0); + + unmap: + bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); + sc->sc_ios = 0; + return (1); +} + +int +nxb_query(struct nxb_softc *sc) +{ + return (0); +} + +int +nxb_intr(void *arg) +{ + return (0); +} + +void +nxb_tick(void *arg) +{ + struct nxb_softc *sc = (struct nxb_softc *)arg; + + nxb_iterate(sc, nx_link_state, NULL); + + timeout_add(&sc->sc_tick, hz); +} + +void +nxb_iterate(struct nxb_softc *sc, + void (*func)(struct nx_softc *, void *), void *arg) +{ + struct nx_softc *nx; + int i; + + for (i = 0; i < NX_MAX_PORTS; i++) + if ((nx = sc->sc_nxp[i].nxp_nx) != NULL) + (func)(nx, arg); +} + +/* + * Routines handling the virtual ''nx'' ports + */ + +int +nx_match(struct device *parent, void *match, void *aux) +{ + struct nxb_port *nxp = (struct nxb_port *)aux; + + if (nxp->nxp_id >= NX_MAX_PORTS) + return (0); + + switch (nxp->nxp_mode) { + case NXNIU_MODE_XGE: + case NXNIU_MODE_GBE: + return (1); + case NXNIU_MODE_FC: + /* FibreChannel mode is not documented and not supported */ + return (0); + } + + return (0); +} + +void +nx_attach(struct device *parent, struct device *self, void *aux) +{ + struct nxb_softc *sc = (struct nxb_softc *)parent; + struct nx_softc *nx = (struct nx_softc *)self; + struct nxb_port *nxp = (struct nxb_port *)aux; + struct ifnet *ifp; + + nx->nx_sc = sc; + nx->nx_port = nxp; + nxp->nxp_nx = nx; + + nx_getlladdr(nx); + + ifp = &nx->nx_ac.ac_if; + ifp->if_softc = nx; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = nx_ioctl; + ifp->if_start = nx_start; + ifp->if_watchdog = nx_watchdog; + ifp->if_hardmtu = NX_JUMBO_MTU; + strlcpy(ifp->if_xname, nx->nx_dev.dv_xname, IFNAMSIZ); + IFQ_SET_MAXLEN(&ifp->if_snd, sc->sc_ntxbuf - 1); + IFQ_SET_READY(&ifp->if_snd); + + ifp->if_capabilities = IFCAP_VLAN_MTU; +#if 0 + ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; + ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | + IFCAP_CSUM_UDPv4; +#endif + + ifmedia_init(&nx->nx_mii.mii_media, 0, + nx_media_change, nx_media_status); + ifmedia_add(&nx->nx_mii.mii_media, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&nx->nx_mii.mii_media, IFM_ETHER | IFM_AUTO); + + if_attach(ifp); + ether_ifattach(ifp); + + return; +} + +int +nx_print(void *aux, const char *parentname) +{ + struct nxb_port *nxp = (struct nxb_port *)aux; + + if (parentname) + printf("nx port %u at %s", + nxp->nxp_id, parentname); + else + printf(" port %u", nxp->nxp_id); + return (UNCONF); +} + +void +nx_getlladdr(struct nx_softc *nx) +{ + /* XXX */ + return; +} + +int +nx_media_change(struct ifnet *ifp) +{ + struct nx_softc *nx = (struct nx_softc *)ifp->if_softc; + struct nxb_port *nxp = nx->nx_port; + + switch (nxp->nxp_mode) { + case NXNIU_MODE_XGE: + /* XXX */ + break; + case NXNIU_MODE_GBE: + mii_mediachg(&nx->nx_mii); + break; + } + + return (0); +} + +void +nx_media_status(struct ifnet *ifp, struct ifmediareq *imr) +{ + struct nx_softc *nx = (struct nx_softc *)ifp->if_softc; + struct nxb_port *nxp = nx->nx_port; + + switch (nxp->nxp_mode) { + case NXNIU_MODE_XGE: + imr->ifm_active = IFM_ETHER | IFM_AUTO; + imr->ifm_status = IFM_AVALID; + nx_link_state(nx, NULL); + if (LINK_STATE_IS_UP(ifp->if_link_state) && + ifp->if_flags & IFF_UP) + imr->ifm_status |= IFM_ACTIVE; + break; + case NXNIU_MODE_GBE: + mii_pollstat(&nx->nx_mii); + imr->ifm_active = nx->nx_mii.mii_media_active; + imr->ifm_status = nx->nx_mii.mii_media_status; + mii_mediachg(&nx->nx_mii); + break; + } +} + +void +nx_link_state(struct nx_softc *nx, void *arg) +{ + struct nxb_port *nxp = nx->nx_port; + struct ifnet *ifp = &nx->nx_ac.ac_if; + u_int32_t status = 0; + int link_state = LINK_STATE_DOWN; + + switch (nxp->nxp_mode) { + case NXNIU_MODE_XGE: + /* XXX */ +// status = nx_read(sc, NX_XG_STATE); + if (status & NXSW_XG_LINK_UP) + link_state = LINK_STATE_FULL_DUPLEX; + if (ifp->if_link_state != link_state) { + ifp->if_link_state = link_state; + if_link_state_change(ifp); + } + break; + case NXNIU_MODE_GBE: + mii_tick(&nx->nx_mii); + break; + } +} + +void +nx_watchdog(struct ifnet *ifp) +{ + return; +} + +int +nx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + struct nx_softc *nx = (struct nx_softc *)ifp->if_softc; + struct ifaddr *ifa; + struct ifreq *ifr; + int s, error = 0; + + s = splnet(); + + if ((error = ether_ioctl(ifp, &nx->nx_ac, cmd, data)) > 0) { + splx(s); + return (error); + } + + switch (cmd) { + case SIOCSIFADDR: + ifa = (struct ifaddr *)data; + ifp->if_flags |= IFF_UP; +#ifdef INET + if (ifa->ifa_addr->sa_family == AF_INET) + arp_ifinit(&nx->nx_ac, ifa); +#endif + /* FALLTHROUGH */ + case SIOCSIFFLAGS: + if (ifp->if_flags & IFF_UP) { + if (ifp->if_flags & IFF_RUNNING) + nx_iff(nx); + else + nx_init(ifp); + } else { + if (ifp->if_flags & IFF_RUNNING) + nx_stop(ifp); + } + break; + + case SIOCSIFMTU: + if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu) + error = EINVAL; + else if (ifp->if_mtu != ifr->ifr_mtu) + ifp->if_mtu = ifr->ifr_mtu; + break; + + case SIOCADDMULTI: + case SIOCDELMULTI: + ifr = (struct ifreq *)data; + error = (cmd == SIOCADDMULTI) ? + ether_addmulti(ifr, &nx->nx_ac) : + ether_delmulti(ifr, &nx->nx_ac); + + if (error == ENETRESET) { + if (ifp->if_flags & IFF_RUNNING) + nx_iff(nx); + error = 0; + } + break; + + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &nx->nx_mii.mii_media, cmd); + break; + + default: + error = ENOTTY; + } + + if (error == ENETRESET) { + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == + (IFF_UP | IFF_RUNNING)) + nx_init(ifp); + error = 0; + } + + splx(s); + + return (error); +} + +void +nx_init(struct ifnet *ifp) +{ + return; +} + +void +nx_start(struct ifnet *ifp) +{ + return; +} + +void +nx_stop(struct ifnet *ifp) +{ + return; +} + +void +nx_iff(struct nx_softc *nx) +{ + return; +} diff --git a/sys/dev/pci/if_nxreg.h b/sys/dev/pci/if_nxreg.h new file mode 100644 index 00000000000..6df81592faa --- /dev/null +++ b/sys/dev/pci/if_nxreg.h @@ -0,0 +1,271 @@ +/* $OpenBSD: if_nxreg.h,v 1.1 2007/04/16 16:21:11 reyk Exp $ */ + +/* + * Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * NetXen NX2031 register definitions based on: + * http://www.netxen.com/products/downloads/ + * Ethernet_Driver_Ref_Guide_Open_Source.pdf + */ + +#ifndef _NX_REG_H +#define _NX_REG_H + +/* + * Common definitions + */ + +#define NX_MAX_PORTS 4 + +#define NX_MAX_MTU ETHER_MTU +#define NX_JUMBO_MTU 8000 /* less than 9k */ + +/* + * Hardware descriptors + */ + +struct nx_txdesc { + u_int64_t tx_next; /* reserved */ + u_int32_t tx_addr2_low; /* low address of buffer 2 */ + u_int32_t tx_addr2_high; /* high address of buffer 2 */ + u_int32_t tx_length; +#define NX_TXDESC_LENGTH_S 0 /* length */ +#define NX_TXDESC_LENGTH_M 0x00ffffff +#define NX_TXDESC_TCPOFF_S 24 /* TCP header offset for TSO */ +#define NX_TXDESC_TCPOFF_M 0xff000000 + u_int8_t tx_ipoff; /* IP header offset for TSO */ + u_int8_t tx_nbuf; /* number of buffers */ + u_int8_t tx_flags; +#define NX_TXDESC_F_VLAN (1<<8) /* VLAN tagged */ +#define NX_TXDESC_F_TSO (1<<1) /* TSO enabled */ +#define NX_TXDESC_F_CKSUM (1<<0) /* checksum enabled */ + u_int8_t tx_opcode; +#define NX_TXDESC_OP_STOPSTATS (1<<9) /* Stop statistics */ +#define NX_TXDESC_OP_GETSTATS (1<<8) /* Get statistics */ +#define NX_TXDESC_OP_TX_TSO (1<<5) /* TCP packet, do TSO */ +#define NX_TXDESC_OP_TX_IP (1<<4) /* IP packet, compute cksum */ +#define NX_TXDESC_OP_TX_UDP (1<<3) /* UDP packet, compute cksum */ +#define NX_TXDESC_OP_TX_TCP (1<<2) /* TCP packet, compute cksum */ +#define NX_TXDESC_OP_TX (1<<1) /* raw Ethernet packet */ + u_int16_t tx_handle; /* handle of the buffer */ + u_int16_t tx_mss; /* MSS for the packet */ + u_int8_t tx_port; /* interface port */ +#define NX_TXDESC_PORT_S 0 +#define NX_TXDESC_PORT_M 0x0f + u_int8_t tx_hdrlength; /* MAC+IP+TCP length for TSO */ + u_int16_t tx_reserved; + u_int32_t tx_addr3_low; /* low address of buffer 3 */ + u_int32_t tx_addr3_high; /* high address of buffer 3 */ + u_int32_t tx_addr1_low; /* low address of buffer 1 */ + u_int32_t tx_addr1_high; /* high address of buffer 1 */ + u_int16_t tx_buf1_length; /* length of buffer 1 */ + u_int16_t tx_buf2_length; /* length of buffer 2 */ + u_int16_t tx_buf3_length; /* length of buffer 3 */ + u_int16_t tx_buf4_length; /* length of buffer 4 */ + u_int32_t tx_addr4_low; /* low address of buffer 4 */ + u_int32_t tx_addr4_high; /* high address of buffer 4 */ +} __packed; + +struct nx_rxdesc { + u_int16_t rx_handle; /* handle of the buffer */ + u_int16_t rx_reserved; + u_int32_t rx_length; /* length of the buffer */ + u_int64_t rx_addr; /* address of the buffer */ +} __packed; + +struct nx_statusdesc { + u_int16_t rx_port; +#define NX_STSDESC_PORT_S 0 /* interface port */ +#define NX_STSDESC_PORT_M 0x000f +#define NX_STSDESC_STS_S 4 /* completion status */ +#define NX_STSDESC_STS_M 0x00f0 +#define NX_STSDESC_STS_NOCHK 1 /* checksum not verified */ +#define NX_STSDESC_STS_CHKOK 2 /* checksum verified ok */ +#define NX_STSDESC_TYPE_S 8 /* type/index of the ring */ +#define NX_STSDESC_TYPE_M 0x0f00 +#define NX_STSDESC_OPCODE_S 12 /* opcode */ +#define NX_STSDESC_OPCODE_M 0xf000 +#define NX_STSDESC_OPCODE 0xa /* received packet */ + u_int16_t rx_length; /* total length of the packet */ + u_int16_t rx_handle; /* handle of the buffer */ + u_int16_t rx_owner; +#define NX_STSDESC_OWNER_S 0 /* owner of the descriptor */ +#define NX_STSDESC_OWNER_M 0x0003 +#define NX_STSDESC_OWNER_HOST 1 /* owner is the host (t.b.d) */ +#define NX_STSDESC_OWNER_CARD 2 /* owner is the card */ +#define NX_STSDESC_PROTO_S 2 /* protocol type */ +#define NX_STSDESC_PROTO_M 0x003c +} __packed; + +/* + * PCI Express Registers + */ + +/* Interrupt Vector */ +#define NXISR_INT_VECTOR 0x00010100 +#define NXISR_INT_VECTOR_TARGET3 (1<<10) /* interrupt for function 3 */ +#define NXISR_INT_VECTOR_TARGET2 (1<<9) /* interrupt for function 2 */ +#define NXISR_INT_VECTOR_TARGET1 (1<<8) /* interrupt for function 1 */ +#define NXISR_INT_VECTOR_TARGET0 (1<<7) /* interrupt for function 0 */ +#define NXISR_INT_VECTOR_RC_INT (1<<5) /* root complex interrupt */ + +/* Interrupt Mask */ +#define NXISR_INT_MASK 0x00010104 +#define NXISR_INT_MASK_TARGET3 (1<<10) /* mask for function 3 */ +#define NXISR_INT_MASK_TARGET2 (1<<9) /* mask for function 2 */ +#define NXISR_INT_MASK_TARGET1 (1<<8) /* mask for function 1 */ +#define NXISR_INT_MASK_TARGET0 (1<<7) /* mask for function 0 */ +#define NXISR_INT_MASK_RC_INT (1<<5) /* root complex mask */ + +/* + * Network Interface Unit (NIU) registers + */ + +/* Mode Register (see also NXNIU_RESET_SYS_FIFOS) */ +#define NXNIU_MODE 0x00000000 +#define NXNIU_MODE_XGE (1<<2) /* XGE interface enabled */ +#define NXNIU_MODE_GBE (1<<1) /* 4 GbE interfaces enabled */ +#define NXNIU_MODE_FC (1<<0) /* *Fibre Channel enabled */ +#define NXNIU_MODE_DEF NUI_XGE_ENABLE + +/* 10G - 1G Mode Enable Register */ +#define NXNIU_XG_SINGLE_TERM 0x00000004 +#define NXNIU_XG_SINGLE_TERM_ENABLE (1<<0) /* Enable 10G + 1G mode */ +#define NXNIU_XG_SINGLE_TERM_DEF 0 /* Disabled */ + +/* XGE Reset Register */ +#define NXNIU_XG_RESET 0x0000001c +#define NXNIU_XG_RESET_CD (1<<1) /* Reset channels CD */ +#define NXNIU_XG_RESET_AB (1<<0) /* Reset channels AB */ +#define NXNIU_XG_RESET_DEF (NXNIU_XG_RESET_AB|NXNIU_XG_RESET_CD) + +/* Interrupt Mask Register */ +#define NXNIU_INT_MASK 0x00000040 +#define NXNIU_INT_MASK_XG (1<<6) /* XGE Interrupt Mask */ +#define NXNIU_INT_MASK_RES5 (1<<5) /* Reserved bit */ +#define NXNIU_INT_MASK_RES4 (1<<4) /* Reserved bit */ +#define NXNIU_INT_MASK_GB3 (1<<3) /* GbE 3 Interrupt Mask */ +#define NXNIU_INT_MASK_GB2 (1<<2) /* GbE 2 Interrupt Mask */ +#define NXNIU_INT_MASK_GB1 (1<<1) /* GbE 1 Interrupt Mask */ +#define NXNIU_INT_MASK_GB0 (1<<0) /* GbE 0 Interrupt Mask */ +#define NXNIU_INT_MASK_DEF ( \ + NXNIU_INT_MASK_XG|NXNIU_INT_MASK_RES5|NXNIU_INT_MASK_RES4| \ + NXNIU_INT_MASK_GB3|NXNIU_INT_MASK_GB2|NXNIU_INT_MASK_GB1| \ + NXNIU_INT_MASK_GB0) /* Reserved bits enabled */ + +/* Reset System FIFOs Register (needed before changing NXNIU_MODE) */ +#define NXNIU_RESET_SYS_FIFOS 0x00000088 +#define NXNIU_RESET_SYS_FIFOS_RX (1<<31) /* Reset all Rx FIFOs */ +#define NXNIU_RESET_SYS_FIFOS_TX (1<<0) /* Reset all Tx FIFOs */ +#define NXNIU_RESET_SYS_FIFOS_DEF 0 /* Disabled */ + +/* XGE Configuration 0 Register */ +#define NXNIU_XGE_CONFIG0 0x00070000 +#define NXNIU_XGE_CONFIG0_SOFTRST_FIFO (1<<31) /* Soft reset FIFOs */ +#define NXNIU_XGE_CONFIG0_SOFTRST_MAC (1<<4) /* Soft reset XGE MAC */ +#define NXNIU_XGE_CONFIG0_RX_ENABLE (1<<2) /* Enable frame Rx */ +#define NXNIU_XGE_CONFIG0_TX_ENABLE (1<<0) /* Enable frame Tx */ +#define NXNIU_XGE_CONFIG0_DEF 0 /* Disabled */ + +/* XGE Configuration 1 Register */ +#define NXNIU_XGE_CONFIG1 0x00070004 +#define NXNIU_XGE_CONFIG1_PROMISC (1<<13) /* Pass all Rx frames */ +#define NXNIU_XGE_CONFIG1_MCAST_ENABLE (1<<12) /* Rx all multicast frames */ +#define NXNIU_XGE_CONFIG1_SEQ_ERROR (1<<10) /* Sequence error detection */ +#define NXNIU_XGE_CONFIG1_NO_PAUSE (1<<8) /* Ignore pause frames */ +#define NXNIU_XGE_CONFIG1_LOCALERR (1<<6) /* Wire local error */ +#define NXNIU_XGE_CONFIG1_LOCALERR_FE 0 /* Signal with 0xFE */ +#define NXNIU_XGE_CONFIG1_LOCALERR_I 1 /* Signal with Ierr */ +#define NXNIU_XGE_CONFIG1_NO_MAXSIZE (1<<5) /* Ignore max Rx size */ +#define NXNIU_XGE_CONFIG1_CRC_TX (1<<1) /* Append CRC to Tx frames */ +#define NXNIU_XGE_CONFIG1_CRC_RX (1<<0) /* Remove CRC from Rx frames */ +#define NXNIU_XGE_CONFIG1_DEF 0 /* Disabled */ + +/* + * Software defined registers (used by the firmware or the driver) + */ + +#define NXSW_CMD_PRODUCER_OFFSET 0x2208 /* Producer CMD ring index */ +#define NXSW_CMD_CONSUMER_OFFSET 0x220c /* Consumer CMD ring index */ +#define NXSW_RCV_PRODUCER_OFFSET 0x2218 /* Producer Rx ring index */ +#define NXSW_RCV_CONSUMER_OFFSET 0x221c /* Consumer Rx ring index */ +#define NXSW_RCV_GLOBAL_RING 0x2220 /* Address of Rx buffer */ +#define NXSW_RCV_STATUS_RING 0x2224 /* Address of Rx status ring */ +#define NXSW_RCV_STATUS_PRODUCER 0x2228 /* Producer Rx status index */ +#define NXSW_RCV_STATUS_CONSUMER 0x222c /* Consumer Rx status index */ +#define NXSW_CMD_ADDR_HI 0x2230 /* CMD ring phys address */ +#define NXSW_CMD_ADDR_LO 0x2234 /* CMD ring phys address */ +#define NXSW_CMD_RING_SIZE 0x2238 /* Entries in the CMD ring */ +#define NXSW_RCV_RING_SIZE 0x223c /* Entries in the Rx ring */ +#define NXSW_JRCV_RING_SIZE 0x2240 /* Entries in the jumbo ring */ +#define NXSW_RCVPEG_STATE 0x2248 /* State of the NX2031 */ +#define NXSW_CMDPEG_STATE 0x2250 /* State of the firmware */ +#define NXSW_CMDPEG_STATE_INIT_START 0xff00 /* Start of initialization */ +#define NXSW_CMDPEG_STATE_INIT_DONE 0xff01 /* Initialization complete */ +#define NXSW_CMDPEG_STATE_INIT_FAILED 0xffff /* Initialization failed */ +#define NXSW_GLOBAL_INT_COAL 0x2280 /* Interrupt coalescing */ +#define NXSW_INT_COAL_MODE 0x2284 /* Reserved */ +#define NXSW_MAX_RCV_BUFS 0x2288 /* Interrupt tuning register */ +#define NXSW_TX_INT_THRESHOLD 0x228c /* Interrupt tuning register */ +#define NXSW_RX_PKT_TIMER 0x2290 /* Interrupt tuning register */ +#define NXSW_TX_PKT_TIMER 0x2294 /* Interrupt tuning register */ +#define NXSW_RX_PKT_CNT 0x2298 /* Rx packet count register */ +#define NXSW_RX_TMR_CNT 0x229c /* Rx timer count register */ +#define NXSW_XG_STATE 0x22a0 /* 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_OFFSET 0x2300 /* Producer jumbo ring index */ +#define NXSW_JRCV_CONSUMER_OFFSET 0x2304 /* Consumer jumbo ring index */ +#define NXSW_JRCV_GLOBAL_RING 0x2220 /* Address of jumbo buffer */ + +/* + * Secondary Interrupt Registers + */ + +/* I2Q Register */ +#define NXI2Q_CLR_PCI_HI 0x00000034 +#define NXI2Q_CLR_PCI_HI_PHY (1<<13) /* PHY interrupt */ +#define NXI2Q_CLR_PCI_HI_DEF 0 /* Cleared */ + +/* Reset Unit Register */ +#define NXROMUSB_GLB_SW_RESET 0x1a100008 +#define NXROMUSB_GLB_SW_RESET_EFC_SIU (1<<30) /* EFC_SIU reset */ +#define NXROMUSB_GLB_SW_RESET_NIU (1<<29) /* NIU software reset */ +#define NXROMUSB_GLB_SW_RESET_U0QMSQG (1<<28) /* Network side QM_SQG reset */ +#define NXROMUSB_GLB_SW_RESET_U1QMSQG (1<<27) /* Storage side QM_SQG reset */ +#define NXROMUSB_GLB_SW_RESET_C2C1 (1<<26) /* Chip to Chip 1 reset */ +#define NXROMUSB_GLB_SW_RESET_C2C0 (1<<25) /* Chip to Chip 2 reset */ +#define NXROMUSB_GLB_SW_RESET_U1PEGI (1<<11) /* Storage Pegasus I-Cache */ +#define NXROMUSB_GLB_SW_RESET_U1PEGD (1<<10) /* Storage Pegasus D-Cache */ +#define NXROMUSB_GLB_SW_RESET_U1PEG3 (1<<9) /* Storage Pegasus3 reset */ +#define NXROMUSB_GLB_SW_RESET_U1PEG2 (1<<8) /* Storage Pegasus2 reset */ +#define NXROMUSB_GLB_SW_RESET_U1PEG1 (1<<7) /* Storage Pegasus1 reset */ +#define NXROMUSB_GLB_SW_RESET_U1PEG0 (1<<6) /* Storage Pegasus0 reset */ +#define NXROMUSB_GLB_SW_RESET_U0PEGI (1<<11) /* Network Pegasus I-Cache */ +#define NXROMUSB_GLB_SW_RESET_U0PEGD (1<<10) /* Network Pegasus D-Cache */ +#define NXROMUSB_GLB_SW_RESET_U0PEG3 (1<<9) /* Network Pegasus3 reset */ +#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_DEF 0xffffffff + +/* Casper Reset Register */ +#define NXROMUSB_GLB_CAS_RESET 0x1a100038 +#define NXRUMUSB_GLB_CAS_RESET_ENABLE (1<<0) /* Enable Casper reset */ +#define NXROMUSB_GLB_CAS_RESET_DEF 0 /* Disabled */ + +#endif /* _NX_REG_H */ |