/*
 * cfg80211 scan result handling
 *
 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/nl80211.h>
#include <linux/etherdevice.h>
#include <net/arp.h>
#include <net/cfg80211.h>
#include <net/iw_handler.h>
#include "core.h"
#include "nl80211.h"

#define IEEE80211_SCAN_RESULT_EXPIRE	(10 * HZ)

void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
{
	struct net_device *dev;
#ifdef CONFIG_WIRELESS_EXT
	union iwreq_data wrqu;
#endif

	dev = dev_get_by_index(&init_net, request->ifidx);
	if (!dev)
		goto out;

	WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);

	if (aborted)
		nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
	else
		nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);

	wiphy_to_dev(request->wiphy)->scan_req = NULL;

#ifdef CONFIG_WIRELESS_EXT
	if (!aborted) {
		memset(&wrqu, 0, sizeof(wrqu));

		wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
	}
#endif

	dev_put(dev);

 out:
	kfree(request);
}
EXPORT_SYMBOL(cfg80211_scan_done);

static void bss_release(struct kref *ref)
{
	struct cfg80211_internal_bss *bss;

	bss = container_of(ref, struct cfg80211_internal_bss, ref);
	if (bss->pub.free_priv)
		bss->pub.free_priv(&bss->pub);

	if (bss->ies_allocated)
		kfree(bss->pub.information_elements);

	kfree(bss);
}

/* must hold dev->bss_lock! */
void cfg80211_bss_age(struct cfg80211_registered_device *dev,
                      unsigned long age_secs)
{
	struct cfg80211_internal_bss *bss;
	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);

	list_for_each_entry(bss, &dev->bss_list, list) {
		bss->ts -= age_jiffies;
	}
}

/* must hold dev->bss_lock! */
void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
{
	struct cfg80211_internal_bss *bss, *tmp;
	bool expired = false;

	list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
		if (bss->hold ||
		    !time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
			continue;
		list_del(&bss->list);
		rb_erase(&bss->rbn, &dev->bss_tree);
		kref_put(&bss->ref, bss_release);
		expired = true;
	}

	if (expired)
		dev->bss_generation++;
}

static u8 *find_ie(u8 num, u8 *ies, size_t len)
{
	while (len > 2 && ies[0] != num) {
		len -= ies[1] + 2;
		ies += ies[1] + 2;
	}
	if (len < 2)
		return NULL;
	if (len < 2 + ies[1])
		return NULL;
	return ies;
}

static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
{
	const u8 *ie1 = find_ie(num, ies1, len1);
	const u8 *ie2 = find_ie(num, ies2, len2);
	int r;

	if (!ie1 && !ie2)
		return 0;
	if (!ie1)
		return -1;

	r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
	if (r == 0 && ie1[1] != ie2[1])
		return ie2[1] - ie1[1];
	return r;
}

static bool is_bss(struct cfg80211_bss *a,
		   const u8 *bssid,
		   const u8 *ssid, size_t ssid_len)
{
	const u8 *ssidie;

	if (bssid && compare_ether_addr(a->bssid, bssid))
		return false;

	if (!ssid)
		return true;

	ssidie = find_ie(WLAN_EID_SSID,
			 a->information_elements,
			 a->len_information_elements);
	if (!ssidie)
		return false;
	if (ssidie[1] != ssid_len)
		return false;
	return memcmp(ssidie + 2, ssid, ssid_len) == 0;
}

static bool is_mesh(struct cfg80211_bss *a,
		    const u8 *meshid, size_t meshidlen,
		    const u8 *meshcfg)
{
	const u8 *ie;

	if (!is_zero_ether_addr(a->bssid))
		return false;

	ie = find_ie(WLAN_EID_MESH_ID,
		     a->information_elements,
		     a->len_information_elements);
	if (!ie)
		return false;
	if (ie[1] != meshidlen)
		return false;
	if (memcmp(ie + 2, meshid, meshidlen))
		return false;

	ie = find_ie(WLAN_EID_MESH_CONFIG,
		     a->information_elements,
		     a->len_information_elements);
	if (ie[1] != IEEE80211_MESH_CONFIG_LEN)
		return false;

	/*
	 * Ignore mesh capability (last two bytes of the IE) when
	 * comparing since that may differ between stations taking
	 * part in the same mesh.
	 */
	return memcmp(ie + 2, meshcfg, IEEE80211_MESH_CONFIG_LEN - 2) == 0;
}

