Skip site navigation (1)Skip section navigation (2)
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>