summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstsp <stsp@openbsd.org>2015-02-23 09:40:47 +0000
committerstsp <stsp@openbsd.org>2015-02-23 09:40:47 +0000
commit2227d3e449a5edd5c76d976899a9e090ff6bfa92 (patch)
tree65e4880a228198119ff325f8dec97c1b0f0e7ab1
parentoops, cdfs must be built. spotted by todd, here is the correct diff (diff)
downloadwireguard-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.c57
-rw-r--r--sys/dev/pci/if_iwmvar.h5
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;