/*
 * This file contains our _wx handlers. Make sure you EXPORT_SYMBOL_GPL them
 *
 * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
 *                          Joseph Jezak <josejx@gentoo.org>
 *                          Larry Finger <Larry.Finger@lwfinger.net>
 *                          Danny van Dyk <kugelfang@gentoo.org>
 *                          Michael Buesch <mbuesch@freenet.de>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 * The full GNU General Public License is included in this distribution in the
 * file called COPYING.
 */

#include "ieee80211softmac_priv.h"

#include <net/iw_handler.h>
/* for is_broadcast_ether_addr and is_zero_ether_addr */
#include <linux/etherdevice.h>

int
ieee80211softmac_wx_trigger_scan(struct net_device *net_dev,
				 struct iw_request_info *info,
				 union iwreq_data *data,
				 char *extra)
{
	struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
	return ieee80211softmac_start_scan(sm);
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan);


/* if we're still scanning, return -EAGAIN so that userspace tools
 * can get the complete scan results, otherwise return 0. */
int
ieee80211softmac_wx_get_scan_results(struct net_device *net_dev,
				     struct iw_request_info *info,
				     union iwreq_data *data,
				     char *extra)
{
	unsigned long flags;
	struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);

	spin_lock_irqsave(&sm->lock, flags);
	if (sm->scanning) {
		spin_unlock_irqrestore(&sm->lock, flags);
		return -EAGAIN;
	}
	spin_unlock_irqrestore(&sm->lock, flags);
	return ieee80211_wx_get_scan(sm->ieee, info, data, extra);
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results);

