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

Commit c8f54701 authored by Johannes Berg's avatar Johannes Berg Committed by Luca Coelho
Browse files

iwlwifi: mvm: remove non-DQA mode



All the firmware versions the driver supports enable DQA, and thus
the only way to get non-DQA mode is to modify the source. Remove
this mode to simplify the code.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent d197358b
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -62,12 +62,6 @@
#ifndef __iwl_fw_api_txq_h__
#define __iwl_fw_api_txq_h__

/* Tx queue numbers for non-DQA mode */
enum {
	IWL_MVM_OFFCHANNEL_QUEUE = 8,
	IWL_MVM_CMD_QUEUE = 9,
};

/*
 * DQA queue numbers
 *
+4 −12
Original line number Diff line number Diff line
@@ -331,10 +331,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
	 */

	memset(&mvm->queue_info, 0, sizeof(mvm->queue_info));
	if (iwl_mvm_is_dqa_supported(mvm))
	mvm->queue_info[IWL_MVM_DQA_CMD_QUEUE].hw_queue_refcount = 1;
	else
		mvm->queue_info[IWL_MVM_CMD_QUEUE].hw_queue_refcount = 1;

	for (i = 0; i < IEEE80211_MAX_QUEUES; i++)
		atomic_set(&mvm->mac80211_queue_stop_count[i], 0);
@@ -1137,14 +1134,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
	/* reset quota debouncing buffer - 0xff will yield invalid data */
	memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd));

	/* Enable DQA-mode if required */
	if (iwl_mvm_is_dqa_supported(mvm)) {
	ret = iwl_mvm_send_dqa_cmd(mvm);
	if (ret)
		goto error;
	} else {
		IWL_DEBUG_FW(mvm, "Working in non-DQA mode\n");
	}

	/* Add auxiliary station for scanning */
	ret = iwl_mvm_add_aux_sta(mvm);
+16 −148
Original line number Diff line number Diff line
@@ -241,32 +241,17 @@ static void iwl_mvm_iface_hw_queues_iter(void *_data, u8 *mac,
	data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(vif);
}

static void iwl_mvm_mac_sta_hw_queues_iter(void *_data,
					   struct ieee80211_sta *sta)
{
	struct iwl_mvm_hw_queues_iface_iterator_data *data = _data;
	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);

	/* Mark the queues used by the sta */
	data->used_hw_queues |= mvmsta->tfd_queue_msk;
}

unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
					 struct ieee80211_vif *exclude_vif)
{
	u8 sta_id;
	struct iwl_mvm_hw_queues_iface_iterator_data data = {
		.exclude_vif = exclude_vif,
		.used_hw_queues =
			BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
			BIT(mvm->aux_queue),
			BIT(mvm->aux_queue) |
			BIT(IWL_MVM_DQA_GCAST_QUEUE),
	};

	if (iwl_mvm_is_dqa_supported(mvm))
		data.used_hw_queues |= BIT(IWL_MVM_DQA_GCAST_QUEUE);
	else
		data.used_hw_queues |= BIT(IWL_MVM_CMD_QUEUE);

	lockdep_assert_held(&mvm->mutex);

	/* mark all VIF used hw queues */
@@ -274,26 +259,6 @@ unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
		mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
		iwl_mvm_iface_hw_queues_iter, &data);

	/*
	 * for DQA, the hw_queue in mac80211 is never really used for
	 * real traffic (only the few queue IDs covered above), so
	 * we can reuse the real HW queue IDs the stations use
	 */
	if (iwl_mvm_is_dqa_supported(mvm))
		return data.used_hw_queues;

	/* don't assign the same hw queues as TDLS stations */
	ieee80211_iterate_stations_atomic(mvm->hw,
					  iwl_mvm_mac_sta_hw_queues_iter,
					  &data);

	/*
	 * Some TDLS stations may be removed but are in the process of being
	 * drained. Don't touch their queues.
	 */
	for_each_set_bit(sta_id, mvm->sta_drained, IWL_MVM_STATION_COUNT)
		data.used_hw_queues |= mvm->tfd_drained[sta_id];

	return data.used_hw_queues;
}

@@ -344,8 +309,7 @@ void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
						NUM_TSF_IDS);
}

static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
					       struct ieee80211_vif *vif)
