/*
 * Copyright (c) 2007-2008 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/*                                                                      */
/*  Module Name : ioctl.c                                               */
/*                                                                      */
/*  Abstract                                                            */
/*      This module contains Linux wireless extension related functons. */
/*                                                                      */
/*  NOTES                                                               */
/*     Platform dependent.                                              */
/*                                                                      */
/************************************************************************/
#include <linux/module.h>
#include <linux/if_arp.h>
#include <linux/uaccess.h>

#include "usbdrv.h"

#define ZD_IOCTL_WPA			    (SIOCDEVPRIVATE + 1)
#define ZD_IOCTL_PARAM			    (SIOCDEVPRIVATE + 2)
#define ZD_IOCTL_GETWPAIE		    (SIOCDEVPRIVATE + 3)
#ifdef ZM_ENABLE_CENC
#define ZM_IOCTL_CENC               (SIOCDEVPRIVATE + 4)
#endif  /* ZM_ENABLE_CENC */
#define ZD_PARAM_ROAMING		    0x0001
#define ZD_PARAM_PRIVACY		    0x0002
#define ZD_PARAM_WPA			    0x0003
#define ZD_PARAM_COUNTERMEASURES	0x0004
#define ZD_PARAM_DROPUNENCRYPTED	0x0005
#define ZD_PARAM_AUTH_ALGS		    0x0006
#define ZD_PARAM_WPS_FILTER		    0x0007

#ifdef ZM_ENABLE_CENC
#define P80211_PACKET_CENCFLAG		0x0001
#endif  /* ZM_ENABLE_CENC */
#define P80211_PACKET_SETKEY     	0x0003

#define ZD_CMD_SET_ENCRYPT_KEY		0x0001
#define ZD_CMD_SET_MLME			    0x0002
#define ZD_CMD_SCAN_REQ			    0x0003
#define ZD_CMD_SET_GENERIC_ELEMENT	0x0004
#define ZD_CMD_GET_TSC			    0x0005

#define ZD_CRYPT_ALG_NAME_LEN		16
#define ZD_MAX_KEY_SIZE			    32
#define ZD_MAX_GENERIC_SIZE		    64

#include <net/iw_handler.h>

extern u16_t zfLnxGetVapId(zdev_t *dev);

static const u32_t channel_frequency_11A[] =
{
	/* Even element for Channel Number, Odd for Frequency */
	36, 5180,
	40, 5200,
	44, 5220,
	48, 5240,
	52, 5260,
	56, 5280,
	60, 5300,
	64, 5320,
	100, 5500,
	104, 5520,
	108, 5540,
	112, 5560,
	116, 5580,
	120, 5600,
	124, 5620,
	128, 5640,
	132, 5660,
	136, 5680,
	140, 5700,
	/**/
	184, 4920,
	188, 4940,
	192, 4960,
	196, 4980,
	8, 5040,
	12, 5060,
	16, 5080,
	34, 5170,
	38, 5190,
	42, 5210,
	46, 5230,
	/**/
	149, 5745,
	153, 5765,
	157, 5785,
	161, 5805,
	165, 5825
	/**/
};

int usbdrv_freq2chan(u32_t freq)
{
	/* 2.4G Hz */
	if (freq > 2400 && freq < 3000) {
		return ((freq-2412)/5) + 1;
	} else {
		u16_t ii;
		u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);

		for (ii = 1; ii < num_chan; ii += 2) {
			if (channel_frequency_11A[ii] == freq)
				return channel_frequency_11A[ii-1];
		}
	}

	return 0;
}

int usbdrv_chan2freq(int chan)
{
	int freq;

	/* If channel number is out of range */
	if (chan > 165 || chan <= 0)
		return -1;

	/* 2.4G band */
	if (chan >= 1 && chan <= 13) {
		freq = (2412 + (chan - 1) * 5);
			return freq;
	} else if (chan >= 36 && chan <= 165) {
		u16_t ii;
		u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);

		for (ii = 0; ii < num_chan; ii += 2) {
			if (channel_frequency_11A[ii] == chan)
				return channel_frequency_11A[ii+1];
		}

	/* Can't find desired frequency */
	if (ii == num_chan)
		return -1;
	}

	/* Can't find deisred frequency */
	return -1;
}

int usbdrv_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
{
	#ifdef ZM_HOSTAPD_SUPPORT
	/* struct usbdrv_private *macp = dev->ml_priv; */
	char essidbuf[IW_ESSID_MAX_SIZE+1];
	int i;

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

	memset(essidbuf, 0, sizeof(essidbuf));

	printk(KERN_ERR "usbdrv_ioctl_setessid\n");

	/* printk("ssidlen=%d\n", erq->length); //for any, it is 1. */
	if (erq->flags) {
		if (erq->length > (IW_ESSID_MAX_SIZE+1))
			return -E2BIG;

		if (copy_from_user(essidbuf, erq->pointer, erq->length))
			return -EFAULT;
	}

	/* zd_DisasocAll(2); */
	/* wait_ms(100); */

	printk(KERN_ERR "essidbuf: ");

	for (i = 0; i < erq->length; i++)
		printk(KERN_ERR "%02x ", essidbuf[i]);

	printk(KERN_ERR "\n");

	essidbuf[erq->length] = '\0';
	/* memcpy(macp->wd.ws.ssid, essidbuf, erq->length); */
	/* macp->wd.ws.ssidLen = strlen(essidbuf)+2; */
	/* macp->wd.ws.ssid[1] = strlen(essidbuf); Update ssid length */

	zfiWlanSetSSID(dev, essidbuf, erq->length);
	#if 0
		printk(KERN_ERR "macp->wd.ws.ssid: ");

		for (i = 0; i < macp->wd.ws.ssidLen; i++)
			printk(KERN_ERR "%02x ", macp->wd.ws.ssid[i]);

		printk(KERN_ERR "\n");
	#endif

	zfiWlanDisable(dev, 0);
	zfiWlanEnable(dev);

	#endif

	return 0;
}

int usbdrv_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
{
	/* struct usbdrv_private *macp = dev->ml_priv; */
	u8_t essidbuf[IW_ESSID_MAX_SIZE+1];
	u8_t len;
	u8_t i;


	/* len = macp->wd.ws.ssidLen; */
	/* memcpy(essidbuf, macp->wd.ws.ssid, macp->wd.ws.ssidLen); */
	zfiWlanQuerySSID(dev, essidbuf, &len);

	essidbuf[len] = 0;

	printk(KERN_ERR "ESSID: ");

	for (i = 0; i < len; i++)
		printk(KERN_ERR "%c", essidbuf[i]);

	printk(KERN_ERR "\n");

	erq->flags = 1;
	erq->length = strlen(essidbuf) + 1;

	if (erq->pointer) {
		if (copy_to_user(erq->pointer, essidbuf, erq->length))
			return -EFAULT;
	}

	return 0;
}

int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
{
	return 0;
}

/*
 * Encode a WPA or RSN information element as a custom
 * element using the hostap format.
 */
u32 encode_ie(void *buf, u32 bufsize, const u8 *ie, u32 ielen,
		const u8 *leader, u32 leader_len)
{
	u8 *p;
	u32 i;

	if (bufsize < leader_len)
		return 0;
	p = buf;
	memcpy(p, leader, leader_len);
	bufsize -= leader_len;
	p += leader_len;
	for (i = 0; i < ielen && bufsize > 2; i++)
		p += sprintf(p, "%02x", ie[i]);
	return (i == ielen ? p - (u8 *)buf:0);
}

/*
 * Translate scan data returned from the card to a card independent
 * format that the Wireless Tools will understand
 */
