summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2005-01-18 18:08:16 +0000
committersam <sam@FreeBSD.org>2005-01-18 18:08:16 +0000
commit176d72c8fe14bee7a50f29cd8391cde1dceae913 (patch)
treed58fb90a21f79a0c90f1a9c87897dd755bc66320
parent13da49151e1589c3d028c54ca05daec1fdd6f69e (diff)
downloadFreeBSD-src-176d72c8fe14bee7a50f29cd8391cde1dceae913.zip
FreeBSD-src-176d72c8fe14bee7a50f29cd8391cde1dceae913.tar.gz
o disable pci retry timeout to avoid problems when operating in C3 state
(fix imported from madwifi by Takanori Watanabe) o eliminate save/restore of pci registers handled by the system o eliminate duplicate zero of the softc (noted by njl) o consolidate common code MFC after: 1 week
-rw-r--r--sys/dev/ath/if_ath_pci.c61
1 files changed, 32 insertions, 29 deletions
diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c
index 6665c61..82f0376 100644
--- a/sys/dev/ath/if_ath_pci.c
+++ b/sys/dev/ath/if_ath_pci.c
@@ -77,12 +77,10 @@ struct ath_pci_softc {
struct resource *sc_sr; /* memory resource */
struct resource *sc_irq; /* irq resource */
void *sc_ih; /* interrupt handler */
- u_int8_t sc_saved_intline;
- u_int8_t sc_saved_cachelinesz;
- u_int8_t sc_saved_lattimer;
};
#define BS_BAR 0x10
+#define PCIR_RETRY_TIMEOUT 0x41
static int
ath_pci_probe(device_t dev)
@@ -97,33 +95,49 @@ ath_pci_probe(device_t dev)
return ENXIO;
}
-static int
-ath_pci_attach(device_t dev)
+static u_int32_t
+ath_pci_setup(device_t dev)
{
- struct ath_pci_softc *psc = device_get_softc(dev);
- struct ath_softc *sc = &psc->sc_sc;
u_int32_t cmd;
- int error = ENXIO;
- int rid;
- bzero(psc, sizeof (*psc));
- sc->sc_dev = dev;
-
+ /*
+ * Enable memory mapping and bus mastering.
+ */
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
pci_write_config(dev, PCIR_COMMAND, cmd, 4);
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
-
if ((cmd & PCIM_CMD_MEMEN) == 0) {
device_printf(dev, "failed to enable memory mapping\n");
- goto bad;
+ return 0;
}
-
if ((cmd & PCIM_CMD_BUSMASTEREN) == 0) {
device_printf(dev, "failed to enable bus mastering\n");
- goto bad;
+ return 0;
}
+ /*
+ * Disable retry timeout to keep PCI Tx retries from
+ * interfering with C3 CPU state.
+ */
+ pci_write_config(dev, PCIR_RETRY_TIMEOUT, 0, 1);
+
+ return 1;
+}
+
+static int
+ath_pci_attach(device_t dev)
+{
+ struct ath_pci_softc *psc = device_get_softc(dev);
+ struct ath_softc *sc = &psc->sc_sc;
+ int error = ENXIO;
+ int rid;
+
+ sc->sc_dev = dev;
+
+ if (!ath_pci_setup(dev))
+ goto bad;
+
/*
* Setup memory-mapping of PCI registers.
*/
@@ -235,10 +249,6 @@ ath_pci_suspend(device_t dev)
ath_suspend(&psc->sc_sc);
- psc->sc_saved_intline = pci_read_config(dev, PCIR_INTLINE, 1);
- psc->sc_saved_cachelinesz= pci_read_config(dev, PCIR_CACHELNSZ, 1);
- psc->sc_saved_lattimer = pci_read_config(dev, PCIR_LATTIMER, 1);
-
return (0);
}
@@ -246,16 +256,9 @@ static int
ath_pci_resume(device_t dev)
{
struct ath_pci_softc *psc = device_get_softc(dev);
- u_int16_t cmd;
- pci_write_config(dev, PCIR_INTLINE, psc->sc_saved_intline, 1);
- pci_write_config(dev, PCIR_CACHELNSZ, psc->sc_saved_cachelinesz, 1);
- pci_write_config(dev, PCIR_LATTIMER, psc->sc_saved_lattimer, 1);
-
- /* re-enable mem-map and busmastering */
- cmd = pci_read_config(dev, PCIR_COMMAND, 2);
- cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
- pci_write_config(dev, PCIR_COMMAND, cmd, 2);
+ if (!ath_pci_setup(dev))
+ return ENXIO;
ath_resume(&psc->sc_sc);
OpenPOWER on IntegriCloud