static int cmp_bss(struct cfg80211_bss *a,
		   struct cfg80211_bss *b)
{
	int r;

	if (a->channel != b->channel)
		return b->channel->center_freq - a->channel->center_freq;

	r = memcmp(a->bssid, b->bssid, ETH_ALEN);
	if (r)
		return r;

	if (is_zero_ether_addr(a->bssid)) {
		r = cmp_ies(WLAN_EID_MESH_ID,
			    a->information_elements,
			    a->len_information_elements,
			    b->information_elements,
			    b->len_information_elements);
		if (r)
			return r;
		return cmp_ies(WLAN_EID_MESH_CONFIG,
			       a->information_elements,
			       a->len_information_elements,
			       b->information_elements,
			       b->len_information_elements);
	}

	return cmp_ies(WLAN_EID_SSID,
		       a->information_elements,
		       a->len_information_elements,
		       b->information_elements,
		       b->len_information_elements);
}

struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
				      struct ieee80211_channel *channel,
				      const u8 *bssid,
				      const u8 *ssid, size_t ssid_len,
				      u16 capa_mask, u16 capa_val)
{
	struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
	struct cfg80211_internal_bss *bss, *res = NULL;

	spin_lock_bh(&dev->bss_lock);

	list_for_each_entry(bss, &dev->bss_list, list) {
		if ((bss->pub.capability & capa_mask) != capa_val)
			continue;
		if (channel && bss->pub.channel != channel)
			continue;
		if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
			res = bss;
			kref_get(&res->ref);
			break;
		}
	}

	spin_unlock_bh(&dev->bss_lock);
	if (!res)
		return NULL;
	return &res->pub;
}
EXPORT_SYMBOL(cfg80211_get_bss);

struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
				       struct ieee80211_channel *channel,
				       const u8 *meshid, size_t meshidlen,
				       const u8 *meshcfg)
{
	struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
	struct cfg80211_internal_bss *bss, *res = NULL;

	spin_lock_bh(&dev->bss_lock);

	list_for_each_entry(bss, &dev->bss_list, list) {
		if (channel && bss->pub.channel != channel)
			continue;
		if (is_mesh(&bss->pub, meshid, meshidlen, meshcfg)) {
			res = bss;
			kref_get(&res->ref);
			break;
		}
	}

	spin_unlock_bh(&dev->bss_lock);
	if (!res)
		return NULL;
	return &res->pub;
}
EXPORT_SYMBOL(cfg80211_get_mesh);


static void rb_insert_bss(struct cfg80211_registered_device *dev,
			  struct cfg80211_internal_bss *bss)
{
	struct rb_node **p = &dev->bss_tree.rb_node;
	struct rb_node *parent = NULL;
	struct cfg80211_internal_bss *tbss;
	int cmp;

	while (*p) {
		parent = *p;
		tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);

		cmp = cmp_bss(&bss->pub, &tbss->pub);

		if (WARN_ON(!cmp)) {
			/* will sort of leak this BSS */
			return;
		}

		if (cmp < 0)
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}

	rb_link_node(&bss->rbn, parent, p);
	rb_insert_color(&bss->rbn, &dev->bss_tree);
}

static struct cfg80211_internal_bss *
rb_find_bss(struct cfg80211_registered_device *dev,
	    struct cfg80211_internal_bss *res)
{
	struct rb_node *n = dev->bss_tree.rb_node;
	struct cfg80211_internal_bss *bss;
	int r;

	while (n) {
		bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
		r = cmp_bss(&res->pub, &bss->pub);

		if (r == 0)
			return bss;
		else if (r < 0)
			n = n->rb_left;
		else
			n = n->rb_right;
	}

	return NULL;
}

