if_vx_pci.c revision 119690
11902Swollman/*
21902Swollman * Copyright (C) 1996 Naoki Hamada <nao@tom-yam.or.jp>
31902Swollman * All rights reserved.
41902Swollman *
51902Swollman * Redistribution and use in source and binary forms, with or without
61902Swollman * modification, are permitted provided that the following conditions
71902Swollman * are met:
88870Srgrimes * 1. Redistributions of source code must retain the above copyright
91902Swollman *    notice, this list of conditions and the following disclaimer.
101902Swollman * 2. Redistributions in binary form must reproduce the above copyright
111902Swollman *    notice, this list of conditions and the following disclaimer in the
128870Srgrimes *    documentation and/or other materials provided with the distribution.
131902Swollman * 3. Neither the name of the author nor the names of any co-contributors
141902Swollman *    may be used to endorse or promote products derived from this software
151902Swollman *    without specific prior written permission.
168870Srgrimes *
171902Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
181902Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191902Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
208870Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
211902Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221902Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231902Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
248870Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251902Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261902Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271902Swollman * SUCH DAMAGE.
281902Swollman */
298870Srgrimes
301902Swollman#include <sys/cdefs.h>
311902Swollman__FBSDID("$FreeBSD: head/sys/dev/vx/if_vx_pci.c 119690 2003-09-02 17:30:40Z jhb $");
328870Srgrimes
331902Swollman#include <sys/param.h>
341902Swollman#include <sys/systm.h>
351902Swollman#include <sys/kernel.h>
361902Swollman#include <sys/socket.h>
371902Swollman
381902Swollman#include <net/if.h>
391902Swollman#include <net/if_arp.h>
401902Swollman
411902Swollman#include <machine/bus_pio.h>
421902Swollman#include <machine/bus.h>
431902Swollman#include <machine/resource.h>
441902Swollman#include <sys/bus.h>
451902Swollman#include <sys/rman.h>
461902Swollman
471902Swollman#include <dev/pci/pcivar.h>
488870Srgrimes#include <dev/pci/pcireg.h>
491902Swollman
501902Swollman#include <dev/vx/if_vxreg.h>
511902Swollman
521902Swollmanstatic void vx_pci_shutdown(device_t);
531902Swollmanstatic int vx_pci_probe(device_t);
541902Swollmanstatic int vx_pci_attach(device_t);
551902Swollman
561902Swollmanstatic device_method_t vx_methods[] = {
571902Swollman	/* Device interface */
581902Swollman	DEVMETHOD(device_probe,		vx_pci_probe),
591902Swollman	DEVMETHOD(device_attach,	vx_pci_attach),
601902Swollman	DEVMETHOD(device_shutdown,	vx_pci_shutdown),
611902Swollman
621902Swollman	{ 0, 0 }
631902Swollman};
641902Swollman
651902Swollmanstatic driver_t vx_driver = {
661902Swollman	"vx",
671902Swollman	vx_methods,
681902Swollman	sizeof(struct vx_softc)
691902Swollman};
701902Swollman
711902Swollmanstatic devclass_t vx_devclass;
721902Swollman
731902SwollmanDRIVER_MODULE(vx, pci, vx_driver, vx_devclass, 0, 0);
741902SwollmanMODULE_DEPEND(vx, pci, 1, 1, 1);
751902SwollmanMODULE_DEPEND(vx, ether, 1, 1, 1);
761902Swollman
771902Swollmanstatic void
781902Swollmanvx_pci_shutdown(
791902Swollman	device_t dev)
801902Swollman{
811902Swollman   struct vx_softc	*sc;
821902Swollman
831902Swollman   sc = device_get_softc(dev);
841902Swollman   vxstop(sc);
851902Swollman   return;
861902Swollman}
871902Swollman
881902Swollmanstatic int
891902Swollmanvx_pci_probe(
901902Swollman	device_t dev)
911902Swollman{
921902Swollman   u_int32_t		device_id;
931902Swollman
941902Swollman   device_id = pci_read_config(dev, PCIR_DEVVENDOR, 4);
951902Swollman
961902Swollman   if(device_id == 0x590010b7ul) {
971902Swollman      device_set_desc(dev, "3COM 3C590 Etherlink III PCI");
981902Swollman      return(0);
991902Swollman   }
1001902Swollman   if(device_id == 0x595010b7ul || device_id == 0x595110b7ul ||
1011902Swollman	device_id == 0x595210b7ul) {
1021902Swollman      device_set_desc(dev, "3COM 3C595 Etherlink III PCI");
1031902Swollman      return(0);
1041902Swollman   }
1051902Swollman	/*
1061902Swollman	 * The (Fast) Etherlink XL adapters are now supported by
1071902Swollman	 * the xl driver, which uses bus master DMA and is much
1081902Swollman	 * faster. (And which also supports the 3c905B.
1091902Swollman	 */
1101902Swollman#ifdef VORTEX_ETHERLINK_XL
1111902Swollman   if(device_id == 0x900010b7ul || device_id == 0x900110b7ul) {
1121902Swollman      device_set_desc(dev, "3COM 3C900 Etherlink XL PCI");
1131902Swollman      return(0);
1141902Swollman   }
1151902Swollman   if(device_id == 0x905010b7ul || device_id == 0x905110b7ul) {
1161902Swollman      device_set_desc(dev, "3COM 3C905 Etherlink XL PCI");
1171902Swollman      return(0);
1181902Swollman   }
1191902Swollman#endif
1201902Swollman   return (ENXIO);
1211902Swollman}
1221902Swollman
1231902Swollmanstatic int
1241902Swollmanvx_pci_attach(
1251902Swollman	device_t dev)
1261902Swollman{
1271902Swollman    struct vx_softc *sc;
1281902Swollman    int rid;
1291902Swollman
1301902Swollman    sc = device_get_softc(dev);
1311902Swollman
1321902Swollman    rid = PCIR_BAR(0);
1331902Swollman    sc->vx_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
1341902Swollman	0, ~0, 1, RF_ACTIVE);
1351902Swollman
1361902Swollman    if (sc->vx_res == NULL)
1371902Swollman	goto bad;
1381902Swollman
1391902Swollman    sc->vx_btag = rman_get_bustag(sc->vx_res);
1401902Swollman    sc->vx_bhandle = rman_get_bushandle(sc->vx_res);
1411902Swollman
1421902Swollman    rid = 0;
1431902Swollman    sc->vx_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
1441902Swollman	RF_SHAREABLE | RF_ACTIVE);
1451902Swollman
1461902Swollman    if (sc->vx_irq == NULL)
1471902Swollman	goto bad;
1481902Swollman
1498870Srgrimes    if (bus_setup_intr(dev, sc->vx_irq, INTR_TYPE_NET,
1508870Srgrimes	vxintr, sc, &sc->vx_intrhand))
1511902Swollman	goto bad;
1521902Swollman
1531902Swollman    if (vxattach(sc) == 0) {
1541902Swollman	goto bad;
1551902Swollman    }
1561902Swollman
1571902Swollman    /* defect check for 3C590 */
1581902Swollman    if ((pci_read_config(dev, PCIR_DEVVENDOR, 4) >> 16) == 0x5900) {
1591902Swollman	GO_WINDOW(0);
1601902Swollman	if (vxbusyeeprom(sc))
1611902Swollman	    goto bad;
1621902Swollman	CSR_WRITE_2(sc, VX_W0_EEPROM_COMMAND,
1631902Swollman	    EEPROM_CMD_RD | EEPROM_SOFT_INFO_2);
1641902Swollman	if (vxbusyeeprom(sc))
1651902Swollman	    goto bad;
1661902Swollman	if (!(CSR_READ_2(sc, VX_W0_EEPROM_DATA) & NO_RX_OVN_ANOMALY)) {
1671902Swollman	    printf("Warning! Defective early revision adapter!\n");
1681902Swollman	}
1691902Swollman    }
1701902Swollman
1711902Swollman    return(0);
1721902Swollman
1731902Swollmanbad:
1741902Swollman    if (sc->vx_intrhand != NULL)
1751902Swollman	bus_teardown_intr(dev, sc->vx_irq, sc->vx_intrhand);
1761902Swollman    if (sc->vx_res != NULL)
1771902Swollman	bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->vx_res);
1781902Swollman    if (sc->vx_irq != NULL)
1791902Swollman	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vx_irq);
1801902Swollman    return(ENXIO);
1811902Swollman}
1821902Swollman