Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3aed8837 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge tag 'iwlwifi-for-kalle-2019-10-09' of...

Merge tag 'iwlwifi-for-kalle-2019-10-09' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes

First batch of fixes intended for v5.4

* fix for an ACPI table parsing bug;
* a fix for a NULL pointer dereference in the cfg with specific
  devices;
* fix the rb_allocator;
* prevent multiple phy configuration with new devices;
* fix a race-condition in the rx queue;
* prevent a couple of memory leaks;
* fix initialization of 3168 devices (the infamous BAD_COMMAND bug);
* fix recognition of some newer systems with integrated MAC;
parents 98d22b01 aa0cc7dd
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -162,12 +162,13 @@ int iwl_acpi_get_mcc(struct device *dev, char *mcc)

	wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_WRDD_WIFI_DATA_SIZE,
					 &tbl_rev);
	if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
	if (IS_ERR(wifi_pkg)) {
		ret = PTR_ERR(wifi_pkg);
		goto out_free;
	}

	if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
	if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER ||
	    tbl_rev != 0) {
		ret = -EINVAL;
		goto out_free;
	}
@@ -224,12 +225,13 @@ int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk)

	wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_ECKV_WIFI_DATA_SIZE,
					 &tbl_rev);
	if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
	if (IS_ERR(wifi_pkg)) {
		ret = PTR_ERR(wifi_pkg);
		goto out_free;
	}

	if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
	if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER ||
	    tbl_rev != 0) {
		ret = -EINVAL;
		goto out_free;
	}
+1 −0
Original line number Diff line number Diff line
@@ -646,6 +646,7 @@ static struct scatterlist *alloc_sgtable(int size)
				if (new_page)
					__free_page(new_page);
			}
			kfree(table);
			return NULL;
		}
		alloc_size = min_t(int, size, PAGE_SIZE);
+6 −6
Original line number Diff line number Diff line
@@ -112,38 +112,38 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf);
 */
static inline u32 iwl_umac_prph(struct iwl_trans *trans, u32 ofs)
{
	return ofs + trans->cfg->trans.umac_prph_offset;
	return ofs + trans->trans_cfg->umac_prph_offset;
}

static inline u32 iwl_read_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs)
{
	return iwl_read_prph_no_grab(trans, ofs +
				     trans->cfg->trans.umac_prph_offset);
				     trans->trans_cfg->umac_prph_offset);
}

static inline u32 iwl_read_umac_prph(struct iwl_trans *trans, u32 ofs)
{
	return iwl_read_prph(trans, ofs + trans->cfg->trans.umac_prph_offset);
	return iwl_read_prph(trans, ofs + trans->trans_cfg->umac_prph_offset);
}

static inline void iwl_write_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs,
					       u32 val)
{
	iwl_write_prph_no_grab(trans,  ofs + trans->cfg->trans.umac_prph_offset,
	iwl_write_prph_no_grab(trans,  ofs + trans->trans_cfg->umac_prph_offset,
			       val);
}

static inline void iwl_write_umac_prph(struct iwl_trans *trans, u32 ofs,
				       u32 val)
{
	iwl_write_prph(trans,  ofs + trans->cfg->trans.umac_prph_offset, val);
	iwl_write_prph(trans,  ofs + trans->trans_cfg->umac_prph_offset, val);
}

static inline int iwl_poll_umac_prph_bit(struct iwl_trans *trans, u32 addr,
					 u32 bits, u32 mask, int timeout)
{
	return iwl_poll_prph_bit(trans, addr +
				 trans->cfg->trans.umac_prph_offset,
				 trans->trans_cfg->umac_prph_offset,
				 bits, mask, timeout);
}

+30 −13
Original line number Diff line number Diff line
@@ -420,6 +420,9 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
	};
	int ret;

	if (mvm->trans->cfg->tx_with_siso_diversity)
		init_cfg.init_flags |= cpu_to_le32(BIT(IWL_INIT_PHY));

	lockdep_assert_held(&mvm->mutex);

	mvm->rfkill_safe_init_done = false;
