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

Commit 4c707c04 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge tag 'iwlwifi-for-kalle-2017-09-15' of...

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

First set of fixes for 4.14

* A couple of bugzilla bugs related to multicast handling;
* Two fixes for WoWLAN bugs that were causing queue hangs and
  re-initialization problems;
* Two fixes for potential uninitialized variable use reported by Dan
  Carpenter in relation to a recently introduced patch;
* A fix for buffer reordering in the newly supported 9000 device
  family;
* Fix a race when starting aggregation;
* Small fix for a recent patch to wake mac80211 queues;
* Send non-bufferable management frames in the generic queue so they
  are not sent on queues that are under power-save;
parents 2bd6bf03 5f90472c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2167,7 +2167,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
	 * 1. We are not using a unified image
	 * 2. We are using a unified image but had an error while exiting D3
	 */
	set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
	set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
	set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
	/*
	 * When switching images we return 1, which causes mac80211
+59 −3
Original line number Diff line number Diff line
@@ -1546,6 +1546,11 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
	struct iwl_mvm_mc_iter_data *data = _data;
	struct iwl_mvm *mvm = data->mvm;
	struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
	struct iwl_host_cmd hcmd = {
		.id = MCAST_FILTER_CMD,
		.flags = CMD_ASYNC,
		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
	};
	int ret, len;

	/* if we don't have free ports, mcast frames will be dropped */
@@ -1560,7 +1565,10 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
	memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
	len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);

	ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd);
	hcmd.len[0] = len;
	hcmd.data[0] = cmd;

	ret = iwl_mvm_send_cmd(mvm, &hcmd);
	if (ret)
		IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
}
@@ -1635,6 +1643,12 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
	if (!cmd)
		goto out;

	if (changed_flags & FIF_ALLMULTI)
		cmd->pass_all = !!(*total_flags & FIF_ALLMULTI);

	if (cmd->pass_all)
		cmd->count = 0;

	iwl_mvm_recalc_multicast(mvm);
out:
	mutex_unlock(&mvm->mutex);
@@ -2563,7 +2577,7 @@ static void iwl_mvm_purge_deferred_tx_frames(struct iwl_mvm *mvm,
			 * queues, so we should never get a second deferred
			 * frame for the RA/TID.
			 */
			iwl_mvm_start_mac_queues(mvm, info->hw_queue);
			iwl_mvm_start_mac_queues(mvm, BIT(info->hw_queue));
			ieee80211_free_txskb(mvm->hw, skb);
		}
	}
@@ -3975,6 +3989,43 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
	return ret;
}

static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop)
{
	if (drop) {
		if (iwl_mvm_has_new_tx_api(mvm))
			/* TODO new tx api */
			WARN_ONCE(1,
				  "Need to implement flush TX queue\n");
		else
			iwl_mvm_flush_tx_path(mvm,
				iwl_mvm_flushable_queues(mvm) & queues,
				0);
	} else {
		if (iwl_mvm_has_new_tx_api(mvm)) {
			struct ieee80211_sta *sta;
			int i;

			mutex_lock(&mvm->mutex);

			for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
				sta = rcu_dereference_protected(
						mvm->fw_id_to_mac_id[i],
						lockdep_is_held(&mvm->mutex));
				if (IS_ERR_OR_NULL(sta))
					continue;

				iwl_mvm_wait_sta_queues_empty(mvm,
						iwl_mvm_sta_from_mac80211(sta));
			}

			mutex_unlock(&mvm->mutex);
		} else {
			iwl_trans_wait_tx_queues_empty(mvm->trans,
						       queues);
		}
	}
}

static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
			      struct ieee80211_vif *vif, u32 queues, bool drop)
{
@@ -3985,7 +4036,12 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
	int i;
	u32 msk = 0;

	if (!vif || vif->type != NL80211_IFTYPE_STATION)
	if (!vif) {
		iwl_mvm_flush_no_vif(mvm, queues, drop);
		return;
	}

	if (vif->type != NL80211_IFTYPE_STATION)
		return;

	/* Make sure we're done with the deferred traffic before flushing */
+2 −1
Original line number Diff line number Diff line
@@ -661,7 +661,8 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
	    (lq_sta->tx_agg_tid_en & BIT(tid)) &&
	    (tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
		IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid);
		rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta);
		if (rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta) == 0)
			tid_data->state = IWL_AGG_QUEUED;
	}
}

+4 −3
Original line number Diff line number Diff line
@@ -672,11 +672,12 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
	 * If there was a significant jump in the nssn - adjust.
	 * If the SN is smaller than the NSSN it might need to first go into
	 * the reorder buffer, in which case we just release up to it and the
	 * rest of the function will take of storing it and releasing up to the
	 * nssn
	 * rest of the function will take care of storing it and releasing up to
	 * the nssn
	 */
	if (!iwl_mvm_is_sn_less(nssn, buffer->head_sn + buffer->buf_size,
				buffer->buf_size)) {
				buffer->buf_size) ||
	    !ieee80211_sn_less(sn, buffer->head_sn + buffer->buf_size)) {
		u16 min_sn = ieee80211_sn_less(sn, nssn) ? sn : nssn;

		iwl_mvm_release_frames(mvm, sta, napi, buffer, min_sn);
+1 −1
Original line number Diff line number Diff line
@@ -555,7 +555,7 @@ static int iwl_mvm_lmac_scan_abort(struct iwl_mvm *mvm)
	struct iwl_host_cmd cmd = {
		.id = SCAN_OFFLOAD_ABORT_CMD,
	};
	u32 status;
	u32 status = CAN_ABORT_STATUS;

	ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
	if (ret)
Loading