static struct cfg80211_internal_bss *
cfg80211_bss_update(struct cfg80211_registered_device *dev,
		    struct cfg80211_internal_bss *res,
		    bool overwrite)
{
	struct cfg80211_internal_bss *found = NULL;
	const u8 *meshid, *meshcfg;

	/*
	 * The reference to "res" is donated to this function.
	 */

	if (WARN_ON(!res->pub.channel)) {
		kref_put(&res->ref, bss_release);
		return NULL;
	}

	res->ts = jiffies;

	if (is_zero_ether_addr(res->pub.bssid)) {
		/* must be mesh, verify */
		meshid = find_ie(WLAN_EID_MESH_ID, res->pub.information_elements,
				 res->pub.len_information_elements);
		meshcfg = find_ie(WLAN_EID_MESH_CONFIG,
				  res->pub.information_elements,
				  res->pub.len_information_elements);
		if (!meshid || !meshcfg ||
		    meshcfg[1] != IEEE80211_MESH_CONFIG_LEN) {
			/* bogus mesh */
			kref_put(&res->ref, bss_release);
			return NULL;
		}
	}

	spin_lock_bh(&dev->bss_lock);

	found = rb_find_bss(dev, res);

	if (found) {
		found->pub.beacon_interval = res->pub.beacon_interval;
		found->pub.tsf = res->pub.tsf;
		found->pub.signal = res->pub.signal;
		found->pub.capability = res->pub.capability;
		found->ts = res->ts;

		/* overwrite IEs */
		if (overwrite) {
			size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
			size_t ielen = res->pub.len_information_elements;

			if (!found->ies_allocated && ksize(found) >= used + ielen) {
				memcpy(found->pub.information_elements,
				       res->pub.information_elements, ielen);
				found->pub.len_information_elements = ielen;
			} else {
				u8 *ies = found->pub.information_elements;

				if (found->ies_allocated)
					ies = krealloc(ies, ielen, GFP_ATOMIC);
				else
					ies = kmalloc(ielen, GFP_ATOMIC);

				if (ies) {
					memcpy(ies, res->pub.information_elements, ielen);
					found->ies_allocated = true;
					found->pub.information_elements = ies;
					found->pub.len_information_elements = ielen;
				}
			}
		}

		kref_put(&res->ref, bss_release);
	} else {
		/* this "consumes" the reference */
		list_add_tail(&res->list, &dev->bss_list);
		rb_insert_bss(dev, res);
		found = res;
	}

	dev->bss_generation++;
	spin_unlock_bh(&dev->bss_lock);

	kref_get(&found->ref);
	return found;
}

struct cfg80211_bss*
cfg80211_inform_bss(struct wiphy *wiphy,
		    struct ieee80211_channel *channel,
		    const u8 *bssid,
		    u64 timestamp, u16 capability, u16 beacon_interval,
		    const u8 *ie, size_t ielen,
		    s32 signal, gfp_t gfp)
{
	struct cfg80211_internal_bss *res;
	size_t privsz;

	if (WARN_ON(!wiphy))
		return NULL;

	privsz = wiphy->bss_priv_size;

	if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
			(signal < 0 || signal > 100)))
		return NULL;

	res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
	if (!res)
		return NULL;

	memcpy(res->pub.bssid, bssid, ETH_ALEN);
	res->pub.channel = channel;
	res->pub.signal = signal;
	res->pub.tsf = timestamp;
	res->pub.beacon_interval = beacon_interval;
	res->pub.capability = capability;
	/* point to after the private area */
	res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
	memcpy(res->pub.information_elements, ie, ielen);
	res->pub.len_information_elements = ielen;

	kref_init(&res->ref);

	res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, 0);
	if (!res)
		return NULL;

	if (res->pub.capability & WLAN_CAPABILITY_ESS)
		regulatory_hint_found_beacon(wiphy, channel, gfp);

	/* cfg80211_bss_update gives us a referenced result */
	return &res->pub;
}
EXPORT_SYMBOL(cfg80211_inform_bss);