char *usbdrv_translate_scan(struct net_device *dev,
	struct iw_request_info *info, char *current_ev,
	char *end_buf, struct zsBssInfo *list)
{
	struct iw_event iwe;   /* Temporary buffer */
	u16_t capabilities;
	char *current_val;     /* For rates */
	char *last_ev;
	int i;
	char    buf[64*2 + 30];

	last_ev = current_ev;

	/* First entry *MUST* be the AP MAC address */
	iwe.cmd = SIOCGIWAP;
	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
	memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
	current_ev = iwe_stream_add_event(info,	current_ev,
					end_buf, &iwe, IW_EV_ADDR_LEN);

	/* Ran out of buffer */
	if (last_ev == current_ev)
		return end_buf;

	last_ev = current_ev;

	/* Other entries will be displayed in the order we give them */

	/* Add the ESSID */
	iwe.u.data.length = list->ssid[1];
	if (iwe.u.data.length > 32)
		iwe.u.data.length = 32;
	iwe.cmd = SIOCGIWESSID;
	iwe.u.data.flags = 1;
	current_ev = iwe_stream_add_point(info,	current_ev,
					end_buf, &iwe, &list->ssid[2]);

	/* Ran out of buffer */
	if (last_ev == current_ev)
		return end_buf;

	last_ev = current_ev;

	/* Add mode */
	iwe.cmd = SIOCGIWMODE;
	capabilities = (list->capability[1] << 8) + list->capability[0];
	if (capabilities & (0x01 | 0x02)) {
		if (capabilities & 0x01)
			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);
	}

	/* Ran out of buffer */
	if (last_ev == current_ev)
		return end_buf;

	last_ev = current_ev;

	/* Add frequency */
	iwe.cmd = SIOCGIWFREQ;
	iwe.u.freq.m = list->channel;
	/* Channel frequency in KHz */
	if (iwe.u.freq.m > 14) {
		if ((184 <= iwe.u.freq.m) && (iwe.u.freq.m <= 196))
			iwe.u.freq.m = 4000 + iwe.u.freq.m * 5;
		else
			iwe.u.freq.m = 5000 + iwe.u.freq.m * 5;
	} else {
		if (iwe.u.freq.m == 14)
			iwe.u.freq.m = 2484;
		else
			iwe.u.freq.m = 2412 + (iwe.u.freq.m - 1) * 5;
	}
	iwe.u.freq.e = 6;
	current_ev = iwe_stream_add_event(info, current_ev,
					end_buf, &iwe, IW_EV_FREQ_LEN);

	/* Ran out of buffer */
	if (last_ev == current_ev)
		return end_buf;

	last_ev = current_ev;

	/* Add quality statistics */
	iwe.cmd = IWEVQUAL;
	iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
				| IW_QUAL_NOISE_UPDATED;
	iwe.u.qual.level = list->signalStrength;
	iwe.u.qual.noise = 0;
	iwe.u.qual.qual = list->signalQuality;
	current_ev = iwe_stream_add_event(info,	current_ev,
					end_buf, &iwe, IW_EV_QUAL_LEN);

	/* Ran out of buffer */
	if (last_ev == current_ev)
		return end_buf;

	last_ev = current_ev;

	/* Add encryption capability */

	iwe.cmd = SIOCGIWENCODE;
	if (capabilities & 0x10)
		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, list->ssid);

	/* Ran out of buffer */
	if (last_ev == current_ev)
		return end_buf;

	last_ev = current_ev;

	/* Rate : stuffing multiple values in a single event require a bit
	* more of magic
	*/
	current_val = current_ev + IW_EV_LCP_LEN;

	iwe.cmd = SIOCGIWRATE;
	/* Those two flags are ignored... */
	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;

	for (i = 0 ; i < list->supportedRates[1] ; i++) {
		/* Bit rate given in 500 kb/s units (+ 0x80) */
		iwe.u.bitrate.value = ((list->supportedRates[i+2] & 0x7f)
					* 500000);
		/* Add new value to event */
		current_val = iwe_stream_add_value(info, current_ev,
				current_val, end_buf, &iwe, IW_EV_PARAM_LEN);

		/* Ran out of buffer */
		if (last_ev == current_val)
			return end_buf;

		last_ev = current_val;
	}

	for (i = 0 ; i < list->extSupportedRates[1] ; i++) {
		/* Bit rate given in 500 kb/s units (+ 0x80) */
		iwe.u.bitrate.value = ((list->extSupportedRates[i+2] & 0x7f)
					* 500000);
		/* Add new value to event */
		current_val = iwe_stream_add_value(info, current_ev,
				current_val, end_buf, &iwe, IW_EV_PARAM_LEN);

		/* Ran out of buffer */
		if (last_ev == current_val)
			return end_buf;

		last_ev = current_ev;
	}

	/* Check if we added any event */
	if ((current_val - current_ev) > IW_EV_LCP_LEN)
		current_ev = current_val;
		#define IEEE80211_ELEMID_RSN 0x30
	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = IWEVCUSTOM;
	snprintf(buf, sizeof(buf), "bcn_int=%d", (list->beaconInterval[1] << 8)
						+ list->beaconInterval[0]);
	iwe.u.data.length = strlen(buf);
	current_ev = iwe_stream_add_point(info, current_ev,
						end_buf, &iwe, buf);

	/* Ran out of buffer */
	if (last_ev == current_ev)
		return end_buf;

	last_ev = current_ev;

	if (list->wpaIe[1] != 0) {
		static const char rsn_leader[] = "rsn_ie=";
		static const char wpa_leader[] = "wpa_ie=";

		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVCUSTOM;
		if (list->wpaIe[0] == IEEE80211_ELEMID_RSN)
			iwe.u.data.length = encode_ie(buf, sizeof(buf),
					list->wpaIe, list->wpaIe[1]+2,
					rsn_leader, sizeof(rsn_leader)-1);
		else
			iwe.u.data.length = encode_ie(buf, sizeof(buf),
					list->wpaIe, list->wpaIe[1]+2,
					wpa_leader, sizeof(wpa_leader)-1);

		if (iwe.u.data.length != 0)
			current_ev = iwe_stream_add_point(info, current_ev,
							end_buf, &iwe, buf);

		/* Ran out of buffer */
		if (last_ev == current_ev)
			return end_buf;

		last_ev = current_ev;
	}

	if (list->rsnIe[1] != 0) {
		static const char rsn_leader[] = "rsn_ie=";
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVCUSTOM;

		if (list->rsnIe[0] == IEEE80211_ELEMID_RSN) {
			iwe.u.data.length = encode_ie(buf, sizeof(buf),
			list->rsnIe, list->rsnIe[1]+2,
			rsn_leader, sizeof(rsn_leader)-1);
			if (iwe.u.data.length != 0)
				current_ev = iwe_stream_add_point(info,
					current_ev, end_buf,  &iwe, buf);

			/* Ran out of buffer */
			if (last_ev == current_ev)
				return end_buf;

			last_ev = current_ev;
		}
	}
	/* The other data in the scan result are not really
	* interesting, so for now drop it
	*/
	return current_ev;
}

int usbdrvwext_giwname(struct net_device *dev,
		struct iw_request_info *info,
		union iwreq_data *wrq, char *extra)
{
	/* struct usbdrv_private *macp = dev->ml_priv; */

	strcpy(wrq->name, "IEEE 802.11-MIMO");

	return 0;
}

int usbdrvwext_siwfreq(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_freq *freq, char *extra)
{
	u32_t FreqKHz;
	struct usbdrv_private *macp = dev->ml_priv;

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

	if (freq->e > 1)
		return -EINVAL;

	if (freq->e == 1) {
		FreqKHz = (freq->m / 100000);

		if (FreqKHz > 4000000) {
			if (FreqKHz > 5825000)
				FreqKHz = 5825000;
			else if (FreqKHz < 4920000)
				FreqKHz = 4920000;
			else if (FreqKHz < 5000000)
				FreqKHz = (((FreqKHz - 4000000) / 5000) * 5000)
						+ 4000000;
			else
				FreqKHz = (((FreqKHz - 5000000) / 5000) * 5000)
						+ 5000000;
		} else {
			if (FreqKHz > 2484000)
				FreqKHz = 2484000;
			else if (FreqKHz < 2412000)
				FreqKHz = 2412000;
			else
				FreqKHz = (((FreqKHz - 2412000) / 5000) * 5000)
						+ 2412000;
		}
	} else {
		FreqKHz = usbdrv_chan2freq(freq->m);

		if (FreqKHz != -1)
			FreqKHz *= 1000;
		else
			FreqKHz = 2412000;
	}

	/* printk("freq->m: %d, freq->e: %d\n", freq->m, freq->e); */
	/* printk("FreqKHz: %d\n", FreqKHz); */

	if (macp->DeviceOpened == 1) {
		zfiWlanSetFrequency(dev, FreqKHz, 0); /* Immediate */
		/* u8_t wpaieLen,wpaie[50]; */
		/* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
		zfiWlanDisable(dev, 0);
		zfiWlanEnable(dev);
		/* if (wpaieLen > 2) */
		/* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
	}

	return 0;
}

int usbdrvwext_giwfreq(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_freq *freq, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;

	if (macp->DeviceOpened != 1)
		return 0;

	freq->m = zfiWlanQueryFrequency(dev);
	freq->e = 3;

	return 0;
}

int usbdrvwext_siwmode(struct net_device *dev,
		struct iw_request_info *info,
		union iwreq_data *wrq, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;
	u8_t WlanMode;

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

	if (macp->DeviceOpened != 1)
		return 0;

	switch (wrq->mode) {
	case IW_MODE_MASTER:
		WlanMode = ZM_MODE_AP;
		break;
	case IW_MODE_INFRA:
		WlanMode = ZM_MODE_INFRASTRUCTURE;
		break;
	case IW_MODE_ADHOC:
		WlanMode = ZM_MODE_IBSS;
		break;
	default:
		WlanMode = ZM_MODE_IBSS;
		break;
	}

	zfiWlanSetWlanMode(dev, WlanMode);
	zfiWlanDisable(dev, 1);
	zfiWlanEnable(dev);

	return 0;
}

int usbdrvwext_giwmode(struct net_device *dev,
	struct iw_request_info *info,
	__u32 *mode, char *extra)
{
	unsigned long irqFlag;
	struct usbdrv_private *macp = dev->ml_priv;

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

	if (macp->DeviceOpened != 1)
		return 0;

	spin_lock_irqsave(&macp->cs_lock, irqFlag);

	switch (zfiWlanQueryWlanMode(dev)) {
	case ZM_MODE_AP:
		*mode = IW_MODE_MASTER;
		break;
	case ZM_MODE_INFRASTRUCTURE:
		*mode = IW_MODE_INFRA;
		break;
	case ZM_MODE_IBSS:
		*mode = IW_MODE_ADHOC;
		break;
	default:
		*mode = IW_MODE_ADHOC;
		break;
	}

	spin_unlock_irqrestore(&macp->cs_lock, irqFlag);

	return 0;
}

int usbdrvwext_siwsens(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_param *sens, char *extra)
{
	return 0;
}

int usbdrvwext_giwsens(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_param *sens, char *extra)
{
	sens->value = 0;
	sens->fixed = 1;

	return 0;
}

int usbdrvwext_giwrange(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_point *data, char *extra)
{
	struct iw_range *range = (struct iw_range *) extra;
	int i, val;
	/* int num_band_a; */
	u16_t channels[60];
	u16_t channel_num;

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

	range->txpower_capa = IW_TXPOW_DBM;
	/* XXX what about min/max_pmp, min/max_pmt, etc. */

	range->we_version_compiled = WIRELESS_EXT;
	range->we_version_source = 13;

	range->retry_capa = IW_RETRY_LIMIT;
	range->retry_flags = IW_RETRY_LIMIT;
	range->min_retry = 0;
	range->max_retry = 255;

	channel_num = zfiWlanQueryAllowChannels(dev, channels);

	/* Gurantee reported channel numbers is less
	* or equal to IW_MAX_FREQUENCIES
	*/
	if (channel_num > IW_MAX_FREQUENCIES)
		channel_num = IW_MAX_FREQUENCIES;

	val = 0;

	for (i = 0; i < channel_num; i++) {
		range->freq[val].i = usbdrv_freq2chan(channels[i]);
		range->freq[val].m = channels[i];
		range->freq[val].e = 6;
		val++;
	}

	range->num_channels = channel_num;
	range->num_frequency = channel_num;

	#if 0
	range->num_channels = 14; /* Only 2.4G */

	/* XXX need to filter against the regulatory domain &| active set */
	val = 0;
	/* B,G Bands */
	for (i = 1; i <= 14; i++) {
		range->freq[val].i = i;
		if (i == 14)
			range->freq[val].m = 2484000;
		else
			range->freq[val].m = (2412+(i-1)*5)*1000;
		range->freq[val].e = 3;
		val++;
	}

	num_band_a = (IW_MAX_FREQUENCIES - val);
	/* A Bands */
	for (i = 0; i < num_band_a; i++) {
		range->freq[val].i = channel_frequency_11A[2 * i];
		range->freq[val].m = channel_frequency_11A[2 * i + 1] * 1000;
		range->freq[val].e = 3;
		val++;
	}
	/* MIMO Rate Not Defined Now
	* For 802.11a, there are too more frequency.
	* We can't return them all.
	*/
	range->num_frequency = val;
	#endif

	/* Max of /proc/net/wireless */
	range->max_qual.qual = 100;  /* ??  92; */
	range->max_qual.level = 154; /* ?? */
	range->max_qual.noise = 154; /* ?? */
	range->sensitivity = 3;      /* ?? */

	/* XXX these need to be nsd-specific! */
	range->min_rts = 0;
	range->max_rts = 2347;
	range->min_frag = 256;
	range->max_frag = 2346;
	range->max_encoding_tokens = 4 /* NUM_WEPKEYS ?? */;
	range->num_encoding_sizes = 2; /* ?? */

	range->encoding_size[0] = 5; /* ?? WEP Key Encoding Size */
	range->encoding_size[1] = 13; /* ?? */

	/* XXX what about num_bitrates/throughput? */
	range->num_bitrates = 0; /* ?? */

	/* estimated max throughput
	* XXX need to cap it if we're running at ~2Mbps..
	*/

	range->throughput = 300000000;

	return 0;
}

int usbdrvwext_siwap(struct net_device *dev, struct iw_request_info *info,
		struct sockaddr *MacAddr, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;

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

	if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
		/* AP Mode */
		zfiWlanSetMacAddress(dev, (u16_t *)&MacAddr->sa_data[0]);
	} else {
		/* STA Mode */
		zfiWlanSetBssid(dev, &MacAddr->sa_data[0]);
	}

	if (macp->DeviceOpened == 1) {
		/* u8_t wpaieLen,wpaie[80]; */
		/* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
		zfiWlanDisable(dev, 0);
		zfiWlanEnable(dev);
		/* if (wpaieLen > 2) */
		/* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
	}

	return 0;
}

int usbdrvwext_giwap(struct net_device *dev,
		struct iw_request_info *info,
		struct sockaddr *MacAddr, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;

	if (macp->DeviceOpened != 1)
		return 0;

	if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
		/* AP Mode */
		zfiWlanQueryMacAddress(dev, &MacAddr->sa_data[0]);
	} else {
		/* STA Mode */
		if (macp->adapterState == ZM_STATUS_MEDIA_CONNECT) {
			zfiWlanQueryBssid(dev, &MacAddr->sa_data[0]);
		} else {
			u8_t zero_addr[6] = { 0x00, 0x00, 0x00, 0x00,
								0x00, 0x00 };
			memcpy(&MacAddr->sa_data[0], zero_addr,
							sizeof(zero_addr));
		}
	}

	return 0;
}

