Date: Sun, 11 Mar 2018 22:49:46 +0000 (UTC) From: Eitan Adler <eadler@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r330784 - stable/11/sys/dev/iwm Message-ID: <201803112249.w2BMnkwJ044355@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: eadler Date: Sun Mar 11 22:49:46 2018 New Revision: 330784 URL: https://svnweb.freebsd.org/changeset/base/330784 Log: Revert r324434 Some users are reporting that it is causing issues for their hardware. In the interest of not breaking stable, revert while we investigate. Modified: stable/11/sys/dev/iwm/if_iwm.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/iwm/if_iwm.c ============================================================================== --- stable/11/sys/dev/iwm/if_iwm.c Sun Mar 11 20:13:15 2018 (r330783) +++ stable/11/sys/dev/iwm/if_iwm.c Sun Mar 11 22:49:46 2018 (r330784) @@ -547,14 +547,12 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode { struct iwm_fw_info *fw = &sc->sc_fw; const struct iwm_tlv_ucode_header *uhdr; - const struct iwm_ucode_tlv *tlv; + struct iwm_ucode_tlv tlv; struct iwm_ucode_capabilities *capa = &sc->ucode_capa; enum iwm_ucode_tlv_type tlv_type; const struct firmware *fwp; const uint8_t *data; - uint32_t tlv_len; uint32_t usniffer_img; - const uint8_t *tlv_data; uint32_t paging_mem_size; int num_of_cpus; int error = 0; @@ -607,21 +605,25 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode goto out; } - snprintf(sc->sc_fwver, sizeof(sc->sc_fwver), "%u.%u (API ver %u)", + snprintf(sc->sc_fwver, sizeof(sc->sc_fwver), "%d.%d (API ver %d)", IWM_UCODE_MAJOR(le32toh(uhdr->ver)), IWM_UCODE_MINOR(le32toh(uhdr->ver)), IWM_UCODE_API(le32toh(uhdr->ver))); data = uhdr->data; len = fw->fw_fp->datasize - sizeof(*uhdr); - while (len >= sizeof(*tlv)) { - len -= sizeof(*tlv); - tlv = (const void *)data; + while (len >= sizeof(tlv)) { + size_t tlv_len; + const void *tlv_data; - tlv_len = le32toh(tlv->length); - tlv_type = le32toh(tlv->type); - tlv_data = tlv->data; + memcpy(&tlv, data, sizeof(tlv)); + tlv_len = le32toh(tlv.length); + tlv_type = le32toh(tlv.type); + len -= sizeof(tlv); + data += sizeof(tlv); + tlv_data = data; + if (len < tlv_len) { device_printf(sc->sc_dev, "firmware too short: %zu bytes\n", @@ -629,21 +631,19 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode error = EINVAL; goto parse_out; } - len -= roundup2(tlv_len, 4); - data += sizeof(tlv) + roundup2(tlv_len, 4); switch ((int)tlv_type) { case IWM_UCODE_TLV_PROBE_MAX_LEN: - if (tlv_len != sizeof(uint32_t)) { + if (tlv_len < sizeof(uint32_t)) { device_printf(sc->sc_dev, - "%s: PROBE_MAX_LEN (%d) != sizeof(uint32_t)\n", + "%s: PROBE_MAX_LEN (%d) < sizeof(uint32_t)\n", __func__, (int) tlv_len); error = EINVAL; goto parse_out; } capa->max_probe_length = - le32_to_cpup((const uint32_t *)tlv_data); + le32toh(*(const uint32_t *)tlv_data); /* limit it to something sensible */ if (capa->max_probe_length > IWM_SCAN_OFFLOAD_PROBE_REQ_SIZE) { @@ -674,14 +674,6 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode error = EINVAL; goto parse_out; } - if (tlv_len % sizeof(uint32_t)) { - device_printf(sc->sc_dev, - "%s: IWM_UCODE_TLV_FLAGS: tlv_len (%d) %% sizeof(uint32_t)\n", - __func__, - (int) tlv_len); - error = EINVAL; - goto parse_out; - } /* * Apparently there can be many flags, but Linux driver * parses only the first one, and so do we. @@ -693,7 +685,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode * 2) TLV_FLAGS contains TLV_FLAGS_PAN * ==> this resets TLV_PAN to itself... hnnnk */ - capa->flags = le32_to_cpup((const uint32_t *)tlv_data); + capa->flags = le32toh(*(const uint32_t *)tlv_data); break; case IWM_UCODE_TLV_CSCHEME: if ((error = iwm_store_cscheme(sc, @@ -714,7 +706,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode error = EINVAL; goto parse_out; } - num_of_cpus = le32_to_cpup((const uint32_t *)tlv_data); + num_of_cpus = le32toh(*(const uint32_t *)tlv_data); if (num_of_cpus == 2) { fw->fw_sects[IWM_UCODE_REGULAR].is_dual_cpus = TRUE; @@ -788,7 +780,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode goto parse_out; } sc->sc_fw.phy_config = - le32_to_cpup((const uint32_t *)tlv_data); + le32toh(*(const uint32_t *)tlv_data); sc->sc_fw.valid_tx_ant = (sc->sc_fw.phy_config & IWM_FW_PHY_CFG_TX_CHAIN) >> IWM_FW_PHY_CFG_TX_CHAIN_POS; @@ -839,7 +831,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode error = EINVAL; goto parse_out; } - paging_mem_size = le32_to_cpup((const uint32_t *)tlv_data); + paging_mem_size = le32toh(*(const uint32_t *)tlv_data); IWM_DPRINTF(sc, IWM_DEBUG_FIRMWARE_TLV, "%s: Paging: paging enabled (size = %u bytes)\n", @@ -872,7 +864,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode goto parse_out; } capa->n_scan_channels = - le32_to_cpup((const uint32_t *)tlv_data); + le32toh(*(const uint32_t *)tlv_data); break; case IWM_UCODE_TLV_FW_VERSION: @@ -897,6 +889,9 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode error = EINVAL; goto parse_out; } + + len -= roundup(tlv_len, 4); + data += roundup(tlv_len, 4); } KASSERT(error == 0, ("unhandled error"));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803112249.w2BMnkwJ044355>