/* 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, add also
	 *        zd1211B, if we support it.
	 */
	strlcpy(req->name, "802.11g zd1211", IFNAMSIZ);
	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(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);
}