int usbdrvwext_iwaplist(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_point *data, char *extra)
{
	/* Don't know how to do yet--CWYang(+) */
	return 0;

}

int usbdrvwext_siwscan(struct net_device *dev, struct iw_request_info *info,
	struct iw_point *data, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;

	if (macp->DeviceOpened != 1)
		return 0;

	printk(KERN_WARNING "CWY - usbdrvwext_siwscan\n");

	zfiWlanScan(dev);

	return 0;
}

int usbdrvwext_giwscan(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_point *data, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;
	/* struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); */
	char *current_ev = extra;
	char *end_buf;
	int i;
	/* struct zsBssList BssList; */
	struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
								GFP_KERNEL);
	/* BssList = wd->sta.pBssList; */
	/* zmw_get_wlan_dev(dev); */

	if (macp->DeviceOpened != 1)
		return 0;

	if (data->length == 0)
		end_buf = extra + IW_SCAN_MAX_DATA;
	else
		end_buf = extra + data->length;

	printk(KERN_WARNING "giwscan - Report Scan Results\n");
	/* printk("giwscan - BssList Sreucture Len : %d\n", sizeof(BssList));
	* printk("giwscan - BssList Count : %d\n",
	* wd->sta.pBssList->bssCount);
	* printk("giwscan - UpdateBssList Count : %d\n",
	* wd->sta.pUpdateBssList->bssCount);
	*/
	zfiWlanQueryBssListV1(dev, pBssList);
	/* zfiWlanQueryBssList(dev, &BssList); */

	/* Read and parse all entries */
	printk(KERN_WARNING "giwscan - pBssList->bssCount : %d\n",
						pBssList->bssCount);
	/* printk("giwscan - BssList.bssCount : %d\n", BssList.bssCount); */

	for (i = 0; i < pBssList->bssCount; i++) {
		/* Translate to WE format this entry
		* current_ev = usbdrv_translate_scan(dev, info, current_ev,
		* extra + IW_SCAN_MAX_DATA, &pBssList->bssInfo[i]);
		*/
		current_ev = usbdrv_translate_scan(dev, info, current_ev,
					end_buf, &pBssList->bssInfo[i]);

		if (current_ev == end_buf) {
			kfree(pBssList);
			data->length = current_ev - extra;
			return -E2BIG;
		}
	}

	/* Length of data */
	data->length = (current_ev - extra);
	data->flags = 0;   /* todo */

	kfree(pBssList);

	return 0;
}

int usbdrvwext_siwessid(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_point *essid, char *extra)
{
	char EssidBuf[IW_ESSID_MAX_SIZE + 1];
	struct usbdrv_private *macp = dev->ml_priv;

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

	if (essid->flags == 1) {
		if (essid->length > (IW_ESSID_MAX_SIZE + 1))
			return -E2BIG;

		if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
			return -EFAULT;

		EssidBuf[essid->length] = '\0';
		/* printk("siwessid - Set Essid : %s\n",EssidBuf); */
		/* printk("siwessid - Essid Len : %d\n",essid->length); */
		/* printk("siwessid - Essid Flag : %x\n",essid->flags); */
		if (macp->DeviceOpened == 1) {
			zfiWlanSetSSID(dev, EssidBuf, strlen(EssidBuf));
			zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev),
						FALSE);
			zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
			/* u8_t wpaieLen,wpaie[50]; */
			/* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
			zfiWlanDisable(dev, 0);
			zfiWlanEnable(dev);
			/* if (wpaieLen > 2) */
			/* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
		}
	}

	return 0;
}

int usbdrvwext_giwessid(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_point *essid, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;
	u8_t EssidLen;
	char EssidBuf[IW_ESSID_MAX_SIZE + 1];
	int ssid_len;

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

	if (macp->DeviceOpened != 1)
		return 0;

	zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);

	/* Convert type from unsigned char to char */
	ssid_len = (int)EssidLen;

	/* Make sure the essid length is not greater than IW_ESSID_MAX_SIZE */
	if (ssid_len > IW_ESSID_MAX_SIZE)
		ssid_len = IW_ESSID_MAX_SIZE;

	EssidBuf[ssid_len] = '\0';

	essid->flags = 1;
	essid->length = strlen(EssidBuf);

	memcpy(extra, EssidBuf, essid->length);
	/* wireless.c in Kernel would handle copy_to_user -- line 679 */
	/* if (essid->pointer) {
	* if (copy_to_user(essid->pointer, EssidBuf, essid->length)) {
	* printk("giwessid - copy_to_user Fail\n");
	* return -EFAULT;
	* }
	* }
	*/

	return 0;
}

int usbdrvwext_siwnickn(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_point *data, char *nickname)
{
	/* Exist but junk--CWYang(+) */
	return 0;
}

int usbdrvwext_giwnickn(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_point *data, char *nickname)
{
	struct usbdrv_private *macp = dev->ml_priv;
	u8_t EssidLen;
	char EssidBuf[IW_ESSID_MAX_SIZE + 1];

	if (macp->DeviceOpened != 1)
		return 0;

	zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
	EssidBuf[EssidLen] = 0;

	data->flags = 1;
	data->length = strlen(EssidBuf);

	memcpy(nickname, EssidBuf, data->length);

	return 0;
}

int usbdrvwext_siwrate(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_param *frq, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;
	/* Array to Define Rate Number that Send to Driver */
	u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0,
			48000, 24000, 12000, 6000, 54000, 36000, 18000, 9000};
	u16_t zcRateToMCS[] = {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd,
				0x8, 0xc};
	u8_t i, RateIndex = 4;
	u16_t RateKbps;

	/* printk("frq->disabled : 0x%x\n",frq->disabled); */
	/* printk("frq->value : 0x%x\n",frq->value); */

	RateKbps = frq->value / 1000;
	/* printk("RateKbps : %d\n", RateKbps); */
	for (i = 0; i < 16; i++) {
		if (RateKbps == zcIndextoRateBG[i])
			RateIndex = i;
	}

	if (zcIndextoRateBG[RateIndex] == 0)
		RateIndex = 0xff;
	/* printk("RateIndex : %x\n", RateIndex); */
	for (i = 0; i < 13; i++)
		if (RateIndex == zcRateToMCS[i])
			break;
	/* printk("Index : %x\n", i); */
	if (RateKbps == 65000) {
		RateIndex = 20;
		printk(KERN_WARNING "RateIndex : %d\n", RateIndex);
	}

	if (macp->DeviceOpened == 1) {
		zfiWlanSetTxRate(dev, i);
		/* zfiWlanDisable(dev); */
		/* zfiWlanEnable(dev); */
	}

	return 0;
}

int usbdrvwext_giwrate(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_param *frq, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;

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

	if (macp->DeviceOpened != 1)
		return 0;

	frq->fixed = 0;
	frq->disabled = 0;
	frq->value = zfiWlanQueryRxRate(dev) * 1000;

	return 0;
}

int usbdrvwext_siwrts(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_param *rts, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;
	int val = rts->value;

	if (macp->DeviceOpened != 1)
		return 0;

	if (rts->disabled)
		val = 2347;

	if ((val < 0) || (val > 2347))
		return -EINVAL;

	zfiWlanSetRtsThreshold(dev, val);

	return 0;
}

int usbdrvwext_giwrts(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_param *rts, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;

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

	if (macp->DeviceOpened != 1)
		return 0;

	rts->value = zfiWlanQueryRtsThreshold(dev);
	rts->disabled = (rts->value >= 2347);
	rts->fixed = 1;

	return 0;
}

int usbdrvwext_siwfrag(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_param *frag, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;
	u16_t fragThreshold;

	if (macp->DeviceOpened != 1)
		return 0;

	if (frag->disabled)
		fragThreshold = 0;
	else
		fragThreshold = frag->value;

	zfiWlanSetFragThreshold(dev, fragThreshold);

	return 0;
}

int usbdrvwext_giwfrag(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_param *frag, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;
	u16 val;
	unsigned long irqFlag;

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

	if (macp->DeviceOpened != 1)
		return 0;

	spin_lock_irqsave(&macp->cs_lock, irqFlag);

	val = zfiWlanQueryFragThreshold(dev);

	frag->value = val;

	frag->disabled = (val >= 2346);
	frag->fixed = 1;

	spin_unlock_irqrestore(&macp->cs_lock, irqFlag);

	return 0;
}

int usbdrvwext_siwtxpow(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_param *rrq, char *extra)
{
	/* Not support yet--CWYng(+) */
	return 0;
}

int usbdrvwext_giwtxpow(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_param *rrq, char *extra)
{
	/* Not support yet--CWYng(+) */
	return 0;
}

int usbdrvwext_siwretry(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_param *rrq, char *extra)
{
	/* Do nothing--CWYang(+) */
	return 0;
}

int usbdrvwext_giwretry(struct net_device *dev,
			struct iw_request_info *info,
			struct iw_param *rrq, char *extra)
{
	/* Do nothing--CWYang(+) */
	return 0;
}

