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

Commit 078e1e60 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

mac80211: Add capability to enable/disable beaconing



This patch adds a flag to notify drivers to start and stop
beaconing when needed, for example, during a scan run. Based
on Sujith's first patch to do the same, but now disables
beaconing for all virtual interfaces while scanning, has a
separate change flag and tracks user-space requests.

Signed-off-by: default avatarSujith <Sujith.Manoharan@atheros.com>
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 07c1e852
Loading
Loading
Loading
Loading
+7 −2
Original line number Original line Diff line number Diff line
@@ -646,10 +646,12 @@ struct ieee80211_if_init_conf {
 * @IEEE80211_IFCC_BSSID: The BSSID changed.
 * @IEEE80211_IFCC_BSSID: The BSSID changed.
 * @IEEE80211_IFCC_BEACON: The beacon for this interface changed
 * @IEEE80211_IFCC_BEACON: The beacon for this interface changed
 *	(currently AP and MESH only), use ieee80211_beacon_get().
 *	(currently AP and MESH only), use ieee80211_beacon_get().
 * @IEEE80211_IFCC_BEACON_ENABLED: The enable_beacon value changed.
 */
 */
enum ieee80211_if_conf_change {
enum ieee80211_if_conf_change {
	IEEE80211_IFCC_BSSID		= BIT(0),
	IEEE80211_IFCC_BSSID		= BIT(0),
	IEEE80211_IFCC_BEACON		= BIT(1),
	IEEE80211_IFCC_BEACON		= BIT(1),
	IEEE80211_IFCC_BEACON_ENABLED	= BIT(2),
};
};


/**
/**
@@ -657,6 +659,8 @@ enum ieee80211_if_conf_change {
 *
 *
 * @changed: parameters that have changed, see &enum ieee80211_if_conf_change.
 * @changed: parameters that have changed, see &enum ieee80211_if_conf_change.
 * @bssid: BSSID of the network we are associated to/creating.
 * @bssid: BSSID of the network we are associated to/creating.
 * @enable_beacon: Indicates whether beacons can be sent.
 *	This is valid only for AP/IBSS/MESH modes.
 *
 *
 * This structure is passed to the config_interface() callback of
 * This structure is passed to the config_interface() callback of
 * &struct ieee80211_hw.
 * &struct ieee80211_hw.
@@ -664,6 +668,7 @@ enum ieee80211_if_conf_change {
struct ieee80211_if_conf {
struct ieee80211_if_conf {
	u32 changed;
	u32 changed;
	const u8 *bssid;
	const u8 *bssid;
	bool enable_beacon;
};
};


/**
/**
+3 −2
Original line number Original line Diff line number Diff line
@@ -523,7 +523,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,


	kfree(old);
	kfree(old);


	return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
	return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
					  IEEE80211_IFCC_BEACON_ENABLED);
}
}


static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
@@ -583,7 +584,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
	synchronize_rcu();
	synchronize_rcu();
	kfree(old);
	kfree(old);


	return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
	return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
}
}


/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
+41 −1
Original line number Original line Diff line number Diff line
@@ -168,7 +168,6 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
		return 0;
		return 0;


	memset(&conf, 0, sizeof(conf));
	memset(&conf, 0, sizeof(conf));
	conf.changed = changed;


	if (sdata->vif.type == NL80211_IFTYPE_STATION ||
	if (sdata->vif.type == NL80211_IFTYPE_STATION ||
	    sdata->vif.type == NL80211_IFTYPE_ADHOC)
	    sdata->vif.type == NL80211_IFTYPE_ADHOC)
@@ -183,9 +182,50 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
		return -EINVAL;
		return -EINVAL;
	}
	}


	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_MESH_POINT:
		break;
	default:
		/* do not warn to simplify caller in scan.c */
		changed &= ~IEEE80211_IFCC_BEACON_ENABLED;
		if (WARN_ON(changed & IEEE80211_IFCC_BEACON))
			return -EINVAL;
		changed &= ~IEEE80211_IFCC_BEACON;
		break;
	}

	if (changed & IEEE80211_IFCC_BEACON_ENABLED) {
		if (local->sw_scanning) {
			conf.enable_beacon = false;
		} else {
			/*
			 * Beacon should be enabled, but AP mode must
			 * check whether there is a beacon configured.
			 */
			switch (sdata->vif.type) {
			case NL80211_IFTYPE_AP:
				conf.enable_beacon =
					!!rcu_dereference(sdata->u.ap.beacon);
				break;
			case NL80211_IFTYPE_ADHOC:
			case NL80211_IFTYPE_MESH_POINT:
				conf.enable_beacon = true;
				break;
			default:
				/* not reached */
				WARN_ON(1);
				break;
			}
		}
	}

	if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID)))
	if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID)))
		return -EINVAL;
		return -EINVAL;


	conf.changed = changed;

	return local->ops->config_interface(local_to_hw(local),
	return local->ops->config_interface(local_to_hw(local),
					    &sdata->vif, &conf);
					    &sdata->vif, &conf);
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -442,7 +442,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)


	ifmsh->housekeeping = true;
	ifmsh->housekeeping = true;
	queue_work(local->hw.workqueue, &ifmsh->work);
	queue_work(local->hw.workqueue, &ifmsh->work);
	ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
	ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
				   IEEE80211_IFCC_BEACON_ENABLED);
}
}


void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
+2 −1
Original line number Original line Diff line number Diff line
@@ -1599,7 +1599,8 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,


	ifsta->probe_resp = skb;
	ifsta->probe_resp = skb;


	ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
	ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
				   IEEE80211_IFCC_BEACON_ENABLED);




	rates = 0;
	rates = 0;
Loading