This patch fixes suspend/resume with an AX201 device for gnezdo@.
Tests on any iwm/iwx device would be apreciated.
Before testing this make sure to update your tree to -current which contains
a very recent fix for a double-free in the resume path of the iwx driver.
You won't have great results testing this patch without the double-free
fix in place.
diff 12fa68b3bbf986fd27f009964b1f0fba6d38edd5 /usr/src
blob - a993ab59bfac08dadef6661758fa45c1bc1110ac
file + sys/dev/pci/if_iwm.c
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -11445,13 +11445,19 @@ iwm_resume(struct iwm_softc *sc)
reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
- /* reconfigure the MSI-X mapping to get the correct IRQ for rfkill */
- iwm_conf_msix_hw(sc, 0);
+ if (!sc->sc_msix) {
+ /* Hardware bug workaround. */
+ reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
+ PCI_COMMAND_STATUS_REG);
+ if (reg & PCI_COMMAND_INTERRUPT_DISABLE)
+ reg &= ~PCI_COMMAND_INTERRUPT_DISABLE;
+ pci_conf_write(sc->sc_pct, sc->sc_pcitag,
+ PCI_COMMAND_STATUS_REG, reg);
+ }
- iwm_enable_rfkill_int(sc);
- iwm_check_rfkill(sc);
+ iwm_disable_interrupts(sc);
- return iwm_prepare_card_hw(sc);
+ return iwm_start_hw(sc);
}
int
blob - 735c23635ed7554664e3a9c84d823c3126286666
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -2328,7 +2328,6 @@ int
iwx_start_hw(struct iwx_softc *sc)
{
int err;
- int t = 0;
err = iwx_prepare_card_hw(sc);
if (err)
@@ -2369,16 +2368,6 @@ iwx_start_hw(struct iwx_softc *sc)
iwx_init_msix_hw(sc);
- while (t < 150000 && !iwx_set_hw_ready(sc)) {
- DELAY(200);
- t += 200;
- if (iwx_set_hw_ready(sc)) {
- break;
- }
- }
- if (t >= 150000)
- return ETIMEDOUT;
-
iwx_enable_rfkill_int(sc);
iwx_check_rfkill(sc);
@@ -9575,13 +9564,19 @@ iwx_resume(struct iwx_softc *sc)
reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
- /* reconfigure the MSI-X mapping to get the correct IRQ for rfkill */
- iwx_conf_msix_hw(sc, 0);
+ if (!sc->sc_msix) {
+ /* Hardware bug workaround. */
+ reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
+ PCI_COMMAND_STATUS_REG);
+ if (reg & PCI_COMMAND_INTERRUPT_DISABLE)
+ reg &= ~PCI_COMMAND_INTERRUPT_DISABLE;
+ pci_conf_write(sc->sc_pct, sc->sc_pcitag,
+ PCI_COMMAND_STATUS_REG, reg);
+ }
- iwx_enable_rfkill_int(sc);
- iwx_check_rfkill(sc);
+ iwx_disable_interrupts(sc);
- return iwx_prepare_card_hw(sc);
+ return iwx_start_hw(sc);
}
int