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

Commit 56007a02 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

mac80211: wait for beacon before enabling powersave



Because DTIM information is required for powersave
but is only conveyed in beacons, wait for a beacon
before enabling powersave, and change the way the
information is conveyed to the driver accordingly.

mwl8k doesn't currently seem to implement PS but
requires the DTIM period in a different way; after
talking to Lennert we agreed to just have mwl8k do
the parsing itself in the finalize_join work.

Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Acked-by: default avatarLennert Buytenhek <buytenh@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c21dbf92
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -319,7 +319,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
			priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;

	if (priv->vif)
		dtimper = priv->vif->bss_conf.dtim_period;
		dtimper = priv->hw->conf.ps_dtim_period;
	else
		dtimper = 1;

+9 −5
Original line number Diff line number Diff line
@@ -3881,12 +3881,16 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
	struct mwl8k_priv *priv =
		container_of(work, struct mwl8k_priv, finalize_join_worker);
	struct sk_buff *skb = priv->beacon_skb;
	struct mwl8k_vif *mwl8k_vif;
	struct ieee80211_mgmt *mgmt = (void *)skb->data;
	int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
	const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
					 mgmt->u.beacon.variable, len);
	int dtim_period = 1;

	mwl8k_vif = mwl8k_first_vif(priv);
	if (mwl8k_vif != NULL)
		mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len,
					mwl8k_vif->vif->bss_conf.dtim_period);
	if (tim && tim[1] >= 2)
		dtim_period = tim[3];

	mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);

	dev_kfree_skb(skb);
	priv->beacon_skb = NULL;
+0 −3
Original line number Diff line number Diff line
@@ -341,9 +341,6 @@ struct wl1251 {
	/* Are we currently scanning */
	bool scanning;

	/* Our association ID */
	u16 aid;

	/* Default key (for WEP) */
	u32 default_key;

+7 −18
Original line number Diff line number Diff line
@@ -617,10 +617,13 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)

		wl->psm_requested = true;

		wl->dtim_period = conf->ps_dtim_period;

		ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
						  wl->dtim_period);

		/*
		 * We enter PSM only if we're already associated.
		 * If we're not, we'll enter it when joining an SSID,
		 * through the bss_info_changed() hook.
		 * mac80211 enables PSM only if we're already associated.
		 */
		ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
		if (ret < 0)
@@ -943,7 +946,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
				       struct ieee80211_bss_conf *bss_conf,
				       u32 changed)
{
	enum wl1251_cmd_ps_mode mode;
	struct wl1251 *wl = hw->priv;
	struct sk_buff *beacon, *skb;
	int ret;
@@ -984,11 +986,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
	if (changed & BSS_CHANGED_ASSOC) {
		if (bss_conf->assoc) {
			wl->beacon_int = bss_conf->beacon_int;
			wl->dtim_period = bss_conf->dtim_period;

			ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
							  wl->dtim_period);
			wl->aid = bss_conf->aid;

			skb = ieee80211_pspoll_get(wl->hw, wl->vif);
			if (!skb)
@@ -1001,17 +998,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
			if (ret < 0)
				goto out_sleep;

			ret = wl1251_acx_aid(wl, wl->aid);
			ret = wl1251_acx_aid(wl, bss_conf->aid);
			if (ret < 0)
				goto out_sleep;

			/* If we want to go in PSM but we're not there yet */
			if (wl->psm_requested && !wl->psm) {
				mode = STATION_POWER_SAVE_MODE;
				ret = wl1251_ps_set_mode(wl, mode);
				if (ret < 0)
					goto out_sleep;
			}
		} else {
			/* use defaults when not associated */
			wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
+6 −1
Original line number Diff line number Diff line
@@ -186,7 +186,8 @@ enum ieee80211_bss_change {
 * @use_short_slot: use short slot time (only relevant for ERP);
 *	if the hardware cannot handle this it must set the
 *	IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag
 * @dtim_period: num of beacons before the next DTIM, for PSM
 * @dtim_period: num of beacons before the next DTIM, for beaconing,
 *	not valid in station mode (cf. hw conf ps_dtim_period)
 * @timestamp: beacon timestamp
 * @beacon_int: beacon interval
 * @assoc_capability: capabilities taken from assoc resp
@@ -648,6 +649,9 @@ enum ieee80211_smps_mode {
 *	value will be only achievable between DTIM frames, the hardware
 *	needs to check for the multicast traffic bit in DTIM beacons.
 *	This variable is valid only when the CONF_PS flag is set.
 * @ps_dtim_period: The DTIM period of the AP we're connected to, for use
 *	in power saving. Power saving will not be enabled until a beacon
 *	has been received and the DTIM period is known.
 * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the
 *	powersave documentation below. This variable is valid only when
 *	the CONF_PS flag is set.
@@ -674,6 +678,7 @@ struct ieee80211_conf {
	int max_sleep_period;

	u16 listen_interval;
	u8 ps_dtim_period;

	u8 long_frame_max_tx_count, short_frame_max_tx_count;

Loading