int usbdrvwext_siwencode(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_point *erq, char *key)
{
	struct zsKeyInfo keyInfo;
	int i;
	int WepState = ZM_ENCRYPTION_WEP_DISABLED;
	struct usbdrv_private *macp = dev->ml_priv;

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

	if ((erq->flags & IW_ENCODE_DISABLED) == 0) {
		keyInfo.key = key;
		keyInfo.keyLength = erq->length;
		keyInfo.keyIndex = (erq->flags & IW_ENCODE_INDEX) - 1;
		if (keyInfo.keyIndex >= 4)
			keyInfo.keyIndex = 0;
		keyInfo.flag = ZM_KEY_FLAG_DEFAULT_KEY;

		zfiWlanSetKey(dev, keyInfo);
		WepState = ZM_ENCRYPTION_WEP_ENABLED;
	} else {
		for (i = 1; i < 4; i++)
			zfiWlanRemoveKey(dev, 0, i);
		WepState = ZM_ENCRYPTION_WEP_DISABLED;
		/* zfiWlanSetEncryMode(dev, ZM_NO_WEP); */
	}

	if (macp->DeviceOpened == 1) {
		zfiWlanSetWepStatus(dev, WepState);
		zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
		/* zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev)); */
		/* u8_t wpaieLen,wpaie[50]; */
		/* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
		zfiWlanDisable(dev, 0);
		zfiWlanEnable(dev);
		/* if (wpaieLen > 2) */
		/* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
	}

	return 0;
}

int usbdrvwext_giwencode(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_point *erq, char *key)
{
	struct usbdrv_private *macp = dev->ml_priv;
	u8_t EncryptionMode;
	u8_t keyLen = 0;

	if (macp->DeviceOpened != 1)
		return 0;

	EncryptionMode = zfiWlanQueryEncryMode(dev);

	if (EncryptionMode)
		erq->flags = IW_ENCODE_ENABLED;
	else
		erq->flags = IW_ENCODE_DISABLED;

	/* We can't return the key, so set the proper flag and return zero */
	erq->flags |= IW_ENCODE_NOKEY;
	memset(key, 0, 16);

	/* Copy the key to the user buffer */
	switch (EncryptionMode) {
	case ZM_WEP64:
		keyLen = 5;
		break;
	case ZM_WEP128:
		keyLen = 13;
		break;
	case ZM_WEP256:
		keyLen = 29;
		break;
	case ZM_AES:
		keyLen = 16;
		break;
	case ZM_TKIP:
		keyLen = 32;
		break;
	#ifdef ZM_ENABLE_CENC
	case ZM_CENC:
		/* ZM_ENABLE_CENC */
		keyLen = 32;
		break;
	#endif
	case ZM_NO_WEP:
		keyLen = 0;
		break;
	default:
		keyLen = 0;
		printk(KERN_ERR "Unknown EncryMode\n");
		break;
	}
	erq->length = keyLen;

	return 0;
}

int usbdrvwext_siwpower(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_param *frq, char *extra)
{
	struct usbdrv_private *macp = dev->ml_priv;
	u8_t PSMode;

	if (macp->DeviceOpened != 1)
		return 0;

	if (frq->disabled)
		PSMode = ZM_STA_PS_NONE;
	else
		PSMode = ZM_STA_PS_MAX;

	zfiWlanSetPowerSaveMode(dev, PSMode);

	return 0;
}

int usbdrvwext_giwpower(struct net_device *dev,
		struct iw_request_info *info,
		struct iw_param *frq, char *extra)
{
	unsigned long irqFlag;
	struct usbdrv_private *macp = dev->ml_priv;

	if (macp->DeviceOpened != 1)
		return 0;

	spin_lock_irqsave(&macp->cs_lock, irqFlag);

	if (zfiWlanQueryPowerSaveMode(dev) == ZM_STA_PS_NONE)
		frq->disabled = 1;
	else
		frq->disabled = 0;

	spin_unlock_irqrestore(&macp->cs_lock, irqFlag);

	return 0;
}

/*int usbdrvwext_setparam(struct net_device *dev, struct iw_request_info *info,
*		   	 void *w, char *extra)
*{
*	struct ieee80211vap *vap = dev->ml_priv;
*	struct ieee80211com *ic = vap->iv_ic;
*	struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
*	int *i = (int *) extra;
*	int param = i[0];		// parameter id is 1st
*	int value = i[1];		// NB: most values are TYPE_INT
*	int retv = 0;
*	int j, caps;
*	const struct ieee80211_authenticator *auth;
*	const struct ieee80211_aclator *acl;
*
*	switch (param) {
*	case IEEE80211_PARAM_AUTHMODE:
*		switch (value) {
*		case IEEE80211_AUTH_WPA:	// WPA
*		case IEEE80211_AUTH_8021X:	// 802.1x
*		case IEEE80211_AUTH_OPEN:	// open
*		case IEEE80211_AUTH_SHARED:	// shared-key
*		case IEEE80211_AUTH_AUTO:	// auto
*			auth = ieee80211_authenticator_get(value);
*			if (auth == NULL)
*				return -EINVAL;
*			break;
*		default:
*			return -EINVAL;
*		}
*		switch (value) {
*		case IEEE80211_AUTH_WPA:	// WPA w/ 802.1x
*			vap->iv_flags |= IEEE80211_F_PRIVACY;
*			value = IEEE80211_AUTH_8021X;
*			break;
*		case IEEE80211_AUTH_OPEN:	// open
*		vap->iv_flags &= ~(IEEE80211_F_WPA | IEEE80211_F_PRIVACY);
*			break;
*		case IEEE80211_AUTH_SHARED:	// shared-key
*		case IEEE80211_AUTH_AUTO:	// auto
*		case IEEE80211_AUTH_8021X:	// 802.1x
*			vap->iv_flags &= ~IEEE80211_F_WPA;
*			// both require a key so mark the PRIVACY capability
*			vap->iv_flags |= IEEE80211_F_PRIVACY;
*			break;
*		}
*		// NB: authenticator attach/detach happens on state change
*		vap->iv_bss->ni_authmode = value;
*		// XXX mixed/mode/usage?
*		vap->iv_auth = auth;
*		retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_PROTMODE:
*		if (value > IEEE80211_PROT_RTSCTS)
*			return -EINVAL;
*		ic->ic_protmode = value;
*		// NB: if not operating in 11g this can wait
*		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
*		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
*			retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_MCASTCIPHER:
*		if ((vap->iv_caps & cipher2cap(value)) == 0 &&
*		    !ieee80211_crypto_available(value))
*			return -EINVAL;
*		rsn->rsn_mcastcipher = value;
*		if (vap->iv_flags & IEEE80211_F_WPA)
*			retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_MCASTKEYLEN:
*		if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
*			return -EINVAL;
*		// XXX no way to verify driver capability
*		rsn->rsn_mcastkeylen = value;
*		if (vap->iv_flags & IEEE80211_F_WPA)
*			retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_UCASTCIPHERS:
*
*		 // Convert cipher set to equivalent capabilities.
*		 // NB: this logic intentionally ignores unknown and
*		 // unsupported ciphers so folks can specify 0xff or
*		 // similar and get all available ciphers.
*
*		caps = 0;
*		for (j = 1; j < 32; j++)	// NB: skip WEP
*			if ((value & (1<<j)) &&
*			    ((vap->iv_caps & cipher2cap(j)) ||
*			     ieee80211_crypto_available(j)))
*				caps |= 1<<j;
*		if (caps == 0)			// nothing available
*			return -EINVAL;
*		// XXX verify ciphers ok for unicast use?
*		// XXX disallow if running as it'll have no effect
*		rsn->rsn_ucastcipherset = caps;
*		if (vap->iv_flags & IEEE80211_F_WPA)
*			retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_UCASTCIPHER:
*		if ((rsn->rsn_ucastcipherset & cipher2cap(value)) == 0)
*			return -EINVAL;
*		rsn->rsn_ucastcipher = value;
*		break;
*	case IEEE80211_PARAM_UCASTKEYLEN:
*		if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
*			return -EINVAL;
*		// XXX no way to verify driver capability
*		rsn->rsn_ucastkeylen = value;
*		break;
*	case IEEE80211_PARAM_KEYMGTALGS:
*		// XXX check
*		rsn->rsn_keymgmtset = value;
*		if (vap->iv_flags & IEEE80211_F_WPA)
*			retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_RSNCAPS:
*		// XXX check
*		rsn->rsn_caps = value;
*		if (vap->iv_flags & IEEE80211_F_WPA)
*			retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_WPA:
*		if (value > 3)
*			return -EINVAL;
*		// XXX verify ciphers available
*		vap->iv_flags &= ~IEEE80211_F_WPA;
*		switch (value) {
*		case 1:
*			vap->iv_flags |= IEEE80211_F_WPA1;
*			break;
*		case 2:
*			vap->iv_flags |= IEEE80211_F_WPA2;
*			break;
*		case 3:
*			vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
*			break;
*		}
*		retv = ENETRESET;		// XXX?
*		break;
*	case IEEE80211_PARAM_ROAMING:
*		if (!(IEEE80211_ROAMING_DEVICE <= value &&
*		    value <= IEEE80211_ROAMING_MANUAL))
*			return -EINVAL;
*		ic->ic_roaming = value;
*		break;
*	case IEEE80211_PARAM_PRIVACY:
*		if (value) {
*			// XXX check for key state?
*			vap->iv_flags |= IEEE80211_F_PRIVACY;
*		} else
*			vap->iv_flags &= ~IEEE80211_F_PRIVACY;
*		break;
*	case IEEE80211_PARAM_DROPUNENCRYPTED:
*		if (value)
*			vap->iv_flags |= IEEE80211_F_DROPUNENC;
*		else
*			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
*		break;
*	case IEEE80211_PARAM_COUNTERMEASURES:
*		if (value) {
*			if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
*				return -EINVAL;
*			vap->iv_flags |= IEEE80211_F_COUNTERM;
*		} else
*			vap->iv_flags &= ~IEEE80211_F_COUNTERM;
*		break;
*	case IEEE80211_PARAM_DRIVER_CAPS:
*		vap->iv_caps = value;		// NB: for testing
*		break;
*	case IEEE80211_PARAM_MACCMD:
*		acl = vap->iv_acl;
*		switch (value) {
*		case IEEE80211_MACCMD_POLICY_OPEN:
*		case IEEE80211_MACCMD_POLICY_ALLOW:
*		case IEEE80211_MACCMD_POLICY_DENY:
*			if (acl == NULL) {
*				acl = ieee80211_aclator_get("mac");
*				if (acl == NULL || !acl->iac_attach(vap))
*					return -EINVAL;
*				vap->iv_acl = acl;
*			}
*			acl->iac_setpolicy(vap, value);
*			break;
*		case IEEE80211_MACCMD_FLUSH:
*			if (acl != NULL)
*				acl->iac_flush(vap);
*			// NB: silently ignore when not in use
*			break;
*		case IEEE80211_MACCMD_DETACH:
*			if (acl != NULL) {
*				vap->iv_acl = NULL;
*				acl->iac_detach(vap);
*			}
*			break;
*		}
*		break;
*	case IEEE80211_PARAM_WMM:
*		if (ic->ic_caps & IEEE80211_C_WME){
*			if (value) {
*				vap->iv_flags |= IEEE80211_F_WME;
*				 *//* XXX needed by ic_reset *//*
*				vap->iv_ic->ic_flags |= IEEE80211_F_WME;
*			}
*			else {
*				*//* XXX needed by ic_reset *//*
*				vap->iv_flags &= ~IEEE80211_F_WME;
*				vap->iv_ic->ic_flags &= ~IEEE80211_F_WME;
*			}
*			retv = ENETRESET;	// Renegotiate for capabilities
*		}
*		break;
*	case IEEE80211_PARAM_HIDESSID:
*		if (value)
*			vap->iv_flags |= IEEE80211_F_HIDESSID;
*		else
*			vap->iv_flags &= ~IEEE80211_F_HIDESSID;
*		retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_APBRIDGE:
*		if (value == 0)
*			vap->iv_flags |= IEEE80211_F_NOBRIDGE;
*		else
*			vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
*		break;
*	case IEEE80211_PARAM_INACT:
*		vap->iv_inact_run = value / IEEE80211_INACT_WAIT;
*		break;
*	case IEEE80211_PARAM_INACT_AUTH:
*		vap->iv_inact_auth = value / IEEE80211_INACT_WAIT;
*		break;
*	case IEEE80211_PARAM_INACT_INIT:
*		vap->iv_inact_init = value / IEEE80211_INACT_WAIT;
*		break;
*	case IEEE80211_PARAM_ABOLT:
*		caps = 0;
*
*		 // Map abolt settings to capability bits;
*		 // this also strips unknown/unwanted bits.
*
*		if (value & IEEE80211_ABOLT_TURBO_PRIME)
*			caps |= IEEE80211_ATHC_TURBOP;
*		if (value & IEEE80211_ABOLT_COMPRESSION)
*			caps |= IEEE80211_ATHC_COMP;
*		if (value & IEEE80211_ABOLT_FAST_FRAME)
*			caps |= IEEE80211_ATHC_FF;
*		if (value & IEEE80211_ABOLT_XR)
*			caps |= IEEE80211_ATHC_XR;
*		if (value & IEEE80211_ABOLT_AR)
*			caps |= IEEE80211_ATHC_AR;
*		if (value & IEEE80211_ABOLT_BURST)
*			caps |= IEEE80211_ATHC_BURST;
*        if (value & IEEE80211_ABOLT_WME_ELE)
*            caps |= IEEE80211_ATHC_WME;
*		// verify requested capabilities are supported
*		if ((caps & ic->ic_ath_cap) != caps)
*			return -EINVAL;
*		if (vap->iv_ath_cap != caps) {
*			if ((vap->iv_ath_cap ^ caps) & IEEE80211_ATHC_TURBOP) {
*				if (ieee80211_set_turbo(dev,
*						caps & IEEE80211_ATHC_TURBOP))
*					return -EINVAL;
*				ieee80211_scan_flush(ic);
*			}
*			vap->iv_ath_cap = caps;
*			ic->ic_athcapsetup(vap->iv_ic, vap->iv_ath_cap);
*			retv = ENETRESET;
*		}
*		break;
*	case IEEE80211_PARAM_DTIM_PERIOD:
*		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
*		    vap->iv_opmode != IEEE80211_M_IBSS)
*			return -EINVAL;
*		if (IEEE80211_DTIM_MIN <= value &&
*		    value <= IEEE80211_DTIM_MAX) {
*			vap->iv_dtim_period = value;
*			retv = ENETRESET;		// requires restart
*		} else
*			retv = EINVAL;
*		break;
*	case IEEE80211_PARAM_BEACON_INTERVAL:
*		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
*		    vap->iv_opmode != IEEE80211_M_IBSS)
*			return -EINVAL;
*		if (IEEE80211_BINTVAL_MIN <= value &&
*		    value <= IEEE80211_BINTVAL_MAX) {
*			ic->ic_lintval = value;		// XXX multi-bss
*			retv = ENETRESET;		// requires restart
*		} else
*			retv = EINVAL;
*		break;
*	case IEEE80211_PARAM_DOTH:
*		if (value) {
*			ic->ic_flags |= IEEE80211_F_DOTH;
*		}
*		else
*			ic->ic_flags &= ~IEEE80211_F_DOTH;
*		retv = ENETRESET;	// XXX: need something this drastic?
*		break;
*	case IEEE80211_PARAM_PWRTARGET:
*		ic->ic_curchanmaxpwr = value;
*		break;
*	case IEEE80211_PARAM_GENREASSOC:
*		IEEE80211_SEND_MGMT(vap->iv_bss,
*					IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0);
*		break;
*	case IEEE80211_PARAM_COMPRESSION:
*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_COMP, value);
*		break;
*    case IEEE80211_PARAM_WMM_AGGRMODE:
*        retv = ieee80211_setathcap(vap, IEEE80211_ATHC_WME, value);
*        break;
*	case IEEE80211_PARAM_FF:
*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_FF, value);
*		break;
*	case IEEE80211_PARAM_TURBO:
*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_TURBOP, value);
*		if (retv == ENETRESET) {
*			if(ieee80211_set_turbo(dev,value))
*					return -EINVAL;
*			ieee80211_scan_flush(ic);
*		}
*		break;
*	case IEEE80211_PARAM_XR:
*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_XR, value);
*		break;
*	case IEEE80211_PARAM_BURST:
*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_BURST, value);
*		break;
*	case IEEE80211_PARAM_AR:
*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_AR, value);
*		break;
*	case IEEE80211_PARAM_PUREG:
*		if (value)
*			vap->iv_flags |= IEEE80211_F_PUREG;
*		else
*			vap->iv_flags &= ~IEEE80211_F_PUREG;
*		// NB: reset only if we're operating on an 11g channel
*		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
*		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
*			retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_WDS:
*		if (value)
*			vap->iv_flags_ext |= IEEE80211_FEXT_WDS;
*		else
*			vap->iv_flags_ext &= ~IEEE80211_FEXT_WDS;
*		break;
*	case IEEE80211_PARAM_BGSCAN:
*		if (value) {
*			if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
*				return -EINVAL;
*			vap->iv_flags |= IEEE80211_F_BGSCAN;
*		} else {
*			// XXX racey?
*			vap->iv_flags &= ~IEEE80211_F_BGSCAN;
*			ieee80211_cancel_scan(vap);	// anything current
*		}
*		break;
*	case IEEE80211_PARAM_BGSCAN_IDLE:
*		if (value >= IEEE80211_BGSCAN_IDLE_MIN)
*			vap->iv_bgscanidle = value*HZ/1000;
*		else
*			retv = EINVAL;
*		break;
*	case IEEE80211_PARAM_BGSCAN_INTERVAL:
*		if (value >= IEEE80211_BGSCAN_INTVAL_MIN)
*			vap->iv_bgscanintvl = value*HZ;
*		else
*			retv = EINVAL;
*		break;
*	case IEEE80211_PARAM_MCAST_RATE:
*		// units are in KILObits per second
*		if (value >= 256 && value <= 54000)
*			vap->iv_mcast_rate = value;
*		else
*			retv = EINVAL;
*		break;
*	case IEEE80211_PARAM_COVERAGE_CLASS:
*		if (value >= 0 && value <= IEEE80211_COVERAGE_CLASS_MAX) {
*			ic->ic_coverageclass = value;
*			if (IS_UP_AUTO(vap))
*				ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
*			retv = 0;
*		}
*		else
*			retv = EINVAL;
*		break;
*	case IEEE80211_PARAM_COUNTRY_IE:
*		if (value)
*			ic->ic_flags_ext |= IEEE80211_FEXT_COUNTRYIE;
*		else
*			ic->ic_flags_ext &= ~IEEE80211_FEXT_COUNTRYIE;
*		retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_REGCLASS:
*		if (value)
*			ic->ic_flags_ext |= IEEE80211_FEXT_REGCLASS;
*		else
*			ic->ic_flags_ext &= ~IEEE80211_FEXT_REGCLASS;
*		retv = ENETRESET;
*		break;
*	case IEEE80211_PARAM_SCANVALID:
*		vap->iv_scanvalid = value*HZ;
*		break;
*	case IEEE80211_PARAM_ROAM_RSSI_11A:
*		vap->iv_roam.rssi11a = value;
*		break;
*	case IEEE80211_PARAM_ROAM_RSSI_11B:
*		vap->iv_roam.rssi11bOnly = value;
*		break;
*	case IEEE80211_PARAM_ROAM_RSSI_11G:
*		vap->iv_roam.rssi11b = value;
*		break;
*	case IEEE80211_PARAM_ROAM_RATE_11A:
*		vap->iv_roam.rate11a = value;
*		break;
*	case IEEE80211_PARAM_ROAM_RATE_11B:
*		vap->iv_roam.rate11bOnly = value;
*		break;
*	case IEEE80211_PARAM_ROAM_RATE_11G:
*		vap->iv_roam.rate11b = value;
*		break;
*	case IEEE80211_PARAM_UAPSDINFO:
*		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
*			if (ic->ic_caps & IEEE80211_C_UAPSD) {
*				if (value)
*					IEEE80211_VAP_UAPSD_ENABLE(vap);
*				else
*					IEEE80211_VAP_UAPSD_DISABLE(vap);
*				retv = ENETRESET;
*			}
*		}
*		else if (vap->iv_opmode == IEEE80211_M_STA) {
*			vap->iv_uapsdinfo = value;
*			IEEE80211_VAP_UAPSD_ENABLE(vap);
*			retv = ENETRESET;
*		}
*		break;
*	case IEEE80211_PARAM_SLEEP:
*		// XXX: Forced sleep for testing. Does not actually place the
*		//      HW in sleep mode yet. this only makes sense for STAs.
*
*		if (value) {
*			// goto sleep
*			IEEE80211_VAP_GOTOSLEEP(vap);
*		}
*		else {
*			// wakeup
*			IEEE80211_VAP_WAKEUP(vap);
*		}
*		ieee80211_send_nulldata(ieee80211_ref_node(vap->iv_bss));
*		break;
*	case IEEE80211_PARAM_QOSNULL:
*		// Force a QoS Null for testing.
*		ieee80211_send_qosnulldata(vap->iv_bss, value);
*		break;
*	case IEEE80211_PARAM_PSPOLL:
*		// Force a PS-POLL for testing.
*		ieee80211_send_pspoll(vap->iv_bss);
*		break;
*	case IEEE80211_PARAM_EOSPDROP:
*		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
*			if (value) IEEE80211_VAP_EOSPDROP_ENABLE(vap);
*			else IEEE80211_VAP_EOSPDROP_DISABLE(vap);
*		}
*		break;
*	case IEEE80211_PARAM_MARKDFS:
*		if (value)
*			ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;
*		else
*			ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
*		break;
*	case IEEE80211_PARAM_CHANBW:
*		switch (value) {
*			case 0:
*				ic->ic_chanbwflag = 0;
*				break;
*			case 1:
*				ic->ic_chanbwflag = IEEE80211_CHAN_HALF;
*				break;
*			case 2:
*				ic->ic_chanbwflag = IEEE80211_CHAN_QUARTER;
*				break;
*			default:
*				retv = EINVAL;
*				break;
*		}
*		break;
*	case IEEE80211_PARAM_SHORTPREAMBLE:
*		if (value) {
*			ic->ic_caps |= IEEE80211_C_SHPREAMBLE;
*		} else {
*			ic->ic_caps &= ~IEEE80211_C_SHPREAMBLE;
*		}
*		retv = ENETRESET;
*		break;
*	default:
*		retv = EOPNOTSUPP;
*		break;
*	}
*	// XXX should any of these cause a rescan?
*	if (retv == ENETRESET)
*		retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
*	return -retv;
*}
*/

int usbdrvwext_setmode(struct net_device *dev, struct iw_request_info *info,
			void *w, char *extra)
{
	return 0;
}

int usbdrvwext_getmode(struct net_device *dev, struct iw_request_info *info,
			void *w, char *extra)
{
	/* struct usbdrv_private *macp = dev->ml_priv; */
	struct iw_point *wri = (struct iw_point *)extra;
	char mode[8];

	strcpy(mode, "11g");
	return copy_to_user(wri->pointer, mode, 6) ? -EFAULT : 0;
}

int zfLnxPrivateIoctl(struct net_device *dev, struct zdap_ioctl* zdreq)
{
	/* void* regp = macp->regp; */
	u16_t cmd;
	/* u32_t temp; */
	u32_t *p;
	u32_t i;

	cmd = zdreq->cmd;
	switch (cmd) {
	case ZM_IOCTL_REG_READ:
		zfiDbgReadReg(dev, zdreq->addr);
		break;
	case ZM_IOCTL_REG_WRITE:
		zfiDbgWriteReg(dev, zdreq->addr, zdreq->value);
		break;
	case ZM_IOCTL_MEM_READ:
		p = (u32_t *) bus_to_virt(zdreq->addr);
		printk(KERN_WARNING
				"usbdrv: read memory addr: 0x%08x value:"
				" 0x%08x\n", zdreq->addr, *p);
		break;
	case ZM_IOCTL_MEM_WRITE:
		p = (u32_t *) bus_to_virt(zdreq->addr);
		*p = zdreq->value;
		printk(KERN_WARNING
			"usbdrv : write value : 0x%08x to memory addr :"
			" 0x%08x\n", zdreq->value, zdreq->addr);
		break;
	case ZM_IOCTL_TALLY:
		zfiWlanShowTally(dev);
		if (zdreq->addr)
			zfiWlanResetTally(dev);
		break;
	case ZM_IOCTL_TEST:
		printk(KERN_WARNING
				"ZM_IOCTL_TEST:len=%d\n", zdreq->addr);
		/* zfiWlanReadReg(dev, 0x10f400); */
		/* zfiWlanReadReg(dev, 0x10f404); */
		printk(KERN_WARNING "IOCTL TEST\n");
		#if 1
		/* print packet */
		for (i = 0; i < zdreq->addr; i++) {
			if ((i&0x7) == 0)
				printk(KERN_WARNING "\n");
			printk(KERN_WARNING "%02X ",
					(unsigned char)zdreq->data[i]);
		}
		printk(KERN_WARNING "\n");
		#endif

		/* For Test?? 1 to 0 by CWYang(-) */
		#if 0
			struct sk_buff *s;

			/* Allocate a skb */
			s = alloc_skb(2000, GFP_ATOMIC);

			/* Copy data to skb */
			for (i = 0; i < zdreq->addr; i++)
				s->data[i] = zdreq->data[i];
			s->len = zdreq->addr;

			/* Call zfIdlRecv() */
			zfiRecv80211(dev, s, NULL);
		#endif
		break;
	/************************* ZDCONFIG ***************************/
	case ZM_IOCTL_FRAG:
		zfiWlanSetFragThreshold(dev, zdreq->addr);
		break;
	case ZM_IOCTL_RTS:
		zfiWlanSetRtsThreshold(dev, zdreq->addr);
		break;
	case ZM_IOCTL_SCAN:
		zfiWlanScan(dev);
		break;
	case ZM_IOCTL_KEY: {
		u8_t key[29];
		struct zsKeyInfo keyInfo;
		u32_t i;

		for (i = 0; i < 29; i++)
			key[i] = 0;

		for (i = 0; i < zdreq->addr; i++)
			key[i] = zdreq->data[i];

		printk(KERN_WARNING
			"key len=%d, key=%02x%02x%02x%02x%02x...\n",
			zdreq->addr, key[0], key[1], key[2], key[3], key[4]);

		keyInfo.keyLength = zdreq->addr;
		keyInfo.keyIndex = 0;
		keyInfo.flag = 0;
		keyInfo.key = key;
		zfiWlanSetKey(dev, keyInfo);
	}
		break;
	case ZM_IOCTL_RATE:
		zfiWlanSetTxRate(dev, zdreq->addr);
		break;
	case ZM_IOCTL_ENCRYPTION_MODE:
		zfiWlanSetEncryMode(dev, zdreq->addr);

		zfiWlanDisable(dev, 0);
		zfiWlanEnable(dev);
		break;
		/* CWYang(+) */
	case ZM_IOCTL_SIGNAL_STRENGTH: {
		u8_t buffer[2];
		zfiWlanQuerySignalInfo(dev, &buffer[0]);
		printk(KERN_WARNING
			"Current Signal Strength : %02d\n", buffer[0]);
	}
		break;
		/* CWYang(+) */
	case ZM_IOCTL_SIGNAL_QUALITY: {
		u8_t buffer[2];
		zfiWlanQuerySignalInfo(dev, &buffer[0]);
		printk(KERN_WARNING
			"Current Signal Quality : %02d\n", buffer[1]);
	}
		break;
	case ZM_IOCTL_SET_PIBSS_MODE:
		if (zdreq->addr == 1)
			zfiWlanSetWlanMode(dev, ZM_MODE_PSEUDO);
		else
			zfiWlanSetWlanMode(dev, ZM_MODE_INFRASTRUCTURE);

		zfiWlanDisable(dev, 0);
		zfiWlanEnable(dev);
		break;
	/********************* ZDCONFIG ***********************/
	default:
		printk(KERN_ERR "usbdrv: error command = %x\n", cmd);
		break;
	}

	return 0;
}

int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
{
	int ret = 0;
	u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	u8_t mac_addr[80];
	struct zsKeyInfo keyInfo;
	struct usbdrv_private *macp = dev->ml_priv;
	u16_t vapId = 0;
	int ii;

	/* zmw_get_wlan_dev(dev); */

	switch (zdparm->cmd) {
	case ZD_CMD_SET_ENCRYPT_KEY:
		/* Set up key information */
		keyInfo.keyLength = zdparm->u.crypt.key_len;
		keyInfo.keyIndex = zdparm->u.crypt.idx;
		if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
			/* AP Mode */
			keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR;
		} else
			keyInfo.flag = 0;
		keyInfo.key = zdparm->u.crypt.key;
		keyInfo.initIv = zdparm->u.crypt.seq;
		keyInfo.macAddr = (u16_t *)zdparm->sta_addr;

		/* Identify the MAC address information */
		if (memcmp(zdparm->sta_addr, bc_addr, sizeof(bc_addr)) == 0)
			keyInfo.flag |= ZM_KEY_FLAG_GK;
		else
			keyInfo.flag |= ZM_KEY_FLAG_PK;

		if (!strcmp(zdparm->u.crypt.alg, "NONE")) {
			/* u8_t zero_mac[]={0,0,0,0,0,0}; */

			/* Set key length to zero */
			keyInfo.keyLength = 0;

			/* del group key */
			if (zdparm->sta_addr[0] & 1) {
				/* if (macp->cardSetting.WPAIeLen==0)
				* { 802.1x dynamic WEP
				*    mDynKeyMode = 0;
				*    mKeyFormat[0] = 0;
				*    mPrivacyInvoked[0]=FALSE;
				*    mCap[0] &= ~CAP_PRIVACY;
				*    macp->cardSetting.EncryOnOff[0]=0;
				* }
				* mWpaBcKeyLen = mGkInstalled = 0;
				*/
			} else {
				/* if (memcmp(zero_mac,zdparm->sta_addr, 6)==0)
				* {
				*     mDynKeyMode=0;
				*    mKeyFormat[0]=0;
				*    pSetting->DynKeyMode=0;
				*    pSetting->EncryMode[0]=0;
				*    mDynKeyMode=0;
				* }
				*/
			}

			printk(KERN_ERR "Set Encryption Type NONE\n");
			return ret;
		} else if (!strcmp(zdparm->u.crypt.alg, "TKIP")) {
			zfiWlanSetEncryMode(dev, ZM_TKIP);
			/* //Linux Supplicant will inverse Tx/Rx key
			* //So we inverse it back, CWYang(+)
			* zfMemoryCopy(&temp[0], &keyInfo.key[16], 8);
			* zfMemoryCopy(&keyInfo.key[16], keyInfo.key[24], 8);
			* zfMemoryCopy(&keyInfo.key[24], &temp[0], 8);
			* u8_t temp;
			* int k;
			* for (k = 0; k < 8; k++)
			* {
			*     temp = keyInfo.key[16 + k];
			*     keyInfo.key[16 + k] = keyInfo.key[24 + k];
			*     keyInfo.key[24 + k] = temp;
			* }
			* CamEncryType = ZM_TKIP;
			* if (idx == 0)
			* {   // Pairwise key
			*     mKeyFormat[0] = CamEncryType;
			*     mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_TKIP;
			* }
			*/
		} else if (!strcmp(zdparm->u.crypt.alg, "CCMP")) {
			zfiWlanSetEncryMode(dev, ZM_AES);
			/* CamEncryType = ZM_AES;
			* if (idx == 0)
			* {  // Pairwise key
			*    mKeyFormat[0] = CamEncryType;
			*    mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_AES;
			* }
			*/
		} else if (!strcmp(zdparm->u.crypt.alg, "WEP")) {
			if (keyInfo.keyLength == 5) {
				/* WEP 64 */
				zfiWlanSetEncryMode(dev, ZM_WEP64);
				/* CamEncryType = ZM_WEP64; */
				/* tmpDynKeyMode=DYN_KEY_WEP64; */
			} else if (keyInfo.keyLength == 13) {
				/* keylen=13, WEP 128 */
				zfiWlanSetEncryMode(dev, ZM_WEP128);
				/* CamEncryType = ZM_WEP128; */
				/* tmpDynKeyMode=DYN_KEY_WEP128; */
			} else {
				zfiWlanSetEncryMode(dev, ZM_WEP256);
			}

	/* For Dynamic WEP key (Non-WPA Radius), the key ID range: 0-3
	* In WPA/RSN mode, the key ID range: 1-3, usually, a broadcast key.
	* For WEP key setting: we set mDynKeyMode and mKeyFormat in following
	* case:
	*   1. For 802.1x dynamically generated WEP key method.
	*   2. For WPA/RSN mode, but key id == 0.
	*	(But this is an impossible case)
	* So, only check case 1.
	* if (macp->cardSetting.WPAIeLen==0)
	* {
	*    mKeyFormat[0] = CamEncryType;
	*    mDynKeyMode = pSetting->DynKeyMode = tmpDynKeyMode;
	*    mPrivacyInvoked[0]=TRUE;
	*    mCap[0] |= CAP_PRIVACY;
	*    macp->cardSetting.EncryOnOff[0]=1;
	* }
	*/
		}

		/* DUMP key context */
		/* #ifdef WPA_DEBUG */
		if (keyInfo.keyLength > 0) {
			printk(KERN_WARNING
						"Otus: Key Context:\n");
			for (ii = 0; ii < keyInfo.keyLength; ) {
				printk(KERN_WARNING
						"0x%02x ", keyInfo.key[ii]);
				if ((++ii % 16) == 0)
					printk(KERN_WARNING "\n");
			}
			printk(KERN_WARNING "\n");
		}
		/* #endif */

		/* Set encrypt mode */
		/* zfiWlanSetEncryMode(dev, CamEncryType); */
		vapId = zfLnxGetVapId(dev);
		if (vapId == 0xffff)
			keyInfo.vapId = 0;
		else
			keyInfo.vapId = vapId + 1;
		keyInfo.vapAddr[0] = keyInfo.macAddr[0];
		keyInfo.vapAddr[1] = keyInfo.macAddr[1];
		keyInfo.vapAddr[2] = keyInfo.macAddr[2];

		zfiWlanSetKey(dev, keyInfo);

		/* zfiWlanDisable(dev); */
		/* zfiWlanEnable(dev); */
		break;
	case ZD_CMD_SET_MLME:
		printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_MLME\n");

		/* Translate STA's address */
		sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
			zdparm->sta_addr[0], zdparm->sta_addr[1],
			zdparm->sta_addr[2], zdparm->sta_addr[3],
			zdparm->sta_addr[4], zdparm->sta_addr[5]);

		switch (zdparm->u.mlme.cmd) {
		case MLME_STA_DEAUTH:
			printk(KERN_WARNING
				" -------Call zfiWlanDeauth, reason:%d\n",
				zdparm->u.mlme.reason_code);
			if (zfiWlanDeauth(dev, (u16_t *) zdparm->sta_addr,
				zdparm->u.mlme.reason_code) != 0)
				printk(KERN_ERR "Can't deauthencate STA: %s\n",
					mac_addr);
			else
				printk(KERN_ERR "Deauthenticate STA: %s"
					"with reason code: %d\n",
					mac_addr, zdparm->u.mlme.reason_code);
			break;
		case MLME_STA_DISASSOC:
			printk(KERN_WARNING
				" -------Call zfiWlanDeauth, reason:%d\n",
				zdparm->u.mlme.reason_code);
			if (zfiWlanDeauth(dev, (u16_t *) zdparm->sta_addr,
				zdparm->u.mlme.reason_code) != 0)
				printk(KERN_ERR "Can't disassociate STA: %s\n",
					mac_addr);
			else
				printk(KERN_ERR "Disassociate STA: %s"
					"with reason code: %d\n",
					mac_addr, zdparm->u.mlme.reason_code);
			break;
		default:
			printk(KERN_ERR "MLME command: 0x%04x not support\n",
				zdparm->u.mlme.cmd);
			break;
		}

		break;
	case ZD_CMD_SCAN_REQ:
		printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
		break;
	case ZD_CMD_SET_GENERIC_ELEMENT:
		printk(KERN_ERR "usbdrv_wpa_ioctl:"
					" ZD_CMD_SET_GENERIC_ELEMENT\n");

		/* Copy the WPA IE
		* zm_msg1_mm(ZM_LV_0, "CWY - wpaie Length : ",
		* zdparm->u.generic_elem.len);
		*/
		printk(KERN_ERR "wpaie Length : % d\n",
						zdparm->u.generic_elem.len);
		if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
			/* AP Mode */
			zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
					zdparm->u.generic_elem.len);
		} else {
			macp->supLen = zdparm->u.generic_elem.len;
			memcpy(macp->supIe, zdparm->u.generic_elem.data,
				zdparm->u.generic_elem.len);
		}
		zfiWlanSetWpaSupport(dev, 1);
		/* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
		* zdparm->u.generic_elem.len);
		*/
		u8_t len = zdparm->u.generic_elem.len;
		u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;

		printk(KERN_ERR "wd->ap.wpaLen : % d\n", len);

		/* DUMP WPA IE */
		for(ii = 0; ii < len;) {
			printk(KERN_ERR "0x%02x ", wpaie[ii]);

			if((++ii % 16) == 0)
				printk(KERN_ERR "\n");
		}
		printk(KERN_ERR "\n");

		/* #ifdef ZM_HOSTAPD_SUPPORT
		* if (wd->wlanMode == ZM_MODE_AP)
		* {// Update Beacon FIFO in the next TBTT.
		*     memcpy(&mWPAIe, pSetting->WPAIe, pSetting->WPAIeLen);
		*     printk(KERN_ERR "Copy WPA IE into mWPAIe\n");
		* }
		* #endif
		*/
		break;

	/* #ifdef ZM_HOSTAPD_SUPPORT */
	case ZD_CMD_GET_TSC:
		printk(KERN_ERR "usbdrv_wpa_ioctl : ZD_CMD_GET_TSC\n");
		break;
	/* #endif */

	default:
		printk(KERN_ERR "usbdrv_wpa_ioctl default : 0x%04x\n",
			zdparm->cmd);
		ret = -EINVAL;
		break;
	}

	return ret;
}