struct cfg80211_bss *
cfg80211_inform_bss_frame(struct wiphy *wiphy,
			  struct ieee80211_channel *channel,
			  struct ieee80211_mgmt *mgmt, size_t len,
			  s32 signal, gfp_t gfp)
{
	struct cfg80211_internal_bss *res;
	size_t ielen = len - offsetof(struct ieee80211_mgmt,
				      u.probe_resp.variable);
	bool overwrite;
	size_t privsz = wiphy->bss_priv_size;

	if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
	            (signal < 0 || signal > 100)))
		return NULL;

	if (WARN_ON(!mgmt || !wiphy ||
		    len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
		return NULL;

	res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
	if (!res)
		return NULL;

	memcpy(res->pub.bssid, mgmt->bssid, ETH_ALEN);
	res->pub.channel = channel;
	res->pub.signal = signal;
	res->pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
	res->pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
	res->pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
	/* point to after the private area */
	res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
	memcpy(res->pub.information_elements, mgmt->u.probe_resp.variable, ielen);
	res->pub.len_information_elements = ielen;

	kref_init(&res->ref);

	overwrite = ieee80211_is_probe_resp(mgmt->frame_control);

	res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, overwrite);
	if (!res)
		return NULL;

	if (res->pub.capability & WLAN_CAPABILITY_ESS)
		regulatory_hint_found_beacon(wiphy, channel, gfp);

	/* cfg80211_bss_update gives us a referenced result */
	return &res->pub;
}
EXPORT_SYMBOL(cfg80211_inform_bss_frame);

void cfg80211_put_bss(struct cfg80211_bss *pub)
{
	struct cfg80211_internal_bss *bss;

	if (!pub)
		return;

	bss = container_of(pub, struct cfg80211_internal_bss, pub);
	kref_put(&bss->ref, bss_release);
}
EXPORT_SYMBOL(cfg80211_put_bss);

void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
{
	struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
	struct cfg80211_internal_bss *bss;

	if (WARN_ON(!pub))
		return;

	bss = container_of(pub, struct cfg80211_internal_bss, pub);

	spin_lock_bh(&dev->bss_lock);

	list_del(&bss->list);
	rb_erase(&bss->rbn, &dev->bss_tree);

	spin_unlock_bh(&dev->bss_lock);

	kref_put(&bss->ref, bss_release);
}
EXPORT_SYMBOL(cfg80211_unlink_bss);

void cfg80211_hold_bss(struct cfg80211_bss *pub)
{
	struct cfg80211_internal_bss *bss;

	if (!pub)
		return;

	bss = container_of(pub, struct cfg80211_internal_bss, pub);
	bss->hold = true;
}
EXPORT_SYMBOL(cfg80211_hold_bss);

void cfg80211_unhold_bss(struct cfg80211_bss *pub)
{
	struct cfg80211_internal_bss *bss;

	if (!pub)
		return;

	bss = container_of(pub, struct cfg80211_internal_bss, pub);
	bss->hold = false;
}
EXPORT_SYMBOL(cfg80211_unhold_bss);

#ifdef CONFIG_WIRELESS_EXT
int cfg80211_wext_siwscan(struct net_device *dev,
			  struct iw_request_info *info,
			  union iwreq_data *wrqu, char *extra)
{
	struct cfg80211_registered_device *rdev;
	struct wiphy *wiphy;
	struct iw_scan_req *wreq = NULL;
	struct cfg80211_scan_request *creq;
	int i, err, n_channels = 0;
	enum ieee80211_band band;

	if (!netif_running(dev))
		return -ENETDOWN;

	rdev = cfg80211_get_dev_from_ifindex(dev->ifindex);

	if (IS_ERR(rdev))
		return PTR_ERR(rdev);

	if (rdev->scan_req) {
		err = -EBUSY;
		goto out;
	}

	wiphy = &rdev->wiphy;

	for (band = 0; band < IEEE80211_NUM_BANDS; band++)
		if (wiphy->bands[band])
			n_channels += wiphy->bands[band]->n_channels;

	creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
		       n_channels * sizeof(void *),
		       GFP_ATOMIC);
	if (!creq) {
		err = -ENOMEM;
		goto out;
	}

	creq->wiphy = wiphy;
	creq->ifidx = dev->ifindex;
	creq->ssids = (void *)(creq + 1);
	creq->channels = (void *)(creq->ssids + 1);
	creq->n_channels = n_channels;
	creq->n_ssids = 1;

	/* all channels */
	i = 0;
	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
		int j;
		if (!wiphy->bands[band])
			continue;
		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
			creq->channels[i] = &wiphy->bands[band]->channels[j];
			i++;
		}
	}

	/* translate scan request */
	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
		wreq = (struct iw_scan_req *)extra;

		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
				return -EINVAL;
			memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
			creq->ssids[0].ssid_len = wreq->essid_len;
		}
		if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
			creq->n_ssids = 0;
	}

	rdev->scan_req = creq;
	err = rdev->ops->scan(wiphy, dev, creq);
	if (err) {
		rdev->scan_req = NULL;
		kfree(creq);
	}
 out:
	cfg80211_put_dev(rdev);
	return err;
}
EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);