int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_mac_iface_iterator_data data = {
@@ -361,6 +325,8 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
	int ret, i, queue_limit;
	unsigned long used_hw_queues;

	lockdep_assert_held(&mvm->mutex);

	/*
	 * Allocate a MAC ID and a TSF for this MAC, along with the queues
	 * and other resources.
@@ -444,7 +410,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
		return 0;
	}

	if (iwl_mvm_is_dqa_supported(mvm)) {
	/*
	 * queues in mac80211 almost entirely independent of
	 * the ones here - no real limit
@@ -453,10 +418,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
	BUILD_BUG_ON(IEEE80211_MAX_QUEUES >
		     BITS_PER_BYTE *
		     sizeof(mvm->hw_queue_to_mac80211[0]));
	} else {
		/* need to not use too many in this case */
		queue_limit = mvm->first_agg_queue;
	}

	/*
	 * Find available queues, and allocate them to the ACs. When in
@@ -478,27 +439,12 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,

	/* Allocate the CAB queue for softAP and GO interfaces */
	if (vif->type == NL80211_IFTYPE_AP) {
		u8 queue;

		if (!iwl_mvm_is_dqa_supported(mvm)) {
			queue = find_first_zero_bit(&used_hw_queues,
						    mvm->first_agg_queue);

			if (queue >= mvm->first_agg_queue) {
				IWL_ERR(mvm, "Failed to allocate cab queue\n");
				ret = -EIO;
				goto exit_fail;
			}
		} else {
			queue = IWL_MVM_DQA_GCAST_QUEUE;
		}

		/*
		 * For TVQM this will be overwritten later with the FW assigned
		 * queue value (when queue is enabled).
		 */
		mvmvif->cab_queue = queue;
		vif->cab_queue = queue;
		mvmvif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
		vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
	} else {
		vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
	}
@@ -519,78 +465,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
	return ret;
}

int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	unsigned int wdg_timeout =
		iwl_mvm_get_wd_timeout(mvm, vif, false, false);
	u32 ac;
	int ret;

	lockdep_assert_held(&mvm->mutex);

	ret = iwl_mvm_mac_ctxt_allocate_resources(mvm, vif);
	if (ret)
		return ret;

	/* If DQA is supported - queues will be enabled when needed */
	if (iwl_mvm_is_dqa_supported(mvm))
		return 0;

	switch (vif->type) {
	case NL80211_IFTYPE_P2P_DEVICE:
		iwl_mvm_enable_ac_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE,
				      IWL_MVM_OFFCHANNEL_QUEUE,
				      IWL_MVM_TX_FIFO_VO, 0, wdg_timeout);
		break;
	case NL80211_IFTYPE_AP:
		iwl_mvm_enable_ac_txq(mvm, vif->cab_queue, vif->cab_queue,
				      IWL_MVM_TX_FIFO_MCAST, 0, wdg_timeout);
		/* fall through */
	default:
		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
			iwl_mvm_enable_ac_txq(mvm, vif->hw_queue[ac],
					      vif->hw_queue[ac],
					      iwl_mvm_ac_to_tx_fifo[ac], 0,
					      wdg_timeout);
		break;
	}

	return 0;
}

void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	int ac;

	lockdep_assert_held(&mvm->mutex);

	/*
	 * If DQA is supported - queues were already disabled, since in
	 * DQA-mode the queues are a property of the STA and not of the
	 * vif, and at this point the STA was already deleted
	 */
	if (iwl_mvm_is_dqa_supported(mvm))
		return;

	switch (vif->type) {
	case NL80211_IFTYPE_P2P_DEVICE:
		iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE,
				    IWL_MVM_OFFCHANNEL_QUEUE,
				    IWL_MAX_TID_COUNT, 0);

		break;
	case NL80211_IFTYPE_AP:
		iwl_mvm_disable_txq(mvm, vif->cab_queue, vif->cab_queue,
				    IWL_MAX_TID_COUNT, 0);
		/* fall through */
	default:
		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
			iwl_mvm_disable_txq(mvm, vif->hw_queue[ac],
					    vif->hw_queue[ac],
					    IWL_MAX_TID_COUNT, 0);
	}
}