#ifdef ZM_ENABLE_CENC
int usbdrv_cenc_ioctl(struct net_device *dev, struct zydas_cenc_param *zdparm)
{
	/* struct usbdrv_private *macp = dev->ml_priv; */
	struct zsKeyInfo keyInfo;
	u16_t apId;
	u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	int ret = 0;
	int ii;

	/* Get the AP Id */
	apId = zfLnxGetVapId(dev);

	if (apId == 0xffff) {
		apId = 0;
	} else {
		apId = apId + 1;
	}

	switch (zdparm->cmd) {
	case ZM_CMD_CENC_SETCENC:
		printk(KERN_ERR "ZM_CMD_CENC_SETCENC\n");
		printk(KERN_ERR "length : % d\n", zdparm->len);
		printk(KERN_ERR "policy : % d\n", zdparm->u.info.cenc_policy);
		break;
	case ZM_CMD_CENC_SETKEY:
		/* ret = wai_ioctl_setkey(vap, ioctl_msg); */
		printk(KERN_ERR "ZM_CMD_CENC_SETKEY\n");

		printk(KERN_ERR "MAC address = ");
		for (ii = 0; ii < 6; ii++) {
			printk(KERN_ERR "0x%02x ",
				zdparm->u.crypt.sta_addr[ii]);
		}
		printk(KERN_ERR "\n");

		printk(KERN_ERR "Key Index : % d\n", zdparm->u.crypt.keyid);
		printk(KERN_ERR "Encryption key = ");
		for (ii = 0; ii < 16; ii++) {
			printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
		}
		printk(KERN_ERR "\n");

		printk(KERN_ERR "MIC key = ");
		for(ii = 16; ii < ZM_CENC_KEY_SIZE; ii++) {
			printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
		}
		printk(KERN_ERR "\n");

		/* Set up key information */
		keyInfo.keyLength = ZM_CENC_KEY_SIZE;
		keyInfo.keyIndex = zdparm->u.crypt.keyid;
		keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR | ZM_KEY_FLAG_CENC;
		keyInfo.key = zdparm->u.crypt.key;
		keyInfo.macAddr = (u16_t *)zdparm->u.crypt.sta_addr;

		/* Identify the MAC address information */
		if (memcmp(zdparm->u.crypt.sta_addr, bc_addr,
				sizeof(bc_addr)) == 0) {
			keyInfo.flag |= ZM_KEY_FLAG_GK;
			keyInfo.vapId = apId;
			memcpy(keyInfo.vapAddr, dev->dev_addr, ETH_ALEN);
		} else {
			keyInfo.flag |= ZM_KEY_FLAG_PK;
		}

		zfiWlanSetKey(dev, keyInfo);

		break;
	case ZM_CMD_CENC_REKEY:
		/* ret = wai_ioctl_rekey(vap, ioctl_msg); */
		printk(KERN_ERR "ZM_CMD_CENC_REKEY\n");
		break;
	default:
		ret = -EOPNOTSUPP;
		break;
	}

	/* if (retv == ENETRESET) */
	/* retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0; */

	return ret;
}
#endif /* ZM_ENABLE_CENC */

