/* zd_netdev.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <net/ieee80211.h>
#include <net/ieee80211softmac.h>
#include <net/ieee80211softmac_wx.h>
#include <net/iw_handler.h>

#include "zd_def.h"
#include "zd_netdev.h"
#include "zd_mac.h"
#include "zd_ieee80211.h"

/* Region 0 means reset regdomain to default. */
static int zd_set_regdomain(struct net_device *netdev,
	                    struct iw_request_info *info,
			    union iwreq_data *req, char *extra)
{
	const u8 *regdomain = (u8 *)req;
	return zd_mac_set_regdomain(zd_netdev_mac(netdev), *regdomain);
}

static int zd_get_regdomain(struct net_device *netdev,
	                    struct iw_request_info *info,
			    union iwreq_data *req, char *extra)
{
	u8 *regdomain = (u8 *)req;
	if (!regdomain)
		return -EINVAL;
	*regdomain = zd_mac_get_regdomain(zd_netdev_mac(netdev));
	return 0;
}

static const struct iw_priv_args zd_priv_args[] = {
	{
		.cmd = ZD_PRIV_SET_REGDOMAIN,
		.set_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
		.name = "set_regdomain",
	},
	{
		.cmd = ZD_PRIV_GET_REGDOMAIN,
		.get_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
		.name = "get_regdomain",
	},
};

#define PRIV_OFFSET(x) [(x)-SIOCIWFIRSTPRIV]

static const iw_handler zd_priv_handler[] = {
	PRIV_OFFSET(ZD_PRIV_SET_REGDOMAIN) = zd_set_regdomain,
	PRIV_OFFSET(ZD_PRIV_GET_REGDOMAIN) = zd_get_regdomain,
};

static int iw_get_name(struct net_device *netdev,
	               struct iw_request_info *info,
		       union iwreq_data *req, char *extra)
{
	/* FIXME: check whether 802.11a will also supported */
	strlcpy(req->name, "IEEE 802.11b/g", IFNAMSIZ);
	return 0;
}

static int iw_get_nick(struct net_device *netdev,
	               struct iw_request_info *info,
		       union iwreq_data *req, char *extra)
{
	strcpy(extra, "zd1211");
	req->data.length = strlen(extra) + 1;
	req->data.flags = 1;
	return 0;
}

static int iw_set_freq(struct net_device *netdev,
	               struct iw_request_info *info,
		       union iwreq_data *req, char *extra)
{
	int r;
	struct zd_mac *mac = zd_netdev_mac(netdev);
	struct iw_freq *freq = &req->freq;
	u8 channel;

	r = zd_find_channel(&channel, freq);
	if (r < 0)
		return r;
	r = zd_mac_request_channel(mac, channel);
	return r;
}

static int iw_get_freq(struct net_device *netdev,
	           struct iw_request_info *info,
		   union iwreq_data *req, char *extra)
{
	int r;
	struct zd_mac *mac = zd_netdev_mac(netdev);
	struct iw_freq *freq = &req->freq;
	u8 channel;
	u8 flags;

	r = zd_mac_get_channel(mac, &channel, &flags);
	if (r)
		return r;

	freq->flags = (flags & MAC_FIXED_CHANNEL) ?
		      IW_FREQ_FIXED : IW_FREQ_AUTO;
	dev_dbg_f(zd_mac_dev(mac), "channel %s\n",
		  (flags & MAC_FIXED_CHANNEL) ? "fixed" : "auto");
	return zd_channel_to_freq(freq, channel);
}

static int iw_set_mode(struct net_device *netdev,
	               struct iw_request_info *info,
		       union iwreq_data *req, char *extra)
{
	return zd_mac_set_mode(zd_netdev_mac(netdev), req->mode);
}

static int iw_get_mode(struct net_device *netdev,
	               struct iw_request_info *info,
		       union iwreq_data *req, char *extra)
{
	return zd_mac_get_mode(zd_netdev_mac(netdev), &req->mode);
}

static int iw_get_range(struct net_device *netdev,
	               struct iw_request_info *info,
		       union iwreq_data *req, char *extra)
{
	struct iw_range *range = (struct iw_range *)extra;

	dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n");
	req->data.length = sizeof(*range);
	return zd_mac_get_range(zd_netdev_mac(netdev), range);
}

static int iw_set_encode(struct net_device *netdev,
			 struct iw_request_info *info,
			 union iwreq_data *data,
			 char *extra)
{
	return ieee80211_wx_set_encode(zd_netdev_ieee80211(netdev), info,
		data, extra);
}

static int iw_get_encode(struct net_device *netdev,
			 struct iw_request_info *info,
			 union iwreq_data *data,
			 char *extra)
{
	return ieee80211_wx_get_encode(zd_netdev_ieee80211(netdev), info,
		data, extra);
}