static void iwl_mvm_ack_rates(struct iwl_mvm *mvm,
			      struct ieee80211_vif *vif,
			      enum nl80211_band band,
@@ -914,18 +788,12 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
{
	struct iwl_mac_ctx_cmd cmd = {};
	u32 tfd_queue_msk = 0;
	int ret, i;
	int ret;

	WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);

	iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);

	if (!iwl_mvm_is_dqa_supported(mvm)) {
		for (i = 0; i < IEEE80211_NUM_ACS; i++)
			if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE)
				tfd_queue_msk |= BIT(vif->hw_queue[i]);
	}

	cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
				       MAC_FILTER_IN_CONTROL_AND_MGMT |
				       MAC_FILTER_IN_BEACON |
+12 −77
Original line number Diff line number Diff line
@@ -464,9 +464,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
	if (mvm->trans->max_skb_frags)
		hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG;

	if (!iwl_mvm_is_dqa_supported(mvm))
		hw->queues = mvm->first_agg_queue;
	else
	hw->queues = IEEE80211_MAX_QUEUES;
	hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
	hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC |
@@ -1067,9 +1064,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)

	iwl_mvm_reset_phy_ctxts(mvm);
	memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
	memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
	memset(mvm->sta_deferred_frames, 0, sizeof(mvm->sta_deferred_frames));
	memset(mvm->tfd_drained, 0, sizeof(mvm->tfd_drained));
	memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
	memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd));

@@ -1372,7 +1367,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
			goto out_release;
		}

		if (iwl_mvm_is_dqa_supported(mvm)) {
		/*
		 * Only queue for this station is the mcast queue,
		 * which shouldn't be in TFD mask anyway
@@ -1382,7 +1376,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
					       IWL_STA_MULTICAST);
		if (ret)
			goto out_release;
		}

		iwl_mvm_vif_dbgfs_register(mvm, vif);
		goto out_unlock;
@@ -1456,8 +1449,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
 out_release:
	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
		mvm->vif_count--;

	iwl_mvm_mac_ctxt_release(mvm, vif);
 out_unlock:
	mutex_unlock(&mvm->mutex);

@@ -1469,40 +1460,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
					struct ieee80211_vif *vif)
{
	u32 tfd_msk = iwl_mvm_mac_get_queues_mask(vif);

	if (tfd_msk && !iwl_mvm_is_dqa_supported(mvm)) {
		/*
		 * mac80211 first removes all the stations of the vif and
		 * then removes the vif. When it removes a station it also
		 * flushes the AMPDU session. So by now, all the AMPDU sessions
		 * of all the stations of this vif are closed, and the queues
		 * of these AMPDU sessions are properly closed.
		 * We still need to take care of the shared queues of the vif.
		 * Flush them here.
		 * For DQA mode there is no need - broacast and multicast queue
		 * are flushed separately.
		 */
		mutex_lock(&mvm->mutex);
		iwl_mvm_flush_tx_path(mvm, tfd_msk, 0);
		mutex_unlock(&mvm->mutex);

		/*
		 * There are transports that buffer a few frames in the host.
		 * For these, the flush above isn't enough since while we were
		 * flushing, the transport might have sent more frames to the
		 * device. To solve this, wait here until the transport is
		 * empty. Technically, this could have replaced the flush
		 * above, but flush is much faster than draining. So flush
		 * first, and drain to make sure we have no frames in the
		 * transport anymore.
		 * If a station still had frames on the shared queues, it is
		 * already marked as draining, so to complete the draining, we
		 * just need to wait until the transport is empty.
		 */
		iwl_trans_wait_tx_queues_empty(mvm->trans, tfd_msk);
	}

	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
		/*
		 * Flush the ROC worker which will flush the OFFCHANNEL queue.
@@ -1510,14 +1467,6 @@ static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
		 * queue are sent in ROC session.
		 */
		flush_work(&mvm->roc_done_wk);
	} else {
		/*
		 * By now, all the AC queues are empty. The AGG queues are
		 * empty too. We already got all the Tx responses for all the
		 * packets in the queues. The drain work can have been
		 * triggered. Flush it.
		 */
		flush_work(&mvm->sta_drained_wk);
	}
}

@@ -1571,7 +1520,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
	iwl_mvm_mac_ctxt_remove(mvm, vif);

out_release:
	iwl_mvm_mac_ctxt_release(mvm, vif);
	mutex_unlock(&mvm->mutex);
}

@@ -2419,11 +2367,6 @@ static void __iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
		struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];

		if (!iwl_mvm_is_dqa_supported(mvm) &&
		    tid_data->state != IWL_AGG_ON &&
		    tid_data->state != IWL_EMPTYING_HW_QUEUE_DELBA)
			continue;

		if (tid_data->txq_id == IWL_MVM_INVALID_QUEUE)
			continue;

