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

Commit 5c1b98a5 authored by Kalle Valo's avatar Kalle Valo Committed by John W. Linville
Browse files

mac80211: create tx handler for dynamic ps



Currently dynamic ps check is in ieee80211_xmit(), but it's cleaner
to have a separate tx handler for this. Also this is a prerequisite for
U-APSD client mode which needs to know the queue frame is in.

Also need_dynamic_ps() function is embedded to the tx handler.

No functional changes expect that the code is run in a later phase than
originally.

Signed-off-by: default avatarKalle Valo <kalle.valo@nokia.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 50ae0cf1
Loading
Loading
Loading
Loading
+41 −40
Original line number Original line Diff line number Diff line
@@ -180,6 +180,46 @@ static int inline is_ieee80211_device(struct ieee80211_local *local,
}
}


/* tx handlers */
/* tx handlers */
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
{
	struct ieee80211_local *local = tx->local;

	/* driver doesn't support power save */
	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
		return TX_CONTINUE;

	/* hardware does dynamic power save */
	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
		return TX_CONTINUE;

	/* dynamic power save disabled */
	if (local->hw.conf.dynamic_ps_timeout <= 0)
		return TX_CONTINUE;

	/* we are scanning, don't enable power save */
	if (local->scanning)
		return TX_CONTINUE;

	if (!local->ps_sdata)
		return TX_CONTINUE;

	/* No point if we're going to suspend */
	if (local->quiescing)
		return TX_CONTINUE;

	if (local->hw.conf.flags & IEEE80211_CONF_PS) {
		ieee80211_stop_queues_by_reason(&local->hw,
						IEEE80211_QUEUE_STOP_REASON_PS);
		ieee80211_queue_work(&local->hw,
				     &local->dynamic_ps_disable_work);
	}

	mod_timer(&local->dynamic_ps_timer, jiffies +
		  msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));

	return TX_CONTINUE;
}


static ieee80211_tx_result debug_noinline
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
@@ -1223,6 +1263,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
			goto txh_done;	\
			goto txh_done;	\
	} while (0)
	} while (0)


	CALL_TXH(ieee80211_tx_h_dynamic_ps);
	CALL_TXH(ieee80211_tx_h_check_assoc);
	CALL_TXH(ieee80211_tx_h_check_assoc);
	CALL_TXH(ieee80211_tx_h_ps_buf);
	CALL_TXH(ieee80211_tx_h_ps_buf);
	CALL_TXH(ieee80211_tx_h_select_key);
	CALL_TXH(ieee80211_tx_h_select_key);
@@ -1405,34 +1446,6 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
	return 0;
	return 0;
}
}


static bool need_dynamic_ps(struct ieee80211_local *local)
{
	/* driver doesn't support power save */
	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
		return false;

	/* hardware does dynamic power save */
	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
		return false;

	/* dynamic power save disabled */
	if (local->hw.conf.dynamic_ps_timeout <= 0)
		return false;

	/* we are scanning, don't enable power save */
	if (local->scanning)
		return false;

	if (!local->ps_sdata)
		return false;

	/* No point if we're going to suspend */
	if (local->quiescing)
		return false;

	return true;
}

static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
			   struct sk_buff *skb)
			   struct sk_buff *skb)
{
{
@@ -1443,18 +1456,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
	int headroom;
	int headroom;
	bool may_encrypt;
	bool may_encrypt;


	if (need_dynamic_ps(local)) {
		if (local->hw.conf.flags & IEEE80211_CONF_PS) {
			ieee80211_stop_queues_by_reason(&local->hw,
					IEEE80211_QUEUE_STOP_REASON_PS);
			ieee80211_queue_work(&local->hw,
					&local->dynamic_ps_disable_work);
		}

		mod_timer(&local->dynamic_ps_timer, jiffies +
		        msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
	}

	rcu_read_lock();
	rcu_read_lock();


	if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
	if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {