if_vx_pci.c revision 139749
159191Skris/*-
259191Skris * Copyright (C) 1996 Naoki Hamada <nao@tom-yam.or.jp>
359191Skris * All rights reserved.
459191Skris *
559191Skris * Redistribution and use in source and binary forms, with or without
659191Skris * modification, are permitted provided that the following conditions
759191Skris * are met:
859191Skris * 1. Redistributions of source code must retain the above copyright
959191Skris *    notice, this list of conditions and the following disclaimer.
1059191Skris * 2. Redistributions in binary form must reproduce the above copyright
1159191Skris *    notice, this list of conditions and the following disclaimer in the
1259191Skris *    documentation and/or other materials provided with the distribution.
1359191Skris * 3. Neither the name of the author nor the names of any co-contributors
1459191Skris *    may be used to endorse or promote products derived from this software
15269682Sjkim *    without specific prior written permission.
1659191Skris *
1759191Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1859191Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1959191Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2059191Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2159191Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22111147Snectar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2359191Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2459191Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2559191Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2659191Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2759191Skris * SUCH DAMAGE.
2859191Skris */
2959191Skris
3059191Skris#include <sys/cdefs.h>
3159191Skris__FBSDID("$FreeBSD: head/sys/dev/vx/if_vx_pci.c 139749 2005-01-06 01:43:34Z imp $");
3259191Skris
3359191Skris#include <sys/param.h>
3459191Skris#include <sys/systm.h>
3559191Skris#include <sys/kernel.h>
3659191Skris#include <sys/module.h>
3759191Skris#include <sys/socket.h>
3859191Skris
3959191Skris#include <net/if.h>
4059191Skris#include <net/if_arp.h>
4159191Skris
4259191Skris#include <machine/bus_pio.h>
4359191Skris#include <machine/bus.h>
4459191Skris#include <machine/resource.h>
4559191Skris#include <sys/bus.h>
4659191Skris#include <sys/rman.h>
4759191Skris
4859191Skris#include <dev/pci/pcivar.h>
4959191Skris#include <dev/pci/pcireg.h>
5059191Skris
5159191Skris#include <dev/vx/if_vxreg.h>
5259191Skris#include <dev/vx/if_vxvar.h>
5359191Skris
5459191Skrisstatic void vx_pci_shutdown(device_t);
5559191Skrisstatic int vx_pci_probe(device_t);
5659191Skrisstatic int vx_pci_attach(device_t);
5759191Skris
5859191Skrisstatic device_method_t vx_methods[] = {
5959191Skris	/* Device interface */
6059191Skris	DEVMETHOD(device_probe, vx_pci_probe),
6159191Skris	DEVMETHOD(device_attach, vx_pci_attach),
6259191Skris	DEVMETHOD(device_shutdown, vx_pci_shutdown),
6359191Skris
6459191Skris	{0, 0}
6559191Skris};
6659191Skris
6759191Skrisstatic driver_t vx_driver = {
68269682Sjkim	"vx",
69269682Sjkim	vx_methods,
70269682Sjkim	sizeof(struct vx_softc)
71269682Sjkim};
7259191Skris
7359191Skrisstatic devclass_t vx_devclass;
74284283Sjkim
75284283SjkimDRIVER_MODULE(vx, pci, vx_driver, vx_devclass, 0, 0);
76284283SjkimMODULE_DEPEND(vx, pci, 1, 1, 1);
77284283SjkimMODULE_DEPEND(vx, ether, 1, 1, 1);
7859191Skris
7959191Skrisstatic void
8059191Skrisvx_pci_shutdown(device_t dev)
8159191Skris{
8259191Skris	struct vx_softc *sc;
8359191Skris
8468651Skris	sc = device_get_softc(dev);
8559191Skris	vxstop(sc);
8659191Skris}
8759191Skris
8859191Skrisstatic int
8959191Skrisvx_pci_probe(device_t dev)
90284283Sjkim{
91284283Sjkim	u_int32_t device_id;
92284283Sjkim
93284283Sjkim	device_id = pci_read_config(dev, PCIR_DEVVENDOR, 4);
9459191Skris
9559191Skris	if (device_id == 0x590010b7ul) {
9659191Skris		device_set_desc(dev, "3COM 3C590 Etherlink III PCI");
9759191Skris		return (0);
9859191Skris	}
9959191Skris	if (device_id == 0x595010b7ul || device_id == 0x595110b7ul ||
10059191Skris	    device_id == 0x595210b7ul) {
10159191Skris		device_set_desc(dev, "3COM 3C595 Etherlink III PCI");
10259191Skris		return (0);
10359191Skris	}
10459191Skris	/*
10559191Skris	 * The (Fast) Etherlink XL adapters are now supported by
10659191Skris	 * the xl driver, which uses bus master DMA and is much
10759191Skris	 * faster. (And which also supports the 3c905B.
108111147Snectar	 */
109111147Snectar#ifdef VORTEX_ETHERLINK_XL
110238405Sjkim	if (device_id == 0x900010b7ul || device_id == 0x900110b7ul) {
111111147Snectar		device_set_desc(dev, "3COM 3C900 Etherlink XL PCI");
112111147Snectar		return (0);
113111147Snectar	}
114111147Snectar	if (device_id == 0x905010b7ul || device_id == 0x905110b7ul) {
11559191Skris		device_set_desc(dev, "3COM 3C905 Etherlink XL PCI");
11659191Skris		return (0);
11759191Skris	}
11859191Skris#endif
11959191Skris	return (ENXIO);
12059191Skris}
12159191Skris
12259191Skrisstatic int
12359191Skrisvx_pci_attach(device_t dev)
12459191Skris{
12559191Skris	struct vx_softc *sc;
12659191Skris	int rid;
12759191Skris
12859191Skris	sc = device_get_softc(dev);
12959191Skris
13059191Skris	rid = PCIR_BAR(0);
13159191Skris	sc->vx_res =
13259191Skris	    bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
13359191Skris
13459191Skris	if (sc->vx_res == NULL)
13559191Skris		goto bad;
13659191Skris
13759191Skris	sc->bst = rman_get_bustag(sc->vx_res);
13859191Skris	sc->bsh = rman_get_bushandle(sc->vx_res);
13959191Skris
14059191Skris	rid = 0;
14159191Skris	sc->vx_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
14259191Skris	    RF_SHAREABLE | RF_ACTIVE);
14359191Skris
14459191Skris	if (sc->vx_irq == NULL)
14559191Skris		goto bad;
14659191Skris
14759191Skris	if (bus_setup_intr(dev, sc->vx_irq, INTR_TYPE_NET,
14859191Skris	    vxintr, sc, &sc->vx_intrhand))
14959191Skris		goto bad;
150
151	if (vxattach(dev) == 0)
152		goto bad;
153
154	/* defect check for 3C590 */
155	if ((pci_read_config(dev, PCIR_DEVVENDOR, 4) >> 16) == 0x5900) {
156		GO_WINDOW(0);
157		if (vxbusyeeprom(sc))
158			goto bad;
159		CSR_WRITE_2(sc, VX_W0_EEPROM_COMMAND,
160		    EEPROM_CMD_RD | EEPROM_SOFTINFO2);
161		if (vxbusyeeprom(sc))
162			goto bad;
163		if (!(CSR_READ_2(sc, VX_W0_EEPROM_DATA) & NO_RX_OVN_ANOMALY))
164			printf("Warning! Defective early revision adapter!\n");
165	}
166	return (0);
167
168bad:
169	if (sc->vx_intrhand != NULL)
170		bus_teardown_intr(dev, sc->vx_irq, sc->vx_intrhand);
171	if (sc->vx_res != NULL)
172		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->vx_res);
173	if (sc->vx_irq != NULL)
174		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vx_irq);
175	return (ENXIO);
176}
177