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

Commit 0574f2ed authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'wireless-drivers-for-davem-2019-08-06' of...

Merge tag 'wireless-drivers-for-davem-2019-08-06' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers



Kalle Valo says:

====================
wireless-drivers fixes for 5.3

Second set of fixes for 5.3. Lots of iwlwifi fixes have accumulated
which consists most of patches in this pull request. Only most notable
iwlwifi fixes are listed below.

mwifiex

* fix a regression related to WPA1 networks since v5.3-rc1

iwlwifi

* fix use-after-free issues

* fix DMA mapping API usage errors

* fix frame drop occurring due to reorder buffer handling in
  RSS in certain conditions

* fix rate scale locking issues

* disable TX A-MSDU on older NICs as it causes problems and was
  never supposed to be supported

* new PCI IDs

* GEO_TX_POWER_LIMIT API issue that many people were hitting
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d0d006a4 1f660725
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -776,7 +776,6 @@ struct iwl_rss_config_cmd {
	u8 indirection_table[IWL_RSS_INDIRECTION_TABLE_SIZE];
} __packed; /* RSS_CONFIG_CMD_API_S_VER_1 */

#define IWL_MULTI_QUEUE_SYNC_MSG_MAX_SIZE 128
#define IWL_MULTI_QUEUE_SYNC_SENDER_POS 0
#define IWL_MULTI_QUEUE_SYNC_SENDER_MSK 0xf

@@ -812,10 +811,12 @@ struct iwl_rxq_sync_notification {
 *
 * @IWL_MVM_RXQ_EMPTY: empty sync notification
 * @IWL_MVM_RXQ_NOTIF_DEL_BA: notify RSS queues of delBA
 * @IWL_MVM_RXQ_NSSN_SYNC: notify all the RSS queues with the new NSSN
 */
enum iwl_mvm_rxq_notif_type {
	IWL_MVM_RXQ_EMPTY,
	IWL_MVM_RXQ_NOTIF_DEL_BA,
	IWL_MVM_RXQ_NSSN_SYNC,
};

/**
+12 −10
Original line number Diff line number Diff line
@@ -2438,17 +2438,19 @@ static void iwl_fw_dbg_info_apply(struct iwl_fw_runtime *fwrt,
{
	u32 img_name_len = le32_to_cpu(dbg_info->img_name_len);
	u32 dbg_cfg_name_len = le32_to_cpu(dbg_info->dbg_cfg_name_len);
	const char err_str[] =
		"WRT: ext=%d. Invalid %s name length %d, expected %d\n";

	if (img_name_len != IWL_FW_INI_MAX_IMG_NAME_LEN) {
		IWL_WARN(fwrt, err_str, ext, "image", img_name_len,
		IWL_WARN(fwrt,
			 "WRT: ext=%d. Invalid image name length %d, expected %d\n",
			 ext, img_name_len,
			 IWL_FW_INI_MAX_IMG_NAME_LEN);
		return;
	}

	if (dbg_cfg_name_len != IWL_FW_INI_MAX_DBG_CFG_NAME_LEN) {
		IWL_WARN(fwrt, err_str, ext, "debug cfg", dbg_cfg_name_len,
		IWL_WARN(fwrt,
			 "WRT: ext=%d. Invalid debug cfg name length %d, expected %d\n",
			 ext, dbg_cfg_name_len,
			 IWL_FW_INI_MAX_DBG_CFG_NAME_LEN);
		return;
	}
@@ -2775,8 +2777,6 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
		struct iwl_ucode_tlv *tlv = iter;
		void *ini_tlv = (void *)tlv->data;
		u32 type = le32_to_cpu(tlv->type);
		const char invalid_ap_str[] =
			"WRT: ext=%d. Invalid apply point %d for %s\n";

		switch (type) {
		case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
@@ -2786,8 +2786,9 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
			struct iwl_fw_ini_allocation_data *buf_alloc = ini_tlv;

			if (pnt != IWL_FW_INI_APPLY_EARLY) {
				IWL_ERR(fwrt, invalid_ap_str, ext, pnt,
					"buffer allocation");
				IWL_ERR(fwrt,
					"WRT: ext=%d. Invalid apply point %d for buffer allocation\n",
					ext, pnt);
				goto next;
			}

@@ -2797,8 +2798,9 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
		}
		case IWL_UCODE_TLV_TYPE_HCMD:
			if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) {
				IWL_ERR(fwrt, invalid_ap_str, ext, pnt,
					"host command");
				IWL_ERR(fwrt,
					"WRT: ext=%d. Invalid apply point %d for host command\n",
					ext, pnt);
				goto next;
			}
			iwl_fw_dbg_send_hcmd(fwrt, tlv, ext);
+3 −1
Original line number Diff line number Diff line
@@ -1640,6 +1640,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
	init_completion(&drv->request_firmware_complete);
	INIT_LIST_HEAD(&drv->list);

	iwl_load_fw_dbg_tlv(drv->trans->dev, drv->trans);

#ifdef CONFIG_IWLWIFI_DEBUGFS
	/* Create the device debugfs entries. */
	drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev),
