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

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

mac80211: pass all probe request IEs to driver



Instead of just passing the cfg80211-requested IEs, pass
the locally generated ones as well.

Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 18a83659
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -503,7 +503,7 @@ struct cfg80211_scan_request {
	int n_ssids;
	struct ieee80211_channel **channels;
	u32 n_channels;
	u8 *ie;
	const u8 *ie;
	size_t ie_len;

	/* internal */
+8 −5
Original line number Diff line number Diff line
@@ -1330,11 +1330,14 @@ enum ieee80211_ampdu_mlme_action {
 *	the scan state machine in stack. The scan must honour the channel
 *	configuration done by the regulatory agent in the wiphy's
 *	registered bands. The hardware (or the driver) needs to make sure
 *	that power save is disabled. When the scan finishes,
 *	ieee80211_scan_completed() must be called; note that it also must
 *	be called when the scan cannot finish because the hardware is
 *	turned off! Anything else is a bug! Returns a negative error code
 *	which will be seen in userspace.
 *	that power save is disabled.
 *	The @req ie/ie_len members are rewritten by mac80211 to contain the
 *	entire IEs after the SSID, so that drivers need not look at these
 *	at all but just send them after the SSID -- mac80211 includes the
 *	(extended) supported rates and HT information (where applicable).
 *	When the scan finishes, ieee80211_scan_completed() must be called;
 *	note that it also must be called when the scan cannot finish due to
 *	any error unless this callback returned a negative error code.
 *
 * @sw_scan_start: Notifier function that is called just before a software scan
 *	is started. Can be NULL, if the driver doesn't need this notification.
+7 −2
Original line number Diff line number Diff line
@@ -671,7 +671,10 @@ struct ieee80211_local {
	struct cfg80211_scan_request int_scan_req;
	struct cfg80211_scan_request *scan_req;
	struct ieee80211_channel *scan_channel;
	const u8 *orig_ies;
	int orig_ies_len;
	int scan_channel_idx;
	int scan_ies_len;

	enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
	unsigned long last_scan_completed;
@@ -1090,9 +1093,11 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
			 u16 transaction, u16 auth_alg,
			 u8 *extra, size_t extra_len,
			 const u8 *bssid, int encrypt);
int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
			     const u8 *ie, size_t ie_len);
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
			      u8 *ssid, size_t ssid_len,
			      u8 *ie, size_t ie_len);
			      const u8 *ssid, size_t ssid_len,
			      const u8 *ie, size_t ie_len);

void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
				  const size_t supp_rates_len,
+34 −15
Original line number Diff line number Diff line
@@ -729,22 +729,12 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,

	wiphy->privid = mac80211_wiphy_privid;

	if (!ops->hw_scan) {
		/* For hw_scan, driver needs to set these up. */
		wiphy->max_scan_ssids = 4;

		/* we support a maximum of 32 rates in cfg80211 */
		wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN
					 - 2 - 32 /* SSID */
					 - 4 - 32 /* (ext) supp rates */;

	}

	/* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
	wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
			       sizeof(struct cfg80211_bss);

	local = wiphy_priv(wiphy);

	local->hw.wiphy = wiphy;

	local->hw.priv = (char *)local +
@@ -831,7 +821,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
	enum ieee80211_band band;
	struct net_device *mdev;
	struct ieee80211_master_priv *mpriv;
	int channels, i, j;
	int channels, i, j, max_bitrates;

	/*
	 * generic code guarantees at least one band,
@@ -839,18 +829,23 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
	 * that hw.conf.channel is assigned
	 */
	channels = 0;
	max_bitrates = 0;
	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
		struct ieee80211_supported_band *sband;

		sband = local->hw.wiphy->bands[band];
		if (sband && !local->oper_channel) {
		if (!sband)
			continue;
		if (!local->oper_channel) {
			/* init channel we're on */
			local->hw.conf.channel =
			local->oper_channel =
			local->scan_channel = &sband->channels[0];
		}
		if (sband)
		channels += sband->n_channels;

		if (max_bitrates < sband->n_bitrates)
			max_bitrates = sband->n_bitrates;
	}

	local->int_scan_req.n_channels = channels;
@@ -870,6 +865,30 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
	else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
		local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;

	/*
	 * Calculate scan IE length -- we need this to alloc
	 * memory and to subtract from the driver limit. It
	 * includes the (extended) supported rates and HT
	 * information -- SSID is the driver's responsibility.
	 */
	local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */

	if (!local->ops->hw_scan) {
		/* For hw_scan, driver needs to set these up. */
		local->hw.wiphy->max_scan_ssids = 4;
		local->hw.wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
	}

	/*
	 * If the driver supports any scan IEs, then assume the
	 * limit includes the IEs mac80211 will add, otherwise
	 * leave it at zero and let the driver sort it out; we
	 * still pass our IEs to the driver but userspace will
	 * not be allowed to in that case.
	 */
	if (local->hw.wiphy->max_scan_ie_len)
		local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;

	result = wiphy_register(local->hw.wiphy);
	if (result < 0)
		goto fail_wiphy_register;
+23 −1
Original line number Diff line number Diff line
@@ -285,6 +285,12 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
	if (WARN_ON(!local->scan_req))
		return;

	if (local->hw_scanning) {
		kfree(local->scan_req->ie);
		local->scan_req->ie = local->orig_ies;
		local->scan_req->ie_len = local->orig_ies_len;
	}

	if (local->scan_req != &local->int_scan_req)
		cfg80211_scan_done(local->scan_req, aborted);
	local->scan_req = NULL;
@@ -457,12 +463,28 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
	}

	if (local->ops->hw_scan) {
		int rc;
		u8 *ies;
		int rc, ielen;

		ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN +
			      local->scan_ies_len + req->ie_len, GFP_KERNEL);
		if (!ies)
			return -ENOMEM;

		ielen = ieee80211_build_preq_ies(local, ies,
						 req->ie, req->ie_len);
		local->orig_ies = req->ie;
		local->orig_ies_len = req->ie_len;
		req->ie = ies;
		req->ie_len = ielen;

		local->hw_scanning = true;
		rc = local->ops->hw_scan(local_to_hw(local), req);
		if (rc) {
			local->hw_scanning = false;
			kfree(ies);
			req->ie_len = local->orig_ies_len;
			req->ie = local->orig_ies;
			return rc;
		}
		local->scan_sdata = scan_sdata;
Loading