1/*	$NetBSD: if_fxp_pci.c,v 1.87 2022/09/24 18:12:42 thorpej Exp $	*/
2
3/*-
4 * Copyright (c) 1997, 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * PCI bus front-end for the Intel i82557 fast Ethernet controller
35 * driver.  Works with Intel Etherexpress Pro 10+, 100B, 100+ cards.
36 */
37
38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: if_fxp_pci.c,v 1.87 2022/09/24 18:12:42 thorpej Exp $");
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/mbuf.h>
44#include <sys/kernel.h>
45#include <sys/socket.h>
46#include <sys/ioctl.h>
47#include <sys/errno.h>
48#include <sys/device.h>
49
50#include <machine/endian.h>
51
52#include <net/if.h>
53#include <net/if_dl.h>
54#include <net/if_media.h>
55#include <net/if_ether.h>
56
57#include <sys/bus.h>
58#include <sys/intr.h>
59
60#include <dev/mii/miivar.h>
61
62#include <dev/ic/i82557reg.h>
63#include <dev/ic/i82557var.h>
64
65#include <dev/pci/pcivar.h>
66#include <dev/pci/pcireg.h>
67#include <dev/pci/pcidevs.h>
68
69struct fxp_pci_softc {
70	struct fxp_softc psc_fxp;
71
72	pci_chipset_tag_t psc_pc;	/* pci chipset tag */
73	pcireg_t psc_regs[0x20>>2];	/* saved PCI config regs (sparse) */
74	pcitag_t psc_tag;		/* pci register tag */
75
76	struct pci_conf_state psc_pciconf; /* standard PCI configuration regs */
77};
78
79static int	fxp_pci_match(device_t, cfdata_t, void *);
80static void	fxp_pci_attach(device_t, device_t, void *);
81static int	fxp_pci_detach(device_t, int);
82
83static int	fxp_pci_enable(struct fxp_softc *);
84
85static void fxp_pci_confreg_restore(struct fxp_pci_softc *psc);
86static bool fxp_pci_resume(device_t dv, const pmf_qual_t *);
87
88CFATTACH_DECL3_NEW(fxp_pci, sizeof(struct fxp_pci_softc),
89    fxp_pci_match, fxp_pci_attach, fxp_pci_detach, NULL, NULL,
90    null_childdetached, DVF_DETACH_SHUTDOWN);
91
92static const struct device_compatible_entry compat_data[] = {
93	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82552),
94	  .data = "Intel i82552 10/100 Network Connection" },
95
96	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_8255X),
97	  .data = "Intel i8255x Ethernet" },
98
99	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82559ER),
100	  .data = "Intel i82559ER Ethernet" },
101
102	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_IN_BUSINESS),
103	  .data = "Intel InBusiness Ethernet" },
104
105	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100),
106	  .data = "Intel PRO/100 Ethernet" },
107
108	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_0),
109	  .data = "Intel PRO/100 VE Network Controller" },
110
111	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_1),
112	  .data = "Intel PRO/100 VE Network Controller" },
113
114	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_2),
115	  .data = "Intel PRO/100 VE Network Controller with 82562ET/EZ PHY" },
116
117	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_3),
118	  .data = "Intel PRO/100 VE Network Controller with 82562ET/EZ (CNR) PHY" },
119
120	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_4),
121	  .data = "Intel PRO/100 VE (MOB) Network Controller" },
122
123	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_5),
124	  .data = "Intel PRO/100 VE (LOM) Network Controller" },
125
126	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_6),
127	  .data = "Intel PRO/100 VE Network Controller" },
128
129	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_7),
130	  .data = "Intel PRO/100 VE Network Controller" },
131
132	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_8),
133	  .data = "Intel PRO/100 VE Network Controller" },
134
135	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_9),
136	  .data = "Intel PRO/100 VE Network Controller" },
137
138	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_10),
139	  .data = "Intel PRO/100 VE Network Controller" },
140
141	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VE_11),
142	  .data = "Intel PRO/100 VE Network Controller" },
143
144	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_0),
145	  .data = "Intel PRO/100 VM Network Controller" },
146
147	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_1),
148	  .data = "Intel PRO/100 VM Network Controller" },
149
150	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_2),
151	  .data = "Intel PRO/100 VM Network Controller" },
152
153	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_3),
154	  .data = "Intel PRO/100 VM Network Controller with 82562EM/EX PHY" },
155
156	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_4),
157	  .data = "Intel PRO/100 VM Network Controller with 82562EM/EX (CNR) PHY" },
158
159	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_5),
160	  .data = "Intel PRO/100 VM (MOB) Network Controller" },
161
162	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_6),
163	  .data = "Intel PRO/100 VM Network Controller with 82562ET/EZ PHY" },
164
165	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_7),
166	  .data = "Intel PRO/100 VM Network Connection" },
167
168	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_8),
169	  .data = "Intel PRO/100 VM Network Connection" },
170
171	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_9),
172	  .data = "Intel PRO/100 VM Network Connection" },
173
174	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_10),
175	  .data = "Intel PRO/100 VM Network Connection" },
176
177	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_11),
178	  .data = "Intel PRO/100 VM Network Connection" },
179
180	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_12),
181	  .data = "Intel PRO/100 VM Network Connection" },
182
183	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_13),
184	  .data = "Intel PRO/100 VM Network Connection" },
185
186	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_14),
187	  .data = "Intel PRO/100 VM Network Connection" },
188
189	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_15),
190	  .data = "Intel PRO/100 VM Network Connection" },
191
192	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_VM_16),
193	  .data = "Intel PRO/100 VM Network Connection" },
194
195	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_100_M),
196	  .data = "Intel PRO/100 M Network Controller" },
197
198	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LAN),
199	  .data = "Intel i82562 Ethernet" },
200
201	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801E_LAN_1),
202	  .data = "Intel i82801E Ethernet" },
203
204	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801E_LAN_2),
205	  .data = "Intel i82801E Ethernet" },
206
207	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_LAN),
208	  .data = "Intel 82801EB/ER (ICH5) Network Controller" },
209
210	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LAN),
211	  .data = "Intel i82801FB LAN Controller" },
212
213	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LAN_2),
214	  .data = "Intel i82801FB LAN Controller" },
215
216	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801G_LAN),
217	  .data = "Intel 82801GB/GR (ICH7) Network Controller" },
218
219	{ .id = PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GB_LAN),
220	  .data = "Intel 82801GB 10/100 Network Controller" },
221
222	PCI_COMPAT_EOL
223};
224
225static int
226fxp_pci_match(device_t parent, cfdata_t match, void *aux)
227{
228	struct pci_attach_args *pa = aux;
229
230	return pci_compatible_match(pa, compat_data);
231}
232
233/*
234 * On resume : (XXX it is necessary with new pmf framework ?)
235 * Restore PCI configuration registers that may have been clobbered.
236 * This is necessary due to bugs on the Sony VAIO Z505-series on-board
237 * ethernet, after an APM suspend/resume, as well as after an ACPI
238 * D3->D0 transition.  We call this function from a power hook after
239 * APM resume events, as well as after the ACPI D3->D0 transition.
240 */
241static void
242fxp_pci_confreg_restore(struct fxp_pci_softc *psc)
243{
244	pcireg_t reg;
245
246#if 0
247	/*
248	 * Check to see if the command register is blank -- if so, then
249	 * we'll assume that all the clobberable-registers have been
250	 * clobbered.
251	 */
252
253	/*
254	 * In general, the above metric is accurate. Unfortunately,
255	 * it is inaccurate across a hibernation. Ideally APM/ACPI
256	 * code should take note of hibernation events and execute
257	 * a hibernation wakeup hook, but at present a hibernation wake
258	 * is indistinguishable from a suspend wake.
259	 */
260
261	if (((reg = pci_conf_read(psc->psc_pc, psc->psc_tag,
262	    PCI_COMMAND_STATUS_REG)) & 0xffff) != 0)
263		return;
264#else
265	reg = pci_conf_read(psc->psc_pc, psc->psc_tag, PCI_COMMAND_STATUS_REG);
266#endif
267
268	pci_conf_write(psc->psc_pc, psc->psc_tag, PCI_COMMAND_STATUS_REG,
269	    (reg & 0xffff0000) |
270	    (psc->psc_regs[PCI_COMMAND_STATUS_REG>>2] & 0xffff));
271	pci_conf_write(psc->psc_pc, psc->psc_tag, PCI_BHLC_REG,
272	    psc->psc_regs[PCI_BHLC_REG>>2]);
273	pci_conf_write(psc->psc_pc, psc->psc_tag, PCI_MAPREG_START+0x0,
274	    psc->psc_regs[(PCI_MAPREG_START+0x0)>>2]);
275	pci_conf_write(psc->psc_pc, psc->psc_tag, PCI_MAPREG_START+0x4,
276	    psc->psc_regs[(PCI_MAPREG_START+0x4)>>2]);
277	pci_conf_write(psc->psc_pc, psc->psc_tag, PCI_MAPREG_START+0x8,
278	    psc->psc_regs[(PCI_MAPREG_START+0x8)>>2]);
279}
280
281static bool
282fxp_pci_resume(device_t dv, const pmf_qual_t *qual)
283{
284	struct fxp_pci_softc *psc = device_private(dv);
285	fxp_pci_confreg_restore(psc);
286
287	return true;
288}
289
290static int
291fxp_pci_detach(device_t self, int flags)
292{
293	struct fxp_pci_softc *psc = device_private(self);
294	struct fxp_softc *sc = &psc->psc_fxp;
295	int error;
296
297	/* Finish off the attach. */
298	if ((error = fxp_detach(sc, flags)) != 0)
299		return error;
300
301	pmf_device_deregister(self);
302
303	pci_intr_disestablish(psc->psc_pc, sc->sc_ih);
304
305	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size);
306
307	return 0;
308}
309
310static void
311fxp_pci_attach(device_t parent, device_t self, void *aux)
312{
313	struct fxp_pci_softc *psc = device_private(self);
314	struct fxp_softc *sc = &psc->psc_fxp;
315	const struct pci_attach_args *pa = aux;
316	pci_chipset_tag_t pc = pa->pa_pc;
317	pci_intr_handle_t ih;
318	const struct device_compatible_entry *dce;
319	const char *chipname = NULL;
320	const char *intrstr = NULL;
321	bus_space_tag_t iot, memt;
322	bus_space_handle_t ioh, memh;
323	int ioh_valid, memh_valid;
324	bus_addr_t addr;
325	pcireg_t csr;
326	int flags;
327	int error;
328	char intrbuf[PCI_INTRSTR_LEN];
329
330	sc->sc_dev = self;
331
332	/*
333	 * Map control/status registers.
334	 */
335	ioh_valid = (pci_mapreg_map(pa, FXP_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0,
336	    &iot, &ioh, NULL, NULL) == 0);
337
338	/*
339	 * Version 2.1 of the PCI spec, page 196, "Address Maps":
340	 *
341	 *	Prefetchable
342	 *
343	 *	Set to one if there are no side effects on reads, the
344	 *	device returns all bytes regardless of the byte enables,
345	 *	and host bridges can merge processor writes into this
346	 *	range without causing errors.  Bit must be set to zero
347	 *	otherwise.
348	 *
349	 * The 82557 incorrectly sets the "prefetchable" bit, resulting
350	 * in errors on systems which will do merged reads and writes.
351	 * These errors manifest themselves as all-bits-set when reading
352	 * from the EEPROM or other < 4 byte registers.
353	 *
354	 * We must work around this problem by always forcing the mapping
355	 * for memory space to be uncacheable.  On systems which cannot
356	 * create an uncacheable mapping (because the firmware mapped it
357	 * into only cacheable/prefetchable space due to the "prefetchable"
358	 * bit), we can fall back onto i/o mapped access.
359	 */
360	memh_valid = 0;
361	memt = pa->pa_memt;
362	if (((pa->pa_flags & PCI_FLAGS_MEM_OKAY) != 0) &&
363	    pci_mapreg_info(pa->pa_pc, pa->pa_tag, FXP_PCI_MMBA,
364	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT,
365	    &addr, &sc->sc_size, &flags) == 0) {
366		flags &= ~BUS_SPACE_MAP_PREFETCHABLE;
367		if (bus_space_map(memt, addr, sc->sc_size, flags, &memh) == 0)
368			memh_valid = 1;
369	}
370
371	if (memh_valid) {
372		sc->sc_st = memt;
373		sc->sc_sh = memh;
374		/*
375		 * Enable address decoding for memory range in case BIOS or
376		 * UEFI didn't set it.
377		 */
378		csr = pci_conf_read(pa->pa_pc, pa->pa_tag,
379		    PCI_COMMAND_STATUS_REG);
380		csr |= PCI_COMMAND_MEM_ENABLE;
381		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
382		    csr);
383	} else if (ioh_valid) {
384		sc->sc_st = iot;
385		sc->sc_sh = ioh;
386	} else {
387		aprint_error(": unable to map device registers\n");
388		return;
389	}
390
391	sc->sc_dmat = pa->pa_dmat;
392
393	dce = pci_compatible_lookup(pa, compat_data);
394	KASSERT(dce != NULL);
395
396	sc->sc_rev = PCI_REVISION(pa->pa_class);
397
398	switch (PCI_PRODUCT(dce->id)) {
399	case PCI_PRODUCT_INTEL_8255X:
400	case PCI_PRODUCT_INTEL_IN_BUSINESS:
401
402		if (sc->sc_rev >= FXP_REV_82558_A4) {
403			chipname = "i82558 Ethernet";
404			sc->sc_flags |= FXPF_FC|FXPF_EXT_TXCB;
405			/*
406			 * Enable the MWI command for memory writes.
407			 */
408			if (pa->pa_flags & PCI_FLAGS_MWI_OKAY)
409				sc->sc_flags |= FXPF_MWI;
410		}
411		if (sc->sc_rev >= FXP_REV_82559_A0) {
412			chipname = "i82559 Ethernet";
413			sc->sc_flags |= FXPF_82559_RXCSUM;
414		}
415		if (sc->sc_rev >= FXP_REV_82559S_A)
416			chipname = "i82559S Ethernet";
417		if (sc->sc_rev >= FXP_REV_82550) {
418			chipname = "i82550 Ethernet";
419			sc->sc_flags &= ~FXPF_82559_RXCSUM;
420			sc->sc_flags |= FXPF_EXT_RFA;
421		}
422		if (sc->sc_rev >= FXP_REV_82551_E)
423			chipname = "i82551 Ethernet";
424
425		/*
426		 * Mark all i82559 and i82550 revisions as having
427		 * the "resume bug".  See i82557.c for details.
428		 */
429		if (sc->sc_rev >= FXP_REV_82559_A0)
430			sc->sc_flags |= FXPF_HAS_RESUME_BUG;
431
432		break;
433
434	case PCI_PRODUCT_INTEL_82559ER:
435		sc->sc_flags |= FXPF_FC|FXPF_EXT_TXCB;
436
437		/*
438		 * i82559ER/82551ER don't support RX hardware checksumming
439		 * even though it has a newer revision number than 82559_A0.
440		 */
441
442		/* All i82559 have the "resume bug". */
443		sc->sc_flags |= FXPF_HAS_RESUME_BUG;
444
445		/* Enable the MWI command for memory writes. */
446		if (pa->pa_flags & PCI_FLAGS_MWI_OKAY)
447			sc->sc_flags |= FXPF_MWI;
448
449		if (sc->sc_rev >= FXP_REV_82551_E)
450			chipname = "Intel i82551ER Ethernet";
451
452		break;
453
454	case PCI_PRODUCT_INTEL_82801BA_LAN:
455	case PCI_PRODUCT_INTEL_PRO_100_VE_0:
456	case PCI_PRODUCT_INTEL_PRO_100_VE_1:
457	case PCI_PRODUCT_INTEL_PRO_100_VM_0:
458	case PCI_PRODUCT_INTEL_PRO_100_VM_1:
459	case PCI_PRODUCT_INTEL_82562EH_HPNA_0:
460	case PCI_PRODUCT_INTEL_82562EH_HPNA_1:
461	case PCI_PRODUCT_INTEL_82562EH_HPNA_2:
462	case PCI_PRODUCT_INTEL_PRO_100_VM_2:
463		/*
464		 * The ICH-2 and ICH-3 have the "resume bug".
465		 */
466		sc->sc_flags |= FXPF_HAS_RESUME_BUG;
467		/* FALLTHROUGH */
468
469	default:
470		if (sc->sc_rev >= FXP_REV_82558_A4)
471			sc->sc_flags |= FXPF_FC|FXPF_EXT_TXCB;
472		if (sc->sc_rev >= FXP_REV_82559_A0)
473			sc->sc_flags |= FXPF_82559_RXCSUM;
474
475		break;
476	}
477
478	pci_aprint_devinfo_fancy(pa, "Ethernet controller",
479		(chipname != NULL ? chipname : dce->data), 1);
480
481	/* Make sure bus-mastering is enabled. */
482	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
483	    pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
484	    PCI_COMMAND_MASTER_ENABLE);
485
486  	/*
487	 * Under some circumstances (such as APM suspend/resume
488	 * cycles, and across ACPI power state changes), the
489	 * i82257-family can lose the contents of critical PCI
490	 * configuration registers, causing the card to be
491	 * non-responsive and useless.  This occurs on the Sony VAIO
492	 * Z505-series, among others.  Preserve them here so they can
493	 * be later restored (by fxp_pci_confreg_restore()).
494	 */
495	psc->psc_pc = pc;
496	psc->psc_tag = pa->pa_tag;
497	psc->psc_regs[PCI_COMMAND_STATUS_REG>>2] =
498	    pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
499	psc->psc_regs[PCI_BHLC_REG>>2] =
500	    pci_conf_read(pc, pa->pa_tag, PCI_BHLC_REG);
501	psc->psc_regs[(PCI_MAPREG_START+0x0)>>2] =
502	    pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START+0x0);
503	psc->psc_regs[(PCI_MAPREG_START+0x4)>>2] =
504	    pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START+0x4);
505	psc->psc_regs[(PCI_MAPREG_START+0x8)>>2] =
506	    pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START+0x8);
507
508	/* power up chip */
509	switch ((error = pci_activate(pa->pa_pc, pa->pa_tag, self,
510	    pci_activate_null))) {
511	case EOPNOTSUPP:
512		break;
513	case 0:
514		sc->sc_enable = fxp_pci_enable;
515		sc->sc_disable = NULL;
516		break;
517	default:
518		aprint_error_dev(self, "cannot activate %d\n", error);
519		return;
520	}
521
522	/* Restore PCI configuration registers. */
523	fxp_pci_confreg_restore(psc);
524
525	sc->sc_enabled = 1;
526
527	/*
528	 * Map and establish our interrupt.
529	 */
530	if (pci_intr_map(pa, &ih)) {
531		aprint_error_dev(self, "couldn't map interrupt\n");
532		return;
533	}
534	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
535	sc->sc_ih = pci_intr_establish_xname(pc, ih, IPL_NET, fxp_intr, sc,
536	    device_xname(self));
537	if (sc->sc_ih == NULL) {
538		aprint_error_dev(self, "couldn't establish interrupt");
539		if (intrstr != NULL)
540			aprint_error(" at %s", intrstr);
541		aprint_error("\n");
542		return;
543	}
544	aprint_normal_dev(self, "interrupting at %s\n", intrstr);
545
546	/* Finish off the attach. */
547	fxp_attach(sc);
548	if (sc->sc_disable != NULL)
549		fxp_disable(sc);
550
551	/* Add a suspend hook to restore PCI config state */
552	if (pmf_device_register(self, NULL, fxp_pci_resume))
553		pmf_class_network_register(self, &sc->sc_ethercom.ec_if);
554	else
555		aprint_error_dev(self, "couldn't establish power handler\n");
556}
557
558static int
559fxp_pci_enable(struct fxp_softc *sc)
560{
561	struct fxp_pci_softc *psc = (void *) sc;
562
563#if 0
564	printf("%s: going to power state D0\n", device_xname(self));
565#endif
566
567	/* Now restore the configuration registers. */
568	fxp_pci_confreg_restore(psc);
569
570	return 0;
571}
572