diff options
author | mjacob <mjacob@FreeBSD.org> | 2000-10-16 23:08:45 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2000-10-16 23:08:45 +0000 |
commit | fa60c9131abce6e30c48c2193513d79197871073 (patch) | |
tree | c82633fd2f3ec460cf2758593f744acccd0af2f0 | |
parent | 0630faf57d33ad66926819237bb3ac2222b6eb65 (diff) | |
download | FreeBSD-src-fa60c9131abce6e30c48c2193513d79197871073.zip FreeBSD-src-fa60c9131abce6e30c48c2193513d79197871073.tar.gz |
Very early and very *very* lightly tested support for LIVENGOOD chipset
(followon to WISEMAN). Presumably some flavors are also no multimode copper
as well.
-rw-r--r-- | sys/pci/if_wx.c | 97 | ||||
-rw-r--r-- | sys/pci/if_wxreg.h | 43 | ||||
-rw-r--r-- | sys/pci/if_wxvar.h | 88 |
3 files changed, 198 insertions, 30 deletions
diff --git a/sys/pci/if_wx.c b/sys/pci/if_wx.c index c509f58..fc7b1c1 100644 --- a/sys/pci/if_wx.c +++ b/sys/pci/if_wx.c @@ -174,7 +174,12 @@ wx_match(parent, match, aux) if (PCI_VENDOR(pa->pa_id) != WX_VENDOR_INTEL) { return (0); } - if (PCI_PRODUCT(pa->pa_id) != WX_PRODUCT_82452) { + switch (PCI_PRODUCT(pa->pa_id)) { + case WX_PRODUCT_82452: + case WX_PRODUCT_LIVENGOOD: + case WX_PRODUCT_82452_SC: + break; + default: return (0); } return (1); @@ -224,7 +229,7 @@ wx_attach(parent, self, aux) return; } printf("%s: interrupting at %s\n", sc->wx_name, intrstr); - sc->revision = + sc->wx_idnrev = (PCI_PRODUCT(pa->pa_id) << 16) | pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0xff; data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); @@ -510,12 +515,22 @@ static wx_softc_t *wxlist; static int wx_probe(device_t dev) { - if ((pci_get_vendor(dev) == WX_VENDOR_INTEL) && - (pci_get_device(dev) == WX_PRODUCT_82452)) { - device_set_desc(dev, "Intel GigaBit Ethernet"); - return 0; + if (pci_get_vendor(dev) != WX_VENDOR_INTEL) { + return (ENXIO); + } + switch (pci_get_device(dev)) { + case WX_PRODUCT_82452: + device_set_desc(dev, "Intel GigaBit Ethernet (WISEMAN)"); + break; + case WX_PRODUCT_LIVENGOOD: + device_set_desc(dev, "Intel GigaBit Ethernet (LIVENGOOD)"); + case WX_PRODUCT_82452_SC: + device_set_desc(dev, "Intel GigaBit Ethernet (LIVENGOOD_SC)"); + break; + default: + return (ENXIO); } - return (ENXIO); + return (0); } static int @@ -557,8 +572,14 @@ wx_attach(device_t dev) } } + s = splimp(); /* + * get revision && id... + */ + sc->wx_idnrev = (pci_get_device(dev) << 16) | (pci_get_revid(dev)); + + /* * Enable bus mastering, make sure that the cache line size is right. */ val = pci_read_config(dev, PCIR_COMMAND, 2); @@ -570,10 +591,6 @@ wx_attach(device_t dev) pci_write_config(dev, PCIR_CACHELNSZ, 0x10, 1); } - /* - * get revision - */ - sc->revision = pci_read_config(dev, PCIR_CLASS, 1); /* * Map control/status registers. @@ -772,9 +789,9 @@ wx_attach_common(sc) /* * First, check for revision support. */ - if (sc->revision < 2) { - printf("%s: cannot support revision %d chips\n", - sc->wx_name, sc->revision); + if (sc->wx_idnrev < WX_WISEMAN_2_0) { + printf("%s: cannot support ID 0x%x, revision %d chips\n", + sc->wx_name, sc->wx_idnrev >> 16, sc->wx_idnrev & 0xffff); return (ENXIO); } @@ -1265,7 +1282,7 @@ wx_check_link(sc) sc->wx_name); } WRITE_CSR(sc, WXREG_XMIT_CFGW, WXTXCW_DEFAULT & ~WXTXCW_ANE); - if (sc->revision == 2) + if (sc->wx_idnrev < WX_WISEMAN_2_1) sc->wx_dcr &= ~WXDCR_TFCE; sc->wx_dcr |= WXDCR_SLU; WRITE_CSR(sc, WXREG_DCR, sc->wx_dcr); @@ -1587,14 +1604,14 @@ wx_hw_stop(sc) wx_softc_t *sc; { u_int32_t icr; - if (sc->revision == 2) { + if (sc->wx_idnrev < WX_WISEMAN_2_1) { wx_mwi_whackon(sc); } WRITE_CSR(sc, WXREG_DCR, WXDCR_RST); DELAY(20 * 1000); WRITE_CSR(sc, WXREG_IMASK, ~0); icr = READ_CSR(sc, WXREG_ICR); - if (sc->revision == 2) { + if (sc->wx_idnrev < WX_WISEMAN_2_1) { wx_mwi_unwhack(sc); } WX_DISABLE_INT(sc); @@ -1620,11 +1637,18 @@ wx_hw_initialize(sc) { int i; + if (IS_LIVENGOOD(sc)) { + if ((READ_CSR(sc, WXREG_DSR) & WXDSR_TBIMODE) == 0) { + printf("%s: no fibre mode detected\n", sc->wx_name); + return (-1); + } + } + WRITE_CSR(sc, WXREG_VET, 0); for (i = 0; i < (WX_VLAN_TAB_SIZE << 2); i += 4) { WRITE_CSR(sc, (WXREG_VFTA + i), 0); } - if (sc->revision == 2) { + if (sc->wx_idnrev < WX_WISEMAN_2_1) { wx_mwi_whackon(sc); WRITE_CSR(sc, WXREG_RCTL, WXRCTL_RST); DELAY(5 * 1000); @@ -1649,7 +1673,7 @@ wx_hw_initialize(sc) i++; } - if (sc->revision == 2) { + if (sc->wx_idnrev < WX_WISEMAN_2_1) { WRITE_CSR(sc, WXREG_RCTL, 0); DELAY(1 * 1000); wx_mwi_unwhack(sc); @@ -1668,6 +1692,14 @@ wx_hw_initialize(sc) WRITE_CSR(sc, WXREG_DCR, sc->wx_dcr | WXDCR_LRST); DELAY(50 * 1000); + + if (IS_LIVENGOOD(sc)) { + u_int16_t tew; + wx_read_eeprom(sc, &tew, WX_EEPROM_CTLR2_OFF, 1); + tew = (tew & WX_EEPROM_CTLR2_SWDPIO) << WX_EEPROM_EXT_SHIFT; + WRITE_CSR(sc, WXREG_EXCT, (u_int32_t)tew); + } + if (sc->wx_dcr & (WXDCR_RFCE|WXDCR_TFCE)) { WRITE_CSR(sc, WXREG_FCAL, FC_FRM_CONST_LO); WRITE_CSR(sc, WXREG_FCAH, FC_FRM_CONST_HI); @@ -1678,7 +1710,8 @@ wx_hw_initialize(sc) WRITE_CSR(sc, WXREG_FCT, 0); } WRITE_CSR(sc, WXREG_FLOW_XTIMER, WX_XTIMER_DFLT); - if (sc->revision == 2) { + + if (sc->wx_idnrev < WX_WISEMAN_2_1) { WRITE_CSR(sc, WXREG_FLOW_RCV_HI, 0); WRITE_CSR(sc, WXREG_FLOW_RCV_LO, 0); sc->wx_dcr &= ~(WXDCR_RFCE|WXDCR_TFCE); @@ -1848,7 +1881,11 @@ wx_init(xsc) WRITE_CSR(sc, WXREG_TDT, 0); WRITE_CSR(sc, WXREG_TQSA_HI, 0); WRITE_CSR(sc, WXREG_TQSA_LO, 0); - WRITE_CSR(sc, WXREG_TIPG, WX_TIPG_DFLT); + if (IS_WISEMAN(sc)) { + WRITE_CSR(sc, WXREG_TIPG, WX_WISEMAN_TIPG_DFLT); + } else { + WRITE_CSR(sc, WXREG_TIPG, WX_LIVENGOOD_TIPG_DFLT); + } WRITE_CSR(sc, WXREG_TIDV, sc->wx_txint_delay); WRITE_CSR(sc, WXREG_TCTL, (WXTCTL_CT(WX_COLLISION_THRESHOLD) | WXTCTL_COLD(WX_FDX_COLLISION_DX) | WXTCTL_EN)); @@ -2054,6 +2091,7 @@ wx_ifmedia_sts(ifp, ifmr) struct ifnet *ifp; struct ifmediareq *ifmr; { + u_int32_t dsr; struct wx_softc *sc = SOFTC_IFP(ifp); ifmr->ifm_status = IFM_AVALID; @@ -2062,7 +2100,20 @@ wx_ifmedia_sts(ifp, ifmr) if (sc->linkup == 0) return; - ifmr->ifm_status |= IFM_ACTIVE|IFM_1000_SX; - if (READ_CSR(sc, WXREG_DSR) & WXDSR_FD) + ifmr->ifm_status |= IFM_ACTIVE; + dsr = READ_CSR(sc, WXREG_DSR); + if (IS_LIVENGOOD(sc)) { + if (dsr & WXDSR_1000BT) { + ifmr->ifm_status |= IFM_1000_SX; + } else if (dsr & WXDSR_100BT) { + ifmr->ifm_status |= IFM_100_FX; /* ?? */ + } else { + ifmr->ifm_status |= IFM_10_T; /* ?? */ + } + } else { + ifmr->ifm_status |= IFM_1000_SX; + } + if (dsr & WXDSR_FD) { ifmr->ifm_active |= IFM_FDX; + } } diff --git a/sys/pci/if_wxreg.h b/sys/pci/if_wxreg.h index 9a7309b..da78b6f 100644 --- a/sys/pci/if_wxreg.h +++ b/sys/pci/if_wxreg.h @@ -29,10 +29,21 @@ #define WX_VENDOR_INTEL 0x8086 #define WX_PRODUCT_82452 0x1000 +#define WX_PRODUCT_LIVENGOOD 0x1001 +#define WX_PRODUCT_82452_SC 0x1003 #define WX_MMBA 0x10 #define MWI 0x10 /* Memory Write Invalidate */ #define WX_CACHELINE_SIZE 0x20 +/* Join PCI ID and revision into one value */ +#define WX_WISEMAN_0 0x10000000 +#define WX_WISEMAN_2_0 0x10000002 +#define WX_WISEMAN_2_1 0x10000003 +#define WX_LIVENGOOD 0x10010000 + +#define IS_WISEMAN(sc) ((sc)->wx_idnrev < WX_LIVENGOOD) +#define IS_LIVENGOOD(sc) (!IS_WISEMAN(sc)) + /* * Information about this chipset gathered from a released Intel Linux driver, * which was clearly a port of an NT driver. @@ -107,6 +118,8 @@ typedef struct { #define WXREG_DCR 0x00000000 #define WXREG_DSR 0x00000008 #define WXREG_EECDR 0x00000010 +#define WXREG_EXCT 0x00000018 +#define WXREG_MDIC 0x00000020 #define WXREG_FCAL 0x00000028 #define WXREG_FCAH 0x0000002C #define WXREG_FCT 0x00000030 @@ -165,6 +178,11 @@ typedef struct { #define WXDCR_LRST 0x8 /* Link Reset */ #define WXDCR_SLU 0x40 /* Set Link Up */ #define WXDCR_ILOS 0x80 /* Invert Loss-of-Signal */ +#define WXDCR_100BT 0x100 /* LIVENGOOD: Set 100BaseT */ +#define WXDCR_1000BT 0x200 /* LIVENGOOD: Set 1000BaseT */ +#define WXDCR_BEM32 0x400 /* LIVENGOOD: Set Big Endian 32 (?) */ +#define WXDCR_FRCSPD 0x800 /* LIVENGOOD: Force Speed (?) */ +#define WXDCR_FRCDPX 0x1000 /* LIVENGOOD: Force Full Duplex */ /* * General purpose I/O pins @@ -201,6 +219,13 @@ typedef struct { #define WXDSR_TXCLK 0x4 /* transmit clock running */ #define WXDSR_RBCLK 0x8 /* receive clock running */ #define WXDSR_TXOFF 0x10 /* transmit paused */ +#define WXDSR_TBIMODE 0x20 /* LIVENGOOD: Fibre Mode */ +#define WXDSR_100BT 0x40 /* LIVENGOOD: 100BaseT */ +#define WXDSR_1000BT 0x80 /* LIVENGOOD: 1000BaseT */ +#define WXDSR_ASDV 0x300 /* LIVENGOOD: ?? */ +#define WXDSR_MTXCKOK 0x400 /* LIVENGOOD: ?? */ +#define WXDSR_PCI66 0x800 /* LIVENGOOD: 66 MHz bus */ +#define WXDSR_BUS64 0x1000 /* LIVENGOOD: In 64 bit slot */ /* * EEPROM Register Defines @@ -236,8 +261,10 @@ typedef struct { #define WXISR_LSC 0x4 /* link status change */ #define WXISR_RXSEQ 0x8 /* receive sequence error */ #define WXISR_RXDMT0 0x10 /* receiver ring 0 getting empty */ +#define WXISR_RXDMT1 0x20 /* receiver ring 1 getting empty */ #define WXISR_RXO 0x40 /* receiver overrun */ #define WXISR_RXT0 0x80 /* ring 0 receiver timer interrupt */ +#define WXISR_RXT1 0x100 /* ring 1 receiver timer interrupt */ #define WXISR_PCIE 0x200 /* ?? Probably PCI interface error... */ #define WXIENABLE_DEFAULT \ @@ -256,12 +283,17 @@ typedef struct { #define WXRCTL_MPE 0x10 /* multicast promiscuous mode */ #define WXRCTL_LPE 0x20 /* large packet enable */ #define WXRCTL_BAM 0x8000 /* broadcast accept mode */ +#define WXRCTL_BSEX 0x2000000 /* LIVENGOOD: Buffer Size Extension */ -#define WXRCTL_2KRBUF (0 << 16) /* 2-Kbyte Receive Buffers */ -#define WXRCTL_1KRBUF (1 << 16) /* 1-Kbyte Receive Buffers */ +#define WXRCTL_2KRBUF (0 << 16) /* 2KB Receive Buffers */ +#define WXRCTL_1KRBUF (1 << 16) /* 1KB Receive Buffers */ #define WXRCTL_512BRBUF (2 << 16) /* 512 Byte Receive Buffers */ #define WXRCTL_256BRBUF (3 << 16) /* 256 Byte Receive Buffers */ +#define WXRCTL_4KRBUF (3 << 16) /* LIVENGOOD: 4KB Receive Buffers */ +#define WXRCTL_8KRBUF (2 << 16) /* LIVENGOOD: 8KB Receive Buffers */ +#define WXRCTL_16KRBUF (1 << 16) /* LIVENGOOD: 16KB Receive Buffers */ + /* * Receive Delay Timer Register bits. @@ -327,12 +359,17 @@ typedef struct { #define WX_EEPROM_CTLR1_SWDPIO_SHIFT 5 #define WX_EEPROM_CTLR1_ILOS (1 << 4) +#define WX_EEPROM_CTLR2_OFF 0xF +#define WX_EEPROM_CTLR2_SWDPIO 0xF0 +#define WX_EEPROM_EXT_SHIFT 4 + #define WX_XTIMER_DFLT 0x100 #define WX_RCV_FLOW_HI_DFLT 0x8000 #define WX_RCV_FLOW_LO_DFLT 0x4000 -#define WX_TIPG_DFLT (10 | (2 << 10) | (10 << 20)) +#define WX_WISEMAN_TIPG_DFLT (10 | (2 << 10) | (10 << 20)) +#define WX_LIVENGOOD_TIPG_DFLT (6 | (8 << 10) | (6 << 20)) #define WX_CRC_LENGTH 4 diff --git a/sys/pci/if_wxvar.h b/sys/pci/if_wxvar.h index 3288a24..71fec0e 100644 --- a/sys/pci/if_wxvar.h +++ b/sys/pci/if_wxvar.h @@ -203,6 +203,87 @@ struct wxmdvar { #define WRITE_CSR(sc, reg, val) \ bus_space_write_4((sc)->w.st, (sc)->w.sh, (reg), (val)) +#elif defined(__OpenBSD__) +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/protosw.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/errno.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/device.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> +#include <net/if_media.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/in_var.h> +#include <netinet/ip.h> +#include <netinet/if_ether.h> +#endif +#ifdef NS +#include <netns/ns.h> +#include <netns/ns_if.h> +#endif + +#include "bpfilter.h" +#if NBPFILTER > 0 +#include <net/bpf.h> +#include <net/bpfdesc.h> +#endif + +#include <vm/vm.h> +#include <vm/vm_param.h> +#include <vm/vm_kern.h> +#include <machine/bus.h> +#include <machine/intr.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> +#include <dev/pci/if_wxreg.h> + +struct wxmdvar { + struct device dev; /* generic device structures */ + void * ih; /* interrupt handler cookie */ + struct arpcom arpcom; /* ethernet common part */ + pci_chipset_tag_t pci_pc; + pcitag_t pci_tag; + u_int32_t cmdw; + bus_space_tag_t st; /* bus space tag */ + bus_space_handle_t sh; /* bus space handle */ + struct ifmedia ifm; + struct wx_softc * next; +}; +#define wx_dev w.dev +#define wx_enaddr w.arpcom.ac_enaddr +#define wx_cmdw w.cmdw +#define wx_media w.ifm +#define wx_next w.next + +#define wx_if w.arpcom.ac_if +#define wx_name w.dev.dv_xname + +#define IOCTL_CMD_TYPE u_long +#define WXMALLOC(len) malloc(len, M_DEVBUF, M_NOWAIT) +#define WXFREE(ptr) free(ptr, M_DEVBUF) +#define SOFTC_IFP(ifp) ifp->if_softc +#define WX_BPFTAP_ARG(ifp) (ifp)->if_bpf +#define TIMEOUT(sc, func, arg, time) timeout(func, arg, time) +#define VTIMEOUT(sc, func, arg, time) timeout(func, arg, time) +#define UNTIMEOUT(f, arg, sc) untimeout(f, arg) +#define INLINE inline + +#define vm_offset_t vaddr_t +#define READ_CSR _read_csr +#define WRITE_CSR _write_csr + #endif @@ -235,16 +316,15 @@ typedef struct wx_softc { /* * misc goodies */ - u_int32_t : 17, + u_int32_t : 25, wx_no_flow : 1, wx_ilos : 1, wx_no_ilos : 1, wx_debug : 1, ane_failed : 1, linkup : 1, - all_mcasts : 1, - revision : 8; /* chip revision */ - + all_mcasts : 1; + u_int32_t wx_idnrev; /* chip revision && PCI ID */ u_int16_t wx_cfg1; u_int16_t wx_txint_delay; u_int32_t wx_ienable; /* current ienable to use */ |