int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	/* struct usbdrv_private *macp; */
	/* void *regp; */
	struct zdap_ioctl zdreq;
	struct iwreq *wrq = (struct iwreq *)ifr;
	struct athr_wlan_param zdparm;
	struct usbdrv_private *macp = dev->ml_priv;

	int err = 0, val = 0;
	int changed = 0;

	/* regp = macp->regp; */

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

	switch (cmd) {
	case SIOCGIWNAME:
		strcpy(wrq->u.name, "IEEE 802.11-DS");
		break;
	case SIOCGIWAP:
		err = usbdrvwext_giwap(dev, NULL, &wrq->u.ap_addr, NULL);
		break;
	case SIOCSIWAP:
		err = usbdrvwext_siwap(dev, NULL, &wrq->u.ap_addr, NULL);
		break;
	case SIOCGIWMODE:
		err = usbdrvwext_giwmode(dev, NULL, &wrq->u.mode, NULL);
		break;
	case SIOCSIWESSID:
		printk(KERN_ERR "CWY - usbdrvwext_siwessid\n");
		/* err = usbdrv_ioctl_setessid(dev, &wrq->u.essid); */
		err = usbdrvwext_siwessid(dev, NULL, &wrq->u.essid, NULL);

		if (!err)
			changed = 1;
		break;
	case SIOCGIWESSID:
		err = usbdrvwext_giwessid(dev, NULL, &wrq->u.essid, NULL);
		break;
	case SIOCSIWRTS:
		err = usbdrv_ioctl_setrts(dev, &wrq->u.rts);
		if (! err)
			changed = 1;
		break;
	/* set_auth */
	case SIOCIWFIRSTPRIV + 0x2: {
		/* printk("CWY - SIOCIWFIRSTPRIV + 0x2(set_auth)\n"); */
		if (!capable(CAP_NET_ADMIN)) {
			err = -EPERM;
			break;
		}
		val = *((int *) wrq->u.name);
		if ((val < 0) || (val > 2)) {
			err = -EINVAL;
			break;
		} else {
			zfiWlanSetAuthenticationMode(dev, val);

			if (macp->DeviceOpened == 1) {
				zfiWlanDisable(dev, 0);
				zfiWlanEnable(dev);
			}

			err = 0;
			changed = 1;
		}
	}
		break;
	/* get_auth */
	case SIOCIWFIRSTPRIV + 0x3: {
		int AuthMode = ZM_AUTH_MODE_OPEN;

		/* printk("CWY - SIOCIWFIRSTPRIV + 0x3(get_auth)\n"); */

		if (wrq->u.data.pointer) {
			wrq->u.data.flags = 1;

			AuthMode = zfiWlanQueryAuthenticationMode(dev, 0);
			if (AuthMode == ZM_AUTH_MODE_OPEN) {
				wrq->u.data.length = 12;

				if (copy_to_user(wrq->u.data.pointer,
					"open system", 12)) {
						return -EFAULT;
				}
			} else if (AuthMode == ZM_AUTH_MODE_SHARED_KEY)	{
				wrq->u.data.length = 11;

				if (copy_to_user(wrq->u.data.pointer,
					"shared key", 11)) {
							return -EFAULT;
				}
			} else if (AuthMode == ZM_AUTH_MODE_AUTO) {
				wrq->u.data.length = 10;

				if (copy_to_user(wrq->u.data.pointer,
					"auto mode", 10)) {
							return -EFAULT;
				}
			} else {
				return -EFAULT;
			}
		}
	}
		break;
	/* debug command */
	case ZDAPIOCTL:
		if (copy_from_user(&zdreq, ifr->ifr_data, sizeof(zdreq))) {
			printk(KERN_ERR "usbdrv : copy_from_user error\n");
			return -EFAULT;
		}

		/* printk(KERN_WARNING
		* "usbdrv : cmd = % 2x, reg = 0x%04lx,
		*value = 0x%08lx\n",
		* zdreq.cmd, zdreq.addr, zdreq.value);
		*/
		zfLnxPrivateIoctl(dev, &zdreq);

		err = 0;
		break;
	case ZD_IOCTL_WPA:
		if (copy_from_user(&zdparm, ifr->ifr_data,
			sizeof(struct athr_wlan_param))) {
			printk(KERN_ERR "usbdrv : copy_from_user error\n");
			return -EFAULT;
		}

		usbdrv_wpa_ioctl(dev, &zdparm);
		err = 0;
		break;
	case ZD_IOCTL_PARAM: {
		int *p;
		int op;
		int arg;

		/* Point to the name field and retrieve the
		* op and arg elements.
		*/
		p = (int *)wrq->u.name;
		op = *p++;
		arg = *p;

		if (op == ZD_PARAM_ROAMING) {
			printk(KERN_ERR
			"*************ZD_PARAM_ROAMING : % d\n", arg);
			/* macp->cardSetting.ap_scan=(U8)arg; */
		}
		if (op == ZD_PARAM_PRIVACY) {
			printk(KERN_ERR "ZD_IOCTL_PRIVACY : ");

			/* Turn on the privacy invoke flag */
			if (arg) {
				/* mCap[0] |= CAP_PRIVACY; */
				/* macp->cardSetting.EncryOnOff[0] = 1; */
				printk(KERN_ERR "enable\n");

			} else {
				/* mCap[0] &= ~CAP_PRIVACY; */
				/* macp->cardSetting.EncryOnOff[0] = 0; */
				printk(KERN_ERR "disable\n");
			}
			/* changed=1; */
		}
		if (op == ZD_PARAM_WPA) {

		printk(KERN_ERR "ZD_PARAM_WPA : ");

		if (arg) {
			printk(KERN_ERR "enable\n");

			if (zfiWlanQueryWlanMode(dev) != ZM_MODE_AP) {
				printk(KERN_ERR "Station Mode\n");
				/* zfiWlanQueryWpaIe(dev, (u8_t *)
					&wpaIe, &wpalen); */
				/* printk("wpaIe : % 2x, % 2x, % 2x\n",
					wpaIe[21], wpaIe[22], wpaIe[23]); */
				/* printk("rsnIe : % 2x, % 2x, % 2x\n",
					wpaIe[17], wpaIe[18], wpaIe[19]); */
				if ((macp->supIe[21] == 0x50) &&
					(macp->supIe[22] == 0xf2) &&
					(macp->supIe[23] == 0x2)) {
					printk(KERN_ERR
				"wd->sta.authMode = ZM_AUTH_MODE_WPAPSK\n");
				/* wd->sta.authMode = ZM_AUTH_MODE_WPAPSK; */
				/* wd->ws.authMode = ZM_AUTH_MODE_WPAPSK; */
				zfiWlanSetAuthenticationMode(dev,
							ZM_AUTH_MODE_WPAPSK);
				} else if ((macp->supIe[21] == 0x50) &&
					(macp->supIe[22] == 0xf2) &&
					(macp->supIe[23] == 0x1)) {
					printk(KERN_ERR
				"wd->sta.authMode = ZM_AUTH_MODE_WPA\n");
				/* wd->sta.authMode = ZM_AUTH_MODE_WPA; */
				/* wd->ws.authMode = ZM_AUTH_MODE_WPA; */
				zfiWlanSetAuthenticationMode(dev,
							ZM_AUTH_MODE_WPA);
					} else if ((macp->supIe[17] == 0xf) &&
						(macp->supIe[18] == 0xac) &&
						(macp->supIe[19] == 0x2))
					{
						printk(KERN_ERR
				"wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK\n");
				/* wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK; */
				/* wd->ws.authMode = ZM_AUTH_MODE_WPA2PSK; */
				zfiWlanSetAuthenticationMode(dev,
				ZM_AUTH_MODE_WPA2PSK);
			} else if ((macp->supIe[17] == 0xf) &&
				(macp->supIe[18] == 0xac) &&
				(macp->supIe[19] == 0x1))
				{
					printk(KERN_ERR
				"wd->sta.authMode = ZM_AUTH_MODE_WPA2\n");
				/* wd->sta.authMode = ZM_AUTH_MODE_WPA2; */
				/* wd->ws.authMode = ZM_AUTH_MODE_WPA2; */
				zfiWlanSetAuthenticationMode(dev,
							ZM_AUTH_MODE_WPA2);
			}
			/* WPA or WPAPSK */
			if ((macp->supIe[21] == 0x50) ||
				(macp->supIe[22] == 0xf2)) {
				if (macp->supIe[11] == 0x2) {
					printk(KERN_ERR
				"wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
				/* wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; */
				/* wd->ws.wepStatus = ZM_ENCRYPTION_TKIP; */
				zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
			} else {
				printk(KERN_ERR
				"wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
				/* wd->sta.wepStatus = ZM_ENCRYPTION_AES; */
				/* wd->ws.wepStatus = ZM_ENCRYPTION_AES; */
				zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
				}
			}
			//WPA2 or WPA2PSK
			if ((macp->supIe[17] == 0xf) ||
				(macp->supIe[18] == 0xac)) {
				if (macp->supIe[13] == 0x2) {
					printk(KERN_ERR
				"wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
				/* wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; */
				/* wd->ws.wepStatus = ZM_ENCRYPTION_TKIP; */
				zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
				} else {
					printk(KERN_ERR
				"wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
				/* wd->sta.wepStatus = ZM_ENCRYPTION_AES; */
				/* wd->ws.wepStatus = ZM_ENCRYPTION_AES; */
				zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
					}
				}
			}
			zfiWlanSetWpaSupport(dev, 1);
		} else {
			/* Reset the WPA related variables */
			printk(KERN_ERR "disable\n");

			zfiWlanSetWpaSupport(dev, 0);
			zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_OPEN);
			zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_WEP_DISABLED);

			/* Now we only set the length in the WPA IE
			* field to zero.
			*macp->cardSetting.WPAIe[1] = 0;
			*/
			}
		}

		if (op == ZD_PARAM_COUNTERMEASURES) {
			printk(KERN_ERR
				"****************ZD_PARAM_COUNTERMEASURES : ");

			if(arg) {
				/*    mCounterMeasureState=1; */
				printk(KERN_ERR "enable\n");
			} else {
				/*    mCounterMeasureState=0; */
				printk(KERN_ERR "disable\n");
			}
		}
		if (op == ZD_PARAM_DROPUNENCRYPTED) {
			printk(KERN_ERR "ZD_PARAM_DROPUNENCRYPTED : ");

			if(arg) {
				printk(KERN_ERR "enable\n");
			} else {
				printk(KERN_ERR "disable\n");
			}
		}
		if (op == ZD_PARAM_AUTH_ALGS) {
			printk(KERN_ERR "ZD_PARAM_AUTH_ALGS : ");

			if (arg == 0) {
				printk(KERN_ERR "OPEN_SYSTEM\n");
			} else {
				printk(KERN_ERR "SHARED_KEY\n");
			}
		}
		if (op == ZD_PARAM_WPS_FILTER) {
			printk(KERN_ERR "ZD_PARAM_WPS_FILTER : ");

			if (arg) {
				/*    mCounterMeasureState=1; */
				macp->forwardMgmt = 1;
				printk(KERN_ERR "enable\n");
			} else {
				/*    mCounterMeasureState=0; */
				macp->forwardMgmt = 0;
				printk(KERN_ERR "disable\n");
			}
		}
	}
		err = 0;
		break;
	case ZD_IOCTL_GETWPAIE: {
		struct ieee80211req_wpaie req_wpaie;
		u16_t apId, i, j;

		/* Get the AP Id */
		apId = zfLnxGetVapId(dev);

		if (apId == 0xffff) {
			apId = 0;
		} else {
			apId = apId + 1;
		}

		if (copy_from_user(&req_wpaie, ifr->ifr_data,
					sizeof(struct ieee80211req_wpaie))) {
			printk(KERN_ERR "usbdrv : copy_from_user error\n");
			return -EFAULT;
		}

		for (i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++) {
			for (j = 0; j < IEEE80211_ADDR_LEN; j++) {
				if (macp->stawpaie[i].wpa_macaddr[j] !=
						req_wpaie.wpa_macaddr[j])
				break;
			}
			if (j == 6)
			break;
		}

		if (i < ZM_OAL_MAX_STA_SUPPORT) {
		/* printk("ZD_IOCTL_GETWPAIE - sta index = % d\n", i); */
		memcpy(req_wpaie.wpa_ie, macp->stawpaie[i].wpa_ie,
							IEEE80211_MAX_IE_SIZE);
		}

		if (copy_to_user(wrq->u.data.pointer, &req_wpaie,
				sizeof(struct ieee80211req_wpaie))) {
			return -EFAULT;
		}
	}

		err = 0;
		break;
	#ifdef ZM_ENABLE_CENC
	case ZM_IOCTL_CENC:
		if (copy_from_user(&macp->zd_wpa_req, ifr->ifr_data,
			sizeof(struct athr_wlan_param))) {
			printk(KERN_ERR "usbdrv : copy_from_user error\n");
			return -EFAULT;
		}

		usbdrv_cenc_ioctl(dev,
				(struct zydas_cenc_param *)&macp->zd_wpa_req);
		err = 0;
		break;
	#endif /* ZM_ENABLE_CENC */
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}