@@ -2437,9 +2380,6 @@ static void __iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,

	switch (cmd) {
	case STA_NOTIFY_SLEEP:
		if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
			ieee80211_sta_block_awake(hw, sta, true);

		for_each_set_bit(tid, &tids, IWL_MAX_TID_COUNT)
			ieee80211_sta_set_buffered(sta, tid, true);

@@ -2632,9 +2572,6 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
	if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
		return -EINVAL;

	/* if a STA is being removed, reuse its ID */
	flush_work(&mvm->sta_drained_wk);

	/*
	 * If we are in a STA removal flow and in DQA mode:
	 *
@@ -2649,8 +2586,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
	 * make sure the worker is no longer handling frames for this STA.
	 */
	if (old_state == IEEE80211_STA_NONE &&
	    new_state == IEEE80211_STA_NOTEXIST &&
	    iwl_mvm_is_dqa_supported(mvm)) {
	    new_state == IEEE80211_STA_NOTEXIST) {
		iwl_mvm_purge_deferred_tx_frames(mvm, mvm_sta);
		flush_work(&mvm->add_stream_wk);

@@ -4032,7 +3968,6 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
		return;

	/* Make sure we're done with the deferred traffic before flushing */
	if (iwl_mvm_is_dqa_supported(mvm))
	flush_work(&mvm->add_stream_wk);

	mutex_lock(&mvm->mutex);
+4 −36
Original line number Diff line number Diff line
@@ -121,6 +121,9 @@
 */
#define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3

/* offchannel queue towards mac80211 */
#define IWL_MVM_OFFCHANNEL_QUEUE 0

extern const struct ieee80211_ops iwl_mvm_hw_ops;

/**
@@ -783,11 +786,7 @@ struct iwl_mvm {
	/* data related to data path */
	struct iwl_rx_phy_info last_phy_info;
	struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT];
	struct work_struct sta_drained_wk;
	unsigned long sta_deferred_frames[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
	unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
	atomic_t pending_frames[IWL_MVM_STATION_COUNT];
	u32 tfd_drained[IWL_MVM_STATION_COUNT];
	u8 rx_ba_sessions;

	/* configured by mac80211 */
@@ -960,9 +959,6 @@ struct iwl_mvm {
	u16 probe_queue;
	u16 p2p_dev_queue;

	u8 first_agg_queue;
	u8 last_agg_queue;

	/* Indicate if device power save is allowed */
	u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */
	unsigned int max_amsdu_len; /* used for debugfs only */
@@ -1125,12 +1121,6 @@ static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
			    IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
}

static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm)
{
	return fw_has_capa(&mvm->fw->ucode_capa,
			   IWL_UCODE_TLV_CAPA_DQA_SUPPORT);
}

static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm)
{
	/* For now we only use this mode to differentiate between
@@ -1469,7 +1459,6 @@ u8 iwl_mvm_get_ctrl_pos(struct cfg80211_chan_def *chandef);

/* MAC (virtual interface) programming */
int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			     bool force_assoc_off, const u8 *bssid_override);
@@ -1720,10 +1709,6 @@ bool iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue,
			    u8 sta_id, u8 tid, unsigned int timeout);

/*
 * Disable a TXQ.
 * Note that in non-DQA mode the %mac80211_queue and %tid params are ignored.
 */
int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
			u8 tid, u8 flags);
int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq);
@@ -1733,25 +1718,8 @@ int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq);
 */
static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm)
{
	u32 cmd_queue = iwl_mvm_is_dqa_supported(mvm) ? IWL_MVM_DQA_CMD_QUEUE :
		IWL_MVM_CMD_QUEUE;

	return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) &
		~BIT(cmd_queue));
}

static inline
void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
			   u8 fifo, u16 ssn, unsigned int wdg_timeout)
{
	struct iwl_trans_txq_scd_cfg cfg = {
		.fifo = fifo,
		.tid = IWL_MAX_TID_COUNT,
		.aggregate = false,
		.frame_limit = IWL_FRAME_LIMIT,
	};

	iwl_mvm_enable_txq(mvm, queue, mac80211_queue, ssn, &cfg, wdg_timeout);
		~BIT(IWL_MVM_DQA_CMD_QUEUE));
}

static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
Loading