static void ieee80211_scan_add_ies(struct iw_request_info *info,
				   struct cfg80211_bss *bss,
				   char **current_ev, char *end_buf)
{
	u8 *pos, *end, *next;
	struct iw_event iwe;

	if (!bss->information_elements ||
	    !bss->len_information_elements)
		return;

	/*
	 * If needed, fragment the IEs buffer (at IE boundaries) into short
	 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
	 */
	pos = bss->information_elements;
	end = pos + bss->len_information_elements;

	while (end - pos > IW_GENERIC_IE_MAX) {
		next = pos + 2 + pos[1];
		while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
			next = next + 2 + next[1];

		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = next - pos;
		*current_ev = iwe_stream_add_point(info, *current_ev,
						   end_buf, &iwe, pos);

		pos = next;
	}

	if (end > pos) {
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = end - pos;
		*current_ev = iwe_stream_add_point(info, *current_ev,
						   end_buf, &iwe, pos);
	}
}

static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
{
	unsigned long end = jiffies;

	if (end >= start)
		return jiffies_to_msecs(end - start);

	return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
}

static char *
ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
	      struct cfg80211_internal_bss *bss, char *current_ev,
	      char *end_buf)
{
	struct iw_event iwe;
	u8 *buf, *cfg, *p;
	u8 *ie = bss->pub.information_elements;
	int rem = bss->pub.len_information_elements, i, sig;
	bool ismesh = false;

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWAP;
	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
	memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
					  IW_EV_ADDR_LEN);

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
	iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
	iwe.u.freq.e = 0;
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
					  IW_EV_FREQ_LEN);

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
	iwe.u.freq.m = bss->pub.channel->center_freq;
	iwe.u.freq.e = 6;
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
					  IW_EV_FREQ_LEN);

	if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVQUAL;
		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
				     IW_QUAL_NOISE_INVALID |
				     IW_QUAL_QUAL_UPDATED;
		switch (wiphy->signal_type) {
		case CFG80211_SIGNAL_TYPE_MBM:
			sig = bss->pub.signal / 100;
			iwe.u.qual.level = sig;
			iwe.u.qual.updated |= IW_QUAL_DBM;
			if (sig < -110)		/* rather bad */
				sig = -110;
			else if (sig > -40)	/* perfect */
				sig = -40;
			/* will give a range of 0 .. 70 */
			iwe.u.qual.qual = sig + 110;
			break;
		case CFG80211_SIGNAL_TYPE_UNSPEC:
			iwe.u.qual.level = bss->pub.signal;
			/* will give range 0 .. 100 */
			iwe.u.qual.qual = bss->pub.signal;
			break;
		default:
			/* not reached */
			break;
		}
		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
						  &iwe, IW_EV_QUAL_LEN);
	}

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWENCODE;
	if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
	else
		iwe.u.data.flags = IW_ENCODE_DISABLED;
	iwe.u.data.length = 0;
	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
					  &iwe, "");

	while (rem >= 2) {
		/* invalid data */
		if (ie[1] > rem - 2)
			break;

		switch (ie[0]) {
		case WLAN_EID_SSID:
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = SIOCGIWESSID;
			iwe.u.data.length = ie[1];
			iwe.u.data.flags = 1;
			current_ev = iwe_stream_add_point(info, current_ev, end_buf,
							  &iwe, ie + 2);
			break;
		case WLAN_EID_MESH_ID:
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = SIOCGIWESSID;
			iwe.u.data.length = ie[1];
			iwe.u.data.flags = 1;
			current_ev = iwe_stream_add_point(info, current_ev, end_buf,
							  &iwe, ie + 2);
			break;
		case WLAN_EID_MESH_CONFIG:
			ismesh = true;
			if (ie[1] != IEEE80211_MESH_CONFIG_LEN)
				break;
			buf = kmalloc(50, GFP_ATOMIC);
			if (!buf)
				break;
			cfg = ie + 2;
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = IWEVCUSTOM;
			sprintf(buf, "Mesh network (version %d)", cfg[0]);
			iwe.u.data.length = strlen(buf);
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
							  &iwe, buf);
			sprintf(buf, "Path Selection Protocol ID: "
				"0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
							cfg[4]);
			iwe.u.data.length = strlen(buf);
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
							  &iwe, buf);
			sprintf(buf, "Path Selection Metric ID: "
				"0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
							cfg[8]);
			iwe.u.data.length = strlen(buf);
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
							  &iwe, buf);
			sprintf(buf, "Congestion Control Mode ID: "
				"0x%02X%02X%02X%02X", cfg[9], cfg[10],
							cfg[11], cfg[12]);
			iwe.u.data.length = strlen(buf);
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
							  &iwe, buf);
			sprintf(buf, "Channel Precedence: "
				"0x%02X%02X%02X%02X", cfg[13], cfg[14],
							cfg[15], cfg[16]);
			iwe.u.data.length = strlen(buf);
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
							  &iwe, buf);
			kfree(buf);
			break;
		case WLAN_EID_SUPP_RATES:
		case WLAN_EID_EXT_SUPP_RATES:
			/* display all supported rates in readable format */
			p = current_ev + iwe_stream_lcp_len(info);

			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = SIOCGIWRATE;
			/* Those two flags are ignored... */
			iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;

			for (i = 0; i < ie[1]; i++) {
				iwe.u.bitrate.value =
					((ie[i + 2] & 0x7f) * 500000);
				p = iwe_stream_add_value(info, current_ev, p,
						end_buf, &iwe, IW_EV_PARAM_LEN);
			}
			current_ev = p;
			break;
		}
		rem -= ie[1] + 2;
		ie += ie[1] + 2;
	}

	if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
	    || ismesh) {
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = SIOCGIWMODE;
		if (ismesh)
			iwe.u.mode = IW_MODE_MESH;
		else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
			iwe.u.mode = IW_MODE_MASTER;
		else
			iwe.u.mode = IW_MODE_ADHOC;
		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
						  &iwe, IW_EV_UINT_LEN);
	}

	buf = kmalloc(30, GFP_ATOMIC);
	if (buf) {
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVCUSTOM;
		sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf));
		iwe.u.data.length = strlen(buf);
		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
						  &iwe, buf);
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVCUSTOM;
		sprintf(buf, " Last beacon: %ums ago",
			elapsed_jiffies_msecs(bss->ts));
		iwe.u.data.length = strlen(buf);
		current_ev = iwe_stream_add_point(info, current_ev,
						  end_buf, &iwe, buf);
		kfree(buf);
	}

	ieee80211_scan_add_ies(info, &bss->pub, &current_ev, end_buf);

	return current_ev;
}


