From c3810af54c1e11e404886c0ce40e59a0bb32674d Mon Sep 17 00:00:00 2001 From: stsp Date: Wed, 8 Sep 2021 13:06:23 +0000 Subject: [PATCH] Make iwm(4) and iwx(4) raise IPL to splnet() while loading firmware. ok mpi@ --- sys/dev/pci/if_iwm.c | 24 +++++++++++++++++++----- sys/dev/pci/if_iwx.c | 22 ++++++++++++++++------ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index d105180e390..58d7c6dcc1f 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwm.c,v 1.366 2021/09/08 11:35:08 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.367 2021/09/08 13:06:23 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -4147,6 +4147,8 @@ iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) { int err; + splassert(IPL_NET); + sc->sc_uc.uc_intr = 0; sc->sc_uc.uc_ok = 0; @@ -4292,7 +4294,7 @@ int iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm) { const int wait_flags = (IWM_INIT_COMPLETE | IWM_CALIB_COMPLETE); - int err; + int err, s; if ((sc->sc_flags & IWM_FLAG_RFKILL) && !justnvm) { printf("%s: radio is disabled by hardware switch\n", @@ -4300,10 +4302,12 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm) return EPERM; } + s = splnet(); sc->sc_init_complete = 0; err = iwm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_INIT); if (err) { printf("%s: failed to load init firmware\n", DEVNAME(sc)); + splx(s); return err; } @@ -4312,6 +4316,7 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm) if (err) { printf("%s: could not init bt coex (error %d)\n", DEVNAME(sc), err); + splx(s); return err; } } @@ -4320,6 +4325,7 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm) err = iwm_nvm_init(sc); if (err) { printf("%s: failed to read nvm\n", DEVNAME(sc)); + splx(s); return err; } @@ -4327,25 +4333,32 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm) IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr, sc->sc_nvm.hw_addr); + splx(s); return 0; } err = iwm_sf_config(sc, IWM_SF_INIT_OFF); - if (err) + if (err) { + splx(s); return err; + } /* Send TX valid antennas before triggering calibrations */ err = iwm_send_tx_ant_cfg(sc, iwm_fw_valid_tx_ant(sc)); - if (err) + if (err) { + splx(s); return err; + } /* * Send phy configurations command to init uCode * to start the 16.0 uCode init image internal calibrations. */ err = iwm_send_phy_cfg_cmd(sc); - if (err) + if (err) { + splx(s); return err; + } /* * Nothing to do but wait for the init complete and phy DB @@ -4358,6 +4371,7 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm) break; } + splx(s); return err; } diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c index 24fb611ab1d..1ce02ab5377 100644 --- a/sys/dev/pci/if_iwx.c +++ b/sys/dev/pci/if_iwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwx.c,v 1.104 2021/09/08 11:35:08 stsp Exp $ */ +/* $OpenBSD: if_iwx.c,v 1.105 2021/09/08 13:06:23 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -3350,6 +3350,8 @@ iwx_load_firmware(struct iwx_softc *sc) struct iwx_fw_sects *fws; int err; + splassert(IPL_NET); + sc->sc_uc.uc_intr = 0; sc->sc_uc.uc_ok = 0; @@ -3465,7 +3467,7 @@ iwx_run_init_mvm_ucode(struct iwx_softc *sc, int readnvm) struct iwx_init_extended_cfg_cmd init_cfg = { .init_flags = htole32(IWX_INIT_NVM), }; - int err; + int err, s; if ((sc->sc_flags & IWX_FLAG_RFKILL) && !readnvm) { printf("%s: radio is disabled by hardware switch\n", @@ -3473,10 +3475,12 @@ iwx_run_init_mvm_ucode(struct iwx_softc *sc, int readnvm) return EPERM; } + s = splnet(); sc->sc_init_complete = 0; err = iwx_load_ucode_wait_alive(sc); if (err) { printf("%s: failed to load init firmware\n", DEVNAME(sc)); + splx(s); return err; } @@ -3486,22 +3490,28 @@ iwx_run_init_mvm_ucode(struct iwx_softc *sc, int readnvm) */ err = iwx_send_cmd_pdu(sc, IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_INIT_EXTENDED_CFG_CMD), 0, sizeof(init_cfg), &init_cfg); - if (err) + if (err) { + splx(s); return err; + } err = iwx_send_cmd_pdu(sc, IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, IWX_NVM_ACCESS_COMPLETE), 0, sizeof(nvm_complete), &nvm_complete); - if (err) + if (err) { + splx(s); return err; + } /* Wait for the init complete notification from the firmware. */ while ((sc->sc_init_complete & wait_flags) != wait_flags) { err = tsleep_nsec(&sc->sc_init_complete, 0, "iwxinit", SEC_TO_NSEC(2)); - if (err) + if (err) { + splx(s); return err; + } } - + splx(s); if (readnvm) { err = iwx_nvm_get(sc); if (err) { -- 2.20.1