static int iw_set_encodeext(struct net_device *netdev,
			 struct iw_request_info *info,
			 union iwreq_data *data,
			 char *extra)
{
	return ieee80211_wx_set_encodeext(zd_netdev_ieee80211(netdev), info,
		data, extra);
}

static int iw_get_encodeext(struct net_device *netdev,
			 struct iw_request_info *info,
			 union iwreq_data *data,
			 char *extra)
{
	return ieee80211_wx_get_encodeext(zd_netdev_ieee80211(netdev), info,
		data, extra);
}

#define WX(x) [(x)-SIOCIWFIRST]

static const iw_handler zd_standard_iw_handlers[] = {
	WX(SIOCGIWNAME)		= iw_get_name,
	WX(SIOCGIWNICKN)	= iw_get_nick,
	WX(SIOCSIWFREQ)		= iw_set_freq,
	WX(SIOCGIWFREQ)		= iw_get_freq,
	WX(SIOCSIWMODE)		= iw_set_mode,
	WX(SIOCGIWMODE)		= iw_get_mode,
	WX(SIOCGIWRANGE)	= iw_get_range,
	WX(SIOCSIWENCODE)	= iw_set_encode,
	WX(SIOCGIWENCODE)	= iw_get_encode,
	WX(SIOCSIWENCODEEXT)	= iw_set_encodeext,
	WX(SIOCGIWENCODEEXT)	= iw_get_encodeext,
	WX(SIOCSIWAUTH)		= ieee80211_wx_set_auth,
	WX(SIOCGIWAUTH)		= ieee80211_wx_get_auth,
	WX(SIOCSIWSCAN)		= ieee80211softmac_wx_trigger_scan,
	WX(SIOCGIWSCAN)		= ieee80211softmac_wx_get_scan_results,
	WX(SIOCSIWESSID)	= ieee80211softmac_wx_set_essid,
	WX(SIOCGIWESSID)	= ieee80211softmac_wx_get_essid,
	WX(SIOCSIWAP)		= ieee80211softmac_wx_set_wap,
	WX(SIOCGIWAP)		= ieee80211softmac_wx_get_wap,
	WX(SIOCSIWRATE)		= ieee80211softmac_wx_set_rate,
	WX(SIOCGIWRATE)		= ieee80211softmac_wx_get_rate,
	WX(SIOCSIWGENIE)	= ieee80211softmac_wx_set_genie,
	WX(SIOCGIWGENIE)	= ieee80211softmac_wx_get_genie,
	WX(SIOCSIWMLME)		= ieee80211softmac_wx_set_mlme,
};

static const struct iw_handler_def iw_handler_def = {
	.standard		= zd_standard_iw_handlers,
	.num_standard		= ARRAY_SIZE(zd_standard_iw_handlers),
	.private		= zd_priv_handler,
	.num_private		= ARRAY_SIZE(zd_priv_handler),
	.private_args		= zd_priv_args,
	.num_private_args	= ARRAY_SIZE(zd_priv_args),
	.get_wireless_stats	= zd_mac_get_wireless_stats,
};

struct net_device *zd_netdev_alloc(struct usb_interface *intf)
{
	int r;
	struct net_device *netdev;
	struct zd_mac *mac;

	netdev = alloc_ieee80211softmac(sizeof(struct zd_mac));
	if (!netdev) {
		dev_dbg_f(&intf->dev, "out of memory\n");
		return NULL;
	}

	mac = zd_netdev_mac(netdev);
	r = zd_mac_init(mac, netdev, intf);
	if (r) {
		usb_set_intfdata(intf, NULL);
		free_ieee80211(netdev);
		return NULL;
	}

	SET_MODULE_OWNER(netdev);
	SET_NETDEV_DEV(netdev, &intf->dev);

	dev_dbg_f(&intf->dev, "netdev->flags %#06hx\n", netdev->flags);
	dev_dbg_f(&intf->dev, "netdev->features %#010lx\n", netdev->features);

	netdev->open = zd_mac_open;
	netdev->stop = zd_mac_stop;
	/* netdev->get_stats = */
	/* netdev->set_multicast_list = */
	netdev->set_mac_address = zd_mac_set_mac_address;
	netdev->wireless_handlers = &iw_handler_def;
	/* netdev->ethtool_ops = */

	return netdev;
}

void zd_netdev_free(struct net_device *netdev)
{
	if (!netdev)
		return;

	zd_mac_clear(zd_netdev_mac(netdev));
	free_ieee80211(netdev);
}

void zd_netdev_disconnect(struct net_device *netdev)
{
	unregister_netdev(netdev);
}