static int ieee80211_scan_results(struct cfg80211_registered_device *dev,
				  struct iw_request_info *info,
				  char *buf, size_t len)
{
	char *current_ev = buf;
	char *end_buf = buf + len;
	struct cfg80211_internal_bss *bss;

	spin_lock_bh(&dev->bss_lock);
	cfg80211_bss_expire(dev);

	list_for_each_entry(bss, &dev->bss_list, list) {
		if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
			spin_unlock_bh(&dev->bss_lock);
			return -E2BIG;
		}
		current_ev = ieee80211_bss(&dev->wiphy, info, bss,
					   current_ev, end_buf);
	}
	spin_unlock_bh(&dev->bss_lock);
	return current_ev - buf;
}


int cfg80211_wext_giwscan(struct net_device *dev,
			  struct iw_request_info *info,
			  struct iw_point *data, char *extra)
{
	struct cfg80211_registered_device *rdev;
	int res;

	if (!netif_running(dev))
		return -ENETDOWN;

	rdev = cfg80211_get_dev_from_ifindex(dev->ifindex);

	if (IS_ERR(rdev))
		return PTR_ERR(rdev);

	if (rdev->scan_req) {
		res = -EAGAIN;
		goto out;
	}

	res = ieee80211_scan_results(rdev, info, extra, data->length);
	data->length = 0;
	if (res >= 0) {
		data->length = res;
		res = 0;
	}

 out:
	cfg80211_put_dev(rdev);
	return res;
}
EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
#endif