int
ieee80211softmac_wx_set_essid(struct net_device *net_dev,
			      struct iw_request_info *info,
			      union iwreq_data *data,
			      char *extra)
{
	struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
	struct ieee80211softmac_auth_queue_item *authptr;
	int length = 0;
	DECLARE_MAC_BUF(mac);

check_assoc_again:
	mutex_lock(&sm->associnfo.mutex);
	if((sm->associnfo.associating || sm->associnfo.associated) &&
	   (data->essid.flags && data->essid.length)) {
		dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
		/* Cancel assoc work */
		cancel_delayed_work(&sm->associnfo.work);
		/* We don't have to do this, but it's a little cleaner */
		list_for_each_entry(authptr, &sm->auth_queue, list)
			cancel_delayed_work(&authptr->work);
		sm->associnfo.bssvalid = 0;
		sm->associnfo.bssfixed = 0;
		sm->associnfo.associating = 0;
		sm->associnfo.associated = 0;
		/* We must unlock to avoid deadlocks with the assoc workqueue
		 * on the associnfo.mutex */
		mutex_unlock(&sm->associnfo.mutex);
		flush_workqueue(sm->wq);
		/* Avoid race! Check assoc status again. Maybe someone started an
		 * association while we flushed. */
		goto check_assoc_again;
	}

	sm->associnfo.static_essid = 0;
	sm->associnfo.assoc_wait = 0;

	if (data->essid.flags && data->essid.length) {
		length = min((int)data->essid.length, IW_ESSID_MAX_SIZE);
		if (length) {
			memcpy(sm->associnfo.req_essid.data, extra, length);
			sm->associnfo.static_essid = 1;
		}
	}

	/* set our requested ESSID length.
	 * If applicable, we have already copied the data in */
	sm->associnfo.req_essid.len = length;

	sm->associnfo.associating = 1;
	/* queue lower level code to do work (if necessary) */
	queue_delayed_work(sm->wq, &sm->associnfo.work, 0);

	mutex_unlock(&sm->associnfo.mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);

int
ieee80211softmac_wx_get_essid(struct net_device *net_dev,
			      struct iw_request_info *info,
			      union iwreq_data *data,
			      char *extra)
{
	struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);

	mutex_lock(&sm->associnfo.mutex);
	/* If all fails, return ANY (empty) */
	data->essid.length = 0;
	data->essid.flags = 0;  /* active */

	/* If we have a statically configured ESSID then return it */
	if (sm->associnfo.static_essid) {
		data->essid.length = sm->associnfo.req_essid.len;
		data->essid.flags = 1;  /* active */
		memcpy(extra, sm->associnfo.req_essid.data, sm->associnfo.req_essid.len);
		dprintk(KERN_INFO PFX "Getting essid from req_essid\n");
	} else if (sm->associnfo.associated || sm->associnfo.associating) {
	/* If we're associating/associated, return that */
		data->essid.length = sm->associnfo.associate_essid.len;
		data->essid.flags = 1;  /* active */
		memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
		dprintk(KERN_INFO PFX "Getting essid from associate_essid\n");
	}
	mutex_unlock(&sm->associnfo.mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);

int
ieee80211softmac_wx_set_rate(struct net_device *net_dev,
			     struct iw_request_info *info,
			     union iwreq_data *data,
			     char *extra)
{
	struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
	struct ieee80211_device *ieee = mac->ieee;
	unsigned long flags;
	s32 in_rate = data->bitrate.value;
	u8 rate;
	int is_ofdm = 0;
	int err = -EINVAL;

	if (in_rate == -1) {
		if (ieee->modulation & IEEE80211_OFDM_MODULATION)
			in_rate = 24000000;
		else
			in_rate = 11000000;
	}

	switch (in_rate) {
	case 1000000:
		rate = IEEE80211_CCK_RATE_1MB;
		break;
	case 2000000:
		rate = IEEE80211_CCK_RATE_2MB;
		break;
	case 5500000:
		rate = IEEE80211_CCK_RATE_5MB;
		break;
	case 11000000:
		rate = IEEE80211_CCK_RATE_11MB;
		break;
	case 6000000:
		rate = IEEE80211_OFDM_RATE_6MB;
		is_ofdm = 1;
		break;
	case 9000000:
		rate = IEEE80211_OFDM_RATE_9MB;
		is_ofdm = 1;
		break;
	case 12000000:
		rate = IEEE80211_OFDM_RATE_12MB;
		is_ofdm = 1;
		break;
	case 18000000:
		rate = IEEE80211_OFDM_RATE_18MB;
		is_ofdm = 1;
		break;
	case 24000000:
		rate = IEEE80211_OFDM_RATE_24MB;
		is_ofdm = 1;
		break;
	case 36000000:
		rate = IEEE80211_OFDM_RATE_36MB;
		is_ofdm = 1;
		break;
	case 48000000:
		rate = IEEE80211_OFDM_RATE_48MB;
		is_ofdm = 1;
		break;
	case 54000000:
		rate = IEEE80211_OFDM_RATE_54MB;
		is_ofdm = 1;
		break;
	default:
		goto out;
	}

	spin_lock_irqsave(&mac->lock, flags);

	/* Check if correct modulation for this PHY. */
	if (is_ofdm && !(ieee->modulation & IEEE80211_OFDM_MODULATION))
		goto out_unlock;

	mac->txrates.user_rate = rate;
	ieee80211softmac_recalc_txrates(mac);
	err = 0;

out_unlock:
	spin_unlock_irqrestore(&mac->lock, flags);
out:
	return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_rate);

int
ieee80211softmac_wx_get_rate(struct net_device *net_dev,
			     struct iw_request_info *info,
			     union iwreq_data *data,
			     char *extra)
{
	struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
	unsigned long flags;
	int err = -EINVAL;

	spin_lock_irqsave(&mac->lock, flags);

	if (unlikely(!mac->running)) {
		err = -ENODEV;
		goto out_unlock;
	}

	switch (mac->txrates.default_rate) {
	case IEEE80211_CCK_RATE_1MB:
		data->bitrate.value = 1000000;
		break;
	case IEEE80211_CCK_RATE_2MB:
		data->bitrate.value = 2000000;
		break;
	case IEEE80211_CCK_RATE_5MB:
		data->bitrate.value = 5500000;
		break;
	case IEEE80211_CCK_RATE_11MB:
		data->bitrate.value = 11000000;
		break;
	case IEEE80211_OFDM_RATE_6MB:
		data->bitrate.value = 6000000;
		break;
	case IEEE80211_OFDM_RATE_9MB:
		data->bitrate.value = 9000000;
		break;
	case IEEE80211_OFDM_RATE_12MB:
		data->bitrate.value = 12000000;
		break;
	case IEEE80211_OFDM_RATE_18MB:
		data->bitrate.value = 18000000;
		break;
	case IEEE80211_OFDM_RATE_24MB:
		data->bitrate.value = 24000000;
		break;
	case IEEE80211_OFDM_RATE_36MB:
		data->bitrate.value = 36000000;
		break;
	case IEEE80211_OFDM_RATE_48MB:
		data->bitrate.value = 48000000;
		break;
	case IEEE80211_OFDM_RATE_54MB:
		data->bitrate.value = 54000000;
		break;
	default:
		assert(0);
		goto out_unlock;
	}
	err = 0;
out_unlock:
	spin_unlock_irqrestore(&mac->lock, flags);

	return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_rate);

int
ieee80211softmac_wx_get_wap(struct net_device *net_dev,
			    struct iw_request_info *info,
			    union iwreq_data *data,
			    char *extra)
{
	struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
	int err = 0;

	mutex_lock(&mac->associnfo.mutex);
	if (mac->associnfo.bssvalid)
		memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
	else
		memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
	data->ap_addr.sa_family = ARPHRD_ETHER;
	mutex_unlock(&mac->associnfo.mutex);

	return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);

int
ieee80211softmac_wx_set_wap(struct net_device *net_dev,
			    struct iw_request_info *info,
			    union iwreq_data *data,
			    char *extra)
{
	struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);

	/* sanity check */
	if (data->ap_addr.sa_family != ARPHRD_ETHER) {
		return -EINVAL;
	}

	mutex_lock(&mac->associnfo.mutex);
	if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
		/* the bssid we have is not to be fixed any longer,
		 * and we should reassociate to the best AP. */
		mac->associnfo.bssfixed = 0;
		/* force reassociation */
		mac->associnfo.bssvalid = 0;
		if (mac->associnfo.associated)
			queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
	} else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
		/* the bssid we have is no longer fixed */
		mac->associnfo.bssfixed = 0;
	} else {
		if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
			if (mac->associnfo.associating || mac->associnfo.associated) {
			/* bssid unchanged and associated or associating - just return */
				goto out;
			}
		} else {
			/* copy new value in data->ap_addr.sa_data to bssid */
			memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN);
		}
		/* tell the other code that this bssid should be used no matter what */
		mac->associnfo.bssfixed = 1;
		/* queue associate if new bssid or (old one again and not associated) */
		queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
	}

 out:
	mutex_unlock(&mac->associnfo.mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);