@@ -694,12 +697,13 @@ static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)

	wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
					 ACPI_WRDS_WIFI_DATA_SIZE, &tbl_rev);
	if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
	if (IS_ERR(wifi_pkg)) {
		ret = PTR_ERR(wifi_pkg);
		goto out_free;
	}

	if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
	if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER ||
	    tbl_rev != 0) {
		ret = -EINVAL;
		goto out_free;
	}
@@ -731,13 +735,14 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm)

	wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
					 ACPI_EWRD_WIFI_DATA_SIZE, &tbl_rev);
	if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
	if (IS_ERR(wifi_pkg)) {
		ret = PTR_ERR(wifi_pkg);
		goto out_free;
	}

	if ((wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) ||
	    (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER)) {
	    (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER) ||
	    tbl_rev != 0) {
		ret = -EINVAL;
		goto out_free;
	}
@@ -791,11 +796,16 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)

	wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
					 ACPI_WGDS_WIFI_DATA_SIZE, &tbl_rev);
	if (IS_ERR(wifi_pkg) || tbl_rev > 1) {
	if (IS_ERR(wifi_pkg)) {
		ret = PTR_ERR(wifi_pkg);
		goto out_free;
	}

	if (tbl_rev != 0) {
		ret = -EINVAL;
		goto out_free;
	}

	mvm->geo_rev = tbl_rev;
	for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
		for (j = 0; j < ACPI_GEO_TABLE_SIZE; j++) {
@@ -889,15 +899,17 @@ static bool iwl_mvm_sar_geo_support(struct iwl_mvm *mvm)
	 * firmware versions.  Unfortunately, we don't have a TLV API
	 * flag to rely on, so rely on the major version which is in
	 * the first byte of ucode_ver.  This was implemented
	 * initially on version 38 and then backported to29 and 17.
	 * The intention was to have it in 36 as well, but not all
	 * 8000 family got this feature enabled.  The 8000 family is
	 * the only one using version 36, so skip this version
	 * entirely.
	 * initially on version 38 and then backported to 17.  It was
	 * also backported to 29, but only for 7265D devices.  The
	 * intention was to have it in 36 as well, but not all 8000
	 * family got this feature enabled.  The 8000 family is the
	 * only one using version 36, so skip this version entirely.
	 */
	return IWL_UCODE_SERIAL(mvm->fw->ucode_ver) >= 38 ||
	       IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 ||
	       IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17;
	       IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17 ||
	       (IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 &&
		((mvm->trans->hw_rev & CSR_HW_REV_TYPE_MSK) ==
		 CSR_HW_REV_TYPE_7265D));
}

int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
@@ -1020,11 +1032,16 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
	wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
					 ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev);

	if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
	if (IS_ERR(wifi_pkg)) {
		ret = PTR_ERR(wifi_pkg);
		goto out_free;
	}

	if (tbl_rev != 0) {
		ret = -EINVAL;
		goto out_free;
	}

	enabled = &wifi_pkg->package.elements[1];
	if (enabled->type != ACPI_TYPE_INTEGER ||
	    (enabled->integer.value != 0 && enabled->integer.value != 1)) {
+5 −4
Original line number Diff line number Diff line
@@ -4881,11 +4881,11 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
	if (!iwl_mvm_has_new_rx_api(mvm))
		return;

	if (notif->sync) {
		notif->cookie = mvm->queue_sync_cookie;

	if (notif->sync)
		atomic_set(&mvm->queue_sync_counter,
			   mvm->trans->num_rx_queues);
	}

	ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif,
				      size, !notif->sync);
@@ -4905,6 +4905,7 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,

out:
	atomic_set(&mvm->queue_sync_counter, 0);
	if (notif->sync)
		mvm->queue_sync_cookie++;
}

Loading