diff options
author | 2015-02-23 09:40:47 +0000 | |
---|---|---|
committer | 2015-02-23 09:40:47 +0000 | |
commit | 2227d3e449a5edd5c76d976899a9e090ff6bfa92 (patch) | |
tree | 65e4880a228198119ff325f8dec97c1b0f0e7ab1 | |
parent | oops, cdfs must be built. spotted by todd, here is the correct diff (diff) | |
download | wireguard-openbsd-2227d3e449a5edd5c76d976899a9e090ff6bfa92.tar.xz wireguard-openbsd-2227d3e449a5edd5c76d976899a9e090ff6bfa92.zip |
Make iwm(4) re-read the firmware image from disk on if down/up like other
drivers do. While here remove unused fields from struct iwm_fw_info.
test and ok brad@ phessler@
-rw-r--r-- | sys/dev/pci/if_iwm.c | 57 | ||||
-rw-r--r-- | sys/dev/pci/if_iwmvar.h | 5 |
2 files changed, 32 insertions, 30 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index f034d7bc5b9..12d72e36026 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.21 2015/02/21 09:53:49 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.22 2015/02/23 09:40:47 stsp Exp $ */ /* * Copyright (c) 2014 genua mbh <info@genua.de> @@ -210,7 +210,8 @@ int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t); int iwm_firmware_store_section(struct iwm_softc *, enum iwm_ucode_type, uint8_t *, size_t); int iwm_set_default_calib(struct iwm_softc *, const void *); -int iwm_read_firmware(struct iwm_softc *); +void iwm_fw_info_free(struct iwm_fw_info *); +int iwm_read_firmware(struct iwm_softc *, enum iwm_ucode_type); uint32_t iwm_read_prph(struct iwm_softc *, uint32_t); void iwm_write_prph(struct iwm_softc *, uint32_t, uint32_t); int iwm_read_mem(struct iwm_softc *, uint32_t, void *, int); @@ -472,10 +473,6 @@ iwm_firmware_store_section(struct iwm_softc *sc, fwone->fws_data = data + sizeof(uint32_t); fwone->fws_len = dlen - sizeof(uint32_t); - /* for freeing the buffer during driver unload */ - fwone->fws_alloc = data; - fwone->fws_allocsize = dlen; - fws->fw_count++; fws->fw_totlen += fwone->fws_len; @@ -508,28 +505,38 @@ iwm_set_default_calib(struct iwm_softc *sc, const void *data) return 0; } +void +iwm_fw_info_free(struct iwm_fw_info *fw) +{ + free(fw->fw_rawdata, M_DEVBUF, fw->fw_rawsize); + fw->fw_rawdata = NULL; + fw->fw_rawsize = 0; + /* don't touch fw->fw_status */ + memset(fw->fw_sects, 0, sizeof(fw->fw_sects)); +} + int -iwm_read_firmware(struct iwm_softc *sc) +iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) { struct iwm_fw_info *fw = &sc->sc_fw; struct iwm_tlv_ucode_header *uhdr; struct iwm_ucode_tlv tlv; enum iwm_ucode_tlv_type tlv_type; uint8_t *data; - int error, status; + int error; size_t len; - if (fw->fw_status == IWM_FW_STATUS_NONE) { - fw->fw_status = IWM_FW_STATUS_INPROGRESS; - } else { - while (fw->fw_status == IWM_FW_STATUS_INPROGRESS) - tsleep(&sc->sc_fw, 0, "iwmfwp", 0); - } - status = fw->fw_status; - - if (status == IWM_FW_STATUS_DONE) + if (fw->fw_status == IWM_FW_STATUS_DONE && + ucode_type != IWM_UCODE_TYPE_INIT) return 0; + while (fw->fw_status == IWM_FW_STATUS_INPROGRESS) + tsleep(&sc->sc_fw, 0, "iwmfwp", 0); + fw->fw_status = IWM_FW_STATUS_INPROGRESS; + + if (fw->fw_rawdata != NULL) + iwm_fw_info_free(fw); + /* * Load firmware into driver memory. * fw_rawdata and fw_rawsize will be set. @@ -687,8 +694,8 @@ iwm_read_firmware(struct iwm_softc *sc) parse_out: if (error) { - printf("%s: firmware parse error, " - "section type %d\n", DEVNAME(sc), tlv_type); + printf("%s: firmware parse error %d, " + "section type %d\n", DEVNAME(sc), error, tlv_type); } if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) { @@ -697,16 +704,14 @@ iwm_read_firmware(struct iwm_softc *sc) } out: - if (error) + if (error) { fw->fw_status = IWM_FW_STATUS_NONE; - else + if (fw->fw_rawdata != NULL) + iwm_fw_info_free(fw); + } else fw->fw_status = IWM_FW_STATUS_DONE; wakeup(&sc->sc_fw); - if (error) { - free(fw->fw_rawdata, M_DEVBUF, fw->fw_rawsize); - fw->fw_rawdata = NULL; - } return error; } @@ -2778,7 +2783,7 @@ iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc, enum iwm_ucode_type old_type = sc->sc_uc_current; int error; - if ((error = iwm_read_firmware(sc)) != 0) + if ((error = iwm_read_firmware(sc, ucode_type)) != 0) return error; sc->sc_uc_current = ucode_type; diff --git a/sys/dev/pci/if_iwmvar.h b/sys/dev/pci/if_iwmvar.h index dfa2f74348d..a96d291b96b 100644 --- a/sys/dev/pci/if_iwmvar.h +++ b/sys/dev/pci/if_iwmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwmvar.h,v 1.3 2015/02/07 07:10:44 phessler Exp $ */ +/* $OpenBSD: if_iwmvar.h,v 1.4 2015/02/23 09:40:47 stsp Exp $ */ /* * Copyright (c) 2014 genua mbh <info@genua.de> @@ -169,9 +169,6 @@ struct iwm_fw_info { void *fws_data; uint32_t fws_len; uint32_t fws_devoff; - - void *fws_alloc; - size_t fws_allocsize; } fw_sect[IWM_UCODE_SECT_MAX]; size_t fw_totlen; int fw_count; |