int
ieee80211softmac_wx_set_genie(struct net_device *dev,
			      struct iw_request_info *info,
			      union iwreq_data *wrqu,
			      char *extra)
{
	struct ieee80211softmac_device *mac = ieee80211_priv(dev);
	unsigned long flags;
	int err = 0;
	char *buf;
	int i;

	mutex_lock(&mac->associnfo.mutex);
	spin_lock_irqsave(&mac->lock, flags);
	/* bleh. shouldn't be locked for that kmalloc... */

	if (wrqu->data.length) {
		if ((wrqu->data.length < 2) || (extra[1]+2 != wrqu->data.length)) {
			/* this is an IE, so the length must be
			 * correct. Is it possible though that
			 * more than one IE is passed in?
			 */
			err = -EINVAL;
			goto out;
		}
		if (mac->wpa.IEbuflen <= wrqu->data.length) {
			buf = kmalloc(wrqu->data.length, GFP_ATOMIC);
			if (!buf) {
				err = -ENOMEM;
				goto out;
			}
			kfree(mac->wpa.IE);
			mac->wpa.IE = buf;
			mac->wpa.IEbuflen = wrqu->data.length;
		}
		memcpy(mac->wpa.IE, extra, wrqu->data.length);
		dprintk(KERN_INFO PFX "generic IE set to ");
		for (i=0;i<wrqu->data.length;i++)
			dprintk("%.2x", (u8)mac->wpa.IE[i]);
		dprintk("\n");
		mac->wpa.IElen = wrqu->data.length;
	} else {
		kfree(mac->wpa.IE);
		mac->wpa.IE = NULL;
		mac->wpa.IElen = 0;
		mac->wpa.IEbuflen = 0;
	}

 out:
	spin_unlock_irqrestore(&mac->lock, flags);
	mutex_unlock(&mac->associnfo.mutex);

	return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);

int
ieee80211softmac_wx_get_genie(struct net_device *dev,
			      struct iw_request_info *info,
			      union iwreq_data *wrqu,
			      char *extra)
{
	struct ieee80211softmac_device *mac = ieee80211_priv(dev);
	unsigned long flags;
	int err = 0;
	int space = wrqu->data.length;

	mutex_lock(&mac->associnfo.mutex);
	spin_lock_irqsave(&mac->lock, flags);

	wrqu->data.length = 0;

	if (mac->wpa.IE && mac->wpa.IElen) {
		wrqu->data.length = mac->wpa.IElen;
		if (mac->wpa.IElen <= space)
			memcpy(extra, mac->wpa.IE, mac->wpa.IElen);
		else
			err = -E2BIG;
	}
	spin_unlock_irqrestore(&mac->lock, flags);
	mutex_unlock(&mac->associnfo.mutex);

	return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);

int
ieee80211softmac_wx_set_mlme(struct net_device *dev,
			     struct iw_request_info *info,
			     union iwreq_data *wrqu,
			     char *extra)
{
	struct ieee80211softmac_device *mac = ieee80211_priv(dev);
	struct iw_mlme *mlme = (struct iw_mlme *)extra;
	u16 reason = mlme->reason_code;
	struct ieee80211softmac_network *net;
	int err = -EINVAL;

	mutex_lock(&mac->associnfo.mutex);

	if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
		printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
		goto out;
	}

	switch (mlme->cmd) {
	case IW_MLME_DEAUTH:
		net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
		if (!net) {
			printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
			goto out;
		}
		err =  ieee80211softmac_deauth_req(mac, net, reason);
		goto out;
	case IW_MLME_DISASSOC:
		ieee80211softmac_send_disassoc_req(mac, reason);
		mac->associnfo.associated = 0;
		mac->associnfo.associating = 0;
		err = 0;
		goto out;
	default:
		err = -EOPNOTSUPP;
	}

out:
	mutex_unlock(&mac->associnfo.mutex);

	return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);