@@ -1660,8 +1662,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
err_fw:
#ifdef CONFIG_IWLWIFI_DEBUGFS
	debugfs_remove_recursive(drv->dbgfs_drv);
	iwl_fw_dbg_free(drv->trans);
#endif
	iwl_fw_dbg_free(drv->trans);
	kfree(drv);
err:
	return ERR_PTR(ret);
+21 −8
Original line number Diff line number Diff line
@@ -755,7 +755,7 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm)

	for (i = 0; i < n_profiles; i++) {
		/* the tables start at element 3 */
		static int pos = 3;
		int pos = 3;

		/* The EWRD profiles officially go from 2 to 4, but we
		 * save them in sar_profiles[1-3] (because we don't
@@ -880,6 +880,22 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
	return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
}

static bool iwl_mvm_sar_geo_support(struct iwl_mvm *mvm)
{
	/*
	 * The GEO_TX_POWER_LIMIT command is not supported on earlier
	 * 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 to 36, 29 and
	 * 17.
	 */
	return IWL_UCODE_SERIAL(mvm->fw->ucode_ver) >= 38 ||
	       IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 36 ||
	       IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 ||
	       IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17;
}

int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
{
	struct iwl_geo_tx_power_profiles_resp *resp;
@@ -909,6 +925,9 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
		.data = { data },
	};

	if (!iwl_mvm_sar_geo_support(mvm))
		return -EOPNOTSUPP;

	ret = iwl_mvm_send_cmd(mvm, &cmd);
	if (ret) {
		IWL_ERR(mvm, "Failed to get geographic profile info %d\n", ret);
@@ -934,13 +953,7 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
	int ret, i, j;
	u16 cmd_wide_id =  WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT);

	/*
	 * This command is not supported on earlier 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.
	 */
	if (IWL_UCODE_SERIAL(mvm->fw->ucode_ver) < 41)
	if (!iwl_mvm_sar_geo_support(mvm))
		return 0;

	ret = iwl_mvm_sar_get_wgds_table(mvm);
+42 −16
Original line number Diff line number Diff line
@@ -207,7 +207,7 @@ static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = {
	},
};

static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
				 enum set_key_cmd cmd,
				 struct ieee80211_vif *vif,
				 struct ieee80211_sta *sta,
@@ -474,6 +474,18 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
	ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
	ieee80211_hw_set(hw, BUFF_MMPDU_TXQ);
	ieee80211_hw_set(hw, STA_MMPDU_TXQ);
	/*
	 * On older devices, enabling TX A-MSDU occasionally leads to
	 * something getting messed up, the command read from the FIFO
	 * gets out of sync and isn't a TX command, so that we have an
	 * assert EDC.
	 *
	 * It's not clear where the bug is, but since we didn't used to
	 * support A-MSDU until moving the mac80211 iTXQs, just leave it
	 * for older devices. We also don't see this issue on any newer
	 * devices.
	 */
	if (mvm->cfg->device_family >= IWL_DEVICE_FAMILY_9000)
		ieee80211_hw_set(hw, TX_AMSDU);
	ieee80211_hw_set(hw, TX_FRAG_LIST);

@@ -2726,7 +2738,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,

		mvmvif->ap_early_keys[i] = NULL;

		ret = iwl_mvm_mac_set_key(hw, SET_KEY, vif, NULL, key);
		ret = __iwl_mvm_mac_set_key(hw, SET_KEY, vif, NULL, key);
		if (ret)
			goto out_quota_failed;
	}
@@ -3494,7 +3506,7 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
	return ret;
}

static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
				 enum set_key_cmd cmd,
				 struct ieee80211_vif *vif,
				 struct ieee80211_sta *sta,
@@ -3553,8 +3565,6 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
			return -EOPNOTSUPP;
	}

	mutex_lock(&mvm->mutex);

	switch (cmd) {
	case SET_KEY:
		if ((vif->type == NL80211_IFTYPE_ADHOC ||
@@ -3700,7 +3710,22 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
		ret = -EINVAL;
	}

	return ret;
}

static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
			       enum set_key_cmd cmd,
			       struct ieee80211_vif *vif,
			       struct ieee80211_sta *sta,
			       struct ieee80211_key_conf *key)
{
	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
	int ret;

	mutex_lock(&mvm->mutex);
	ret = __iwl_mvm_mac_set_key(hw, cmd, vif, sta, key);
	mutex_unlock(&mvm->mutex);

	return ret;
}

@@ -5041,7 +5066,6 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
	u32 qmask = BIT(mvm->trans->num_rx_queues) - 1;
	int ret;

	lockdep_assert_held(&mvm->mutex);

	if (!iwl_mvm_has_new_rx_api(mvm))
		return;
@@ -5052,13 +5076,15 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
		atomic_set(&mvm->queue_sync_counter,
			   mvm->trans->num_rx_queues);

	ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif, size);
	ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif,
				      size, !notif->sync);
	if (ret) {
		IWL_ERR(mvm, "Failed to trigger RX queues sync (%d)\n", ret);
		goto out;
	}

	if (notif->sync) {
		lockdep_assert_held(&mvm->mutex);
		ret = wait_event_timeout(mvm->rx_sync_waitq,
					 atomic_read(&mvm->queue_sync_counter) == 0 ||
					 iwl_mvm_is_radio_killed(mvm),
Loading