// SPDX-License-Identifier: GPL-2.0
/*
 *   Driver for KeyStream wireless LAN cards.
 *
 *   Copyright (C) 2005-2008 KeyStream Corp.
 *   Copyright (C) 2009 Renesas Technology Corp.
 */

#include <linux/circ_buf.h>
#include <linux/if_arp.h>
#include <net/iw_handler.h>
#include <uapi/linux/llc.h>
#include "eap_packet.h"
#include "ks_wlan.h"
#include "michael_mic.h"
#include "ks_hostif.h"

static inline void inc_smeqhead(struct ks_wlan_private *priv)
{
	priv->sme_i.qhead = (priv->sme_i.qhead + 1) % SME_EVENT_BUFF_SIZE;
}

static inline void inc_smeqtail(struct ks_wlan_private *priv)
{
	priv->sme_i.qtail = (priv->sme_i.qtail + 1) % SME_EVENT_BUFF_SIZE;
}

static inline unsigned int cnt_smeqbody(struct ks_wlan_private *priv)
{
	return CIRC_CNT_TO_END(priv->sme_i.qhead, priv->sme_i.qtail,
			       SME_EVENT_BUFF_SIZE);
}

static inline u8 get_byte(struct ks_wlan_private *priv)
{
	u8 data;

	data = *(priv->rxp)++;
	/* length check in advance ! */
	--(priv->rx_size);
	return data;
}

static inline u16 get_word(struct ks_wlan_private *priv)
{
	u16 data;

	data = (get_byte(priv) & 0xff);
	data |= ((get_byte(priv) << 8) & 0xff00);
	return data;
}

static inline u32 get_dword(struct ks_wlan_private *priv)
{
	u32 data;

	data = (get_byte(priv) & 0xff);
	data |= ((get_byte(priv) << 8) & 0x0000ff00);
	data |= ((get_byte(priv) << 16) & 0x00ff0000);
	data |= ((get_byte(priv) << 24) & 0xff000000);
	return data;
}

static void ks_wlan_hw_wakeup_task(struct work_struct *work)
{
	struct ks_wlan_private *priv;
	int ps_status;
	long time_left;

	priv = container_of(work, struct ks_wlan_private, wakeup_work);
	ps_status = atomic_read(&priv->psstatus.status);

	if (ps_status == PS_SNOOZE) {
		ks_wlan_hw_wakeup_request(priv);
		time_left = wait_for_completion_interruptible_timeout(
				&priv->psstatus.wakeup_wait,
				msecs_to_jiffies(20));
		if (time_left <= 0) {
			netdev_dbg(priv->net_dev, "wake up timeout or interrupted !!!\n");
			schedule_work(&priv->wakeup_work);
			return;
		}
	}

	/* power save */
	if (atomic_read(&priv->sme_task.count) > 0)
		tasklet_enable(&priv->sme_task);
}

static void ks_wlan_do_power_save(struct ks_wlan_private *priv)
{
	if (is_connect_status(priv->connect_status))
		hostif_sme_enqueue(priv, SME_POW_MNGMT_REQUEST);
	else
		priv->dev_state = DEVICE_STATE_READY;
}

static
int get_current_ap(struct ks_wlan_private *priv, struct link_ap_info *ap_info)
{
	struct local_ap *ap;
	union iwreq_data wrqu;
	struct net_device *netdev = priv->net_dev;
	u8 size;

	ap = &priv->current_ap;

	if (is_disconnect_status(priv->connect_status)) {
		memset(ap, 0, sizeof(struct local_ap));
		return -EPERM;
	}

	ether_addr_copy(ap->bssid, ap_info->bssid);
	memcpy(ap->ssid.body, priv->reg.ssid.body,
	       priv->reg.ssid.size);
	ap->ssid.size = priv->reg.ssid.size;
	memcpy(ap->rate_set.body, ap_info->rate_set.body,
	       ap_info->rate_set.size);
	ap->rate_set.size = ap_info->rate_set.size;
	if (ap_info->ext_rate_set.size != 0) {
		memcpy(&ap->rate_set.body[ap->rate_set.size],
		       ap_info->ext_rate_set.body,
		       ap_info->ext_rate_set.size);
		ap->rate_set.size += ap_info->ext_rate_set.size;
	}
	ap->channel = ap_info->ds_parameter.channel;
	ap->rssi = ap_info->rssi;
	ap->sq = ap_info->sq;
	ap->noise = ap_info->noise;
	ap->capability = le16_to_cpu(ap_info->capability);
	size = (ap_info->rsn.size <= RSN_IE_BODY_MAX) ?
		ap_info->rsn.size : RSN_IE_BODY_MAX;
	if ((ap_info->rsn_mode & RSN_MODE_WPA2) &&
	    (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)) {
		ap->rsn_ie.id = RSN_INFO_ELEM_ID;
		ap->rsn_ie.size = size;
		memcpy(ap->rsn_ie.body, ap_info->rsn.body, size);
	} else if ((ap_info->rsn_mode & RSN_MODE_WPA) &&
		   (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA)) {
		ap->wpa_ie.id = WPA_INFO_ELEM_ID;
		ap->wpa_ie.size = size;
		memcpy(ap->wpa_ie.body, ap_info->rsn.body, size);
	} else {
		ap->rsn_ie.id = 0;
		ap->rsn_ie.size = 0;
		ap->wpa_ie.id = 0;
		ap->wpa_ie.size = 0;
	}

	wrqu.data.length = 0;
	wrqu.data.flags = 0;
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
	if (is_connect_status(priv->connect_status)) {
		ether_addr_copy(wrqu.ap_addr.sa_data, priv->current_ap.bssid);
		netdev_dbg(priv->net_dev,
			   "IWEVENT: connect bssid=%pM\n",
			   wrqu.ap_addr.sa_data);
		wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
	}
	netdev_dbg(priv->net_dev, "Link AP\n"
		   "- bssid=%02X:%02X:%02X:%02X:%02X:%02X\n"
		   "- essid=%s\n"
		   "- rate_set=%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X\n"
		   "- channel=%d\n"
		   "- rssi=%d\n"
		   "- sq=%d\n"
		   "- capability=%04X\n"
		   "- rsn.mode=%d\n"
		   "- rsn.size=%d\n"
		   "- ext_rate_set_size=%d\n"
		   "- rate_set_size=%d\n",
		   ap->bssid[0], ap->bssid[1], ap->bssid[2],
		   ap->bssid[3], ap->bssid[4], ap->bssid[5],
		   &(ap->ssid.body[0]),
		   ap->rate_set.body[0], ap->rate_set.body[1],
		   ap->rate_set.body[2], ap->rate_set.body[3],
		   ap->rate_set.body[4], ap->rate_set.body[5],
		   ap->rate_set.body[6], ap->rate_set.body[7],
		   ap->channel, ap->rssi, ap->sq, ap->capability,
		   ap_info->rsn_mode, ap_info->rsn.size,
		   ap_info->ext_rate_set.size, ap_info->rate_set.size);

	return 0;
}

static u8 read_ie(unsigned char *bp, u8 max, u8 *body)
{
	u8 size = (*(bp + 1) <= max) ? *(bp + 1) : max;

	memcpy(body, bp + 2, size);
	return size;
}


static
int get_ap_information(struct ks_wlan_private *priv, struct ap_info *ap_info,
		       struct local_ap *ap)
{
	unsigned char *bp;
	int bsize, offset;

	memset(ap, 0, sizeof(struct local_ap));

	ether_addr_copy(ap->bssid, ap_info->bssid);
	ap->rssi = ap_info->rssi;
	ap->sq = ap_info->sq;
	ap->noise = ap_info->noise;
	ap->capability = le16_to_cpu(ap_info->capability);
	ap->channel = ap_info->ch_info;

	bp = ap_info->body;
	bsize = le16_to_cpu(ap_info->body_size);
	offset = 0;

	while (bsize > offset) {
		switch (*bp) { /* Information Element ID */
		case WLAN_EID_SSID:
			ap->ssid.size = read_ie(bp, IEEE80211_MAX_SSID_LEN,
						ap->ssid.body);
			break;
		case WLAN_EID_SUPP_RATES:
		case WLAN_EID_EXT_SUPP_RATES:
			if ((*(bp + 1) + ap->rate_set.size) <=
			    RATE_SET_MAX_SIZE) {
				memcpy(&ap->rate_set.body[ap->rate_set.size],
				       bp + 2, *(bp + 1));
				ap->rate_set.size += *(bp + 1);
			} else {
				memcpy(&ap->rate_set.body[ap->rate_set.size],
				       bp + 2,
				       RATE_SET_MAX_SIZE - ap->rate_set.size);
				ap->rate_set.size +=
				    (RATE_SET_MAX_SIZE - ap->rate_set.size);
			}
			break;
		case WLAN_EID_RSN:
			ap->rsn_ie.id = *bp;
			ap->rsn_ie.size = read_ie(bp, RSN_IE_BODY_MAX,
						  ap->rsn_ie.body);
			break;
		case WLAN_EID_VENDOR_SPECIFIC: /* WPA */
			/* WPA OUI check */
			if (memcmp(bp + 2, CIPHER_ID_WPA_WEP40, 4) == 0) {
				ap->wpa_ie.id = *bp;
				ap->wpa_ie.size = read_ie(bp, RSN_IE_BODY_MAX,
							  ap->wpa_ie.body);
			}
			break;
		case WLAN_EID_DS_PARAMS:
		case WLAN_EID_FH_PARAMS:
		case WLAN_EID_CF_PARAMS:
		case WLAN_EID_TIM:
		case WLAN_EID_IBSS_PARAMS:
		case WLAN_EID_COUNTRY:
		case WLAN_EID_ERP_INFO:
			break;
		default:
			netdev_err(priv->net_dev,
				   "unknown Element ID=%d\n", *bp);
			break;
		}

		offset += 2;	/* id & size field */
		offset += *(bp + 1);	/* +size offset */
		bp += (*(bp + 1) + 2);	/* pointer update */
	}

	return 0;
}

static
int hostif_data_indication_wpa(struct ks_wlan_private *priv,
			       unsigned short auth_type)
{
	struct ether_hdr *eth_hdr;
	unsigned short eth_proto;
	unsigned char recv_mic[8];
	char buf[128];
	unsigned long now;
	struct mic_failure *mic_failure;
	struct michael_mic michael_mic;
	union iwreq_data wrqu;
	unsigned int key_index = auth_type - 1;
	struct wpa_key *key = &priv->wpa.key[key_index];

	eth_hdr = (struct ether_hdr *)(priv->rxp);
	eth_proto = ntohs(eth_hdr->h_proto);

	if (eth_hdr->h_dest_snap != eth_hdr->h_source_snap) {
		netdev_err(priv->net_dev, "invalid data format\n");
		priv->nstats.rx_errors++;
		return -EINVAL;
	}
	if (((auth_type == TYPE_PMK1 &&
	      priv->wpa.pairwise_suite == IW_AUTH_CIPHER_TKIP) ||
	     (auth_type == TYPE_GMK1 &&
	      priv->wpa.group_suite == IW_AUTH_CIPHER_TKIP) ||
	     (auth_type == TYPE_GMK2 &&
	      priv->wpa.group_suite == IW_AUTH_CIPHER_TKIP)) &&
	    key->key_len) {
		netdev_dbg(priv->net_dev, "TKIP: protocol=%04X: size=%u\n",
			   eth_proto, priv->rx_size);
		/* MIC save */
		memcpy(&recv_mic[0], (priv->rxp) + ((priv->rx_size) - 8), 8);
		priv->rx_size = priv->rx_size - 8;
		if (auth_type > 0 && auth_type < 4) {	/* auth_type check */
			michael_mic_function(&michael_mic, key->rx_mic_key,
					     priv->rxp, priv->rx_size,
					     0,	michael_mic.result);
		}
		if (memcmp(michael_mic.result, recv_mic, 8) != 0) {
			now = jiffies;
			mic_failure = &priv->wpa.mic_failure;
			/* MIC FAILURE */
			if (mic_failure->last_failure_time &&
			    (now - mic_failure->last_failure_time) / HZ >= 60) {
				mic_failure->failure = 0;
			}
			netdev_err(priv->net_dev, "MIC FAILURE\n");
			if (mic_failure->failure == 0) {
				mic_failure->failure = 1;
				mic_failure->counter = 0;
			} else if (mic_failure->failure == 1) {
				mic_failure->failure = 2;
				mic_failure->counter =
					(u16)((now - mic_failure->last_failure_time) / HZ);
				/*  range 1-60 */
				if (!mic_failure->counter)
					mic_failure->counter = 1;
			}
			priv->wpa.mic_failure.last_failure_time = now;

			/*  needed parameters: count, keyid, key type, TSC */
			sprintf(buf,
				"MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=%pM)",
				key_index,
				eth_hdr->h_dest[0] & 0x01 ? "broad" : "uni",
				eth_hdr->h_source);
			memset(&wrqu, 0, sizeof(wrqu));
			wrqu.data.length = strlen(buf);
			wireless_send_event(priv->net_dev, IWEVCUSTOM, &wrqu,
					    buf);
			return -EINVAL;
		}
	}
	return 0;
}

static
void hostif_data_indication(struct ks_wlan_private *priv)
{
	unsigned int rx_ind_size;	/* indicate data size */
	struct sk_buff *skb;
	u16 auth_type;
	unsigned char temp[256];
	struct ether_hdr *eth_hdr;
	struct ieee802_1x_hdr *aa1x_hdr;
	size_t size;
	int ret;

	/* min length check */
	if (priv->rx_size <= ETH_HLEN) {
		priv->nstats.rx_errors++;
		return;
	}

	auth_type = get_word(priv);	/* AuthType */
	get_word(priv);	/* Reserve Area */

	eth_hdr = (struct ether_hdr *)(priv->rxp);

	/* source address check */
	if (ether_addr_equal(&priv->eth_addr[0], eth_hdr->h_source)) {
		netdev_err(priv->net_dev, "invalid : source is own mac address !!\n");
		netdev_err(priv->net_dev,
			   "eth_hdrernet->h_dest=%02X:%02X:%02X:%02X:%02X:%02X\n",
			   eth_hdr->h_source[0], eth_hdr->h_source[1],
			   eth_hdr->h_source[2], eth_hdr->h_source[3],
			   eth_hdr->h_source[4], eth_hdr->h_source[5]);
		priv->nstats.rx_errors++;
		return;
	}

	/*  for WPA */
	if (auth_type != TYPE_DATA && priv->wpa.rsn_enabled) {
		ret = hostif_data_indication_wpa(priv, auth_type);
		if (ret)
			return;
	}

	if ((priv->connect_status & FORCE_DISCONNECT) ||
	    priv->wpa.mic_failure.failure == 2) {
		return;
	}

	/* check 13th byte at rx data */
	switch (*(priv->rxp + 12)) {
	case LLC_SAP_SNAP:
		rx_ind_size = priv->rx_size - 6;
		skb = dev_alloc_skb(rx_ind_size);
		if (!skb) {
			priv->nstats.rx_dropped++;
			return;
		}
		netdev_dbg(priv->net_dev, "SNAP, rx_ind_size = %d\n",
			   rx_ind_size);

		size = ETH_ALEN * 2;
		skb_put_data(skb, priv->rxp, size);

		/* (SNAP+UI..) skip */

		size = rx_ind_size - (ETH_ALEN * 2);
		skb_put_data(skb, &eth_hdr->h_proto, size);

		aa1x_hdr = (struct ieee802_1x_hdr *)(priv->rxp + ETHER_HDR_SIZE);
		break;
	case LLC_SAP_NETBEUI:
		rx_ind_size = (priv->rx_size + 2);
		skb = dev_alloc_skb(rx_ind_size);
		if (!skb) {
			priv->nstats.rx_dropped++;
			return;
		}
		netdev_dbg(priv->net_dev, "NETBEUI/NetBIOS rx_ind_size=%d\n",
			   rx_ind_size);

		/* 8802/FDDI MAC copy */
		skb_put_data(skb, priv->rxp, 12);

		/* NETBEUI size add */
		temp[0] = (((rx_ind_size - 12) >> 8) & 0xff);
		temp[1] = ((rx_ind_size - 12) & 0xff);
		skb_put_data(skb, temp, 2);

		/* copy after Type */
		skb_put_data(skb, priv->rxp + 12, rx_ind_size - 14);

		aa1x_hdr = (struct ieee802_1x_hdr *)(priv->rxp + 14);
		break;
	default:	/* other rx data */
		netdev_err(priv->net_dev, "invalid data format\n");
		priv->nstats.rx_errors++;
		return;
	}

	if (aa1x_hdr->type == IEEE802_1X_TYPE_EAPOL_KEY &&
	    priv->wpa.rsn_enabled)
		atomic_set(&priv->psstatus.snooze_guard, 1);

	/* rx indication */
	skb->dev = priv->net_dev;
	skb->protocol = eth_type_trans(skb, skb->dev);
	priv->nstats.rx_packets++;
	priv->nstats.rx_bytes += rx_ind_size;
	netif_rx(skb);
}

static
void hostif_mib_get_confirm(struct ks_wlan_private *priv)
{
	struct net_device *dev = priv->net_dev;
	u32 mib_status;
	u32 mib_attribute;
	u16 mib_val_size;
	u16 mib_val_type;

	mib_status = get_dword(priv);
	mib_attribute = get_dword(priv);
	mib_val_size = get_word(priv);
	mib_val_type = get_word(priv);

	if (mib_status) {
		netdev_err(priv->net_dev, "attribute=%08X, status=%08X\n",
			   mib_attribute, mib_status);
		return;
	}

	switch (mib_attribute) {
	case DOT11_MAC_ADDRESS:
		hostif_sme_enqueue(priv, SME_GET_MAC_ADDRESS);
		ether_addr_copy(priv->eth_addr, priv->rxp);
		priv->mac_address_valid = true;
		ether_addr_copy(dev->dev_addr, priv->eth_addr);
		netdev_info(dev, "MAC ADDRESS = %pM\n", priv->eth_addr);
		break;
	case DOT11_PRODUCT_VERSION:
		priv->version_size = priv->rx_size;
		memcpy(priv->firmware_version, priv->rxp, priv->rx_size);
		priv->firmware_version[priv->rx_size] = '\0';
		netdev_info(dev, "firmware ver. = %s\n",
			    priv->firmware_version);
		hostif_sme_enqueue(priv, SME_GET_PRODUCT_VERSION);
		/* wake_up_interruptible_all(&priv->confirm_wait); */
		complete(&priv->confirm_wait);
		break;
	case LOCAL_GAIN:
		memcpy(&priv->gain, priv->rxp, sizeof(priv->gain));
		netdev_dbg(priv->net_dev, "tx_mode=%d, rx_mode=%d, tx_gain=%d, rx_gain=%d\n",
			   priv->gain.tx_mode, priv->gain.rx_mode,
			   priv->gain.tx_gain, priv->gain.rx_gain);
		break;
	case LOCAL_EEPROM_SUM:
		memcpy(&priv->eeprom_sum, priv->rxp, sizeof(priv->eeprom_sum));
		if (priv->eeprom_sum.type != 0 &&
		    priv->eeprom_sum.type != 1) {
			netdev_err(dev, "LOCAL_EEPROM_SUM error!\n");
			return;
		}
		priv->eeprom_checksum = (priv->eeprom_sum.type == 0) ?
					 EEPROM_CHECKSUM_NONE :
					 (priv->eeprom_sum.result == 0) ?
					 EEPROM_NG : EEPROM_OK;
		break;
	default:
		netdev_err(priv->net_dev, "mib_attribute=%08x\n",
			   (unsigned int)mib_attribute);
		break;
	}
}

static
void hostif_mib_set_confirm(struct ks_wlan_private *priv)
{
	u32 mib_status;
	u32 mib_attribute;

	mib_status = get_dword(priv);
	mib_attribute = get_dword(priv);

	if (mib_status) {
		/* in case of error */
		netdev_err(priv->net_dev, "error :: attribute=%08X, status=%08X\n",
			   mib_attribute, mib_status);
	}

	switch (mib_attribute) {
	case DOT11_RTS_THRESHOLD:
		hostif_sme_enqueue(priv, SME_RTS_THRESHOLD_CONFIRM);
		break;
	case DOT11_FRAGMENTATION_THRESHOLD:
		hostif_sme_enqueue(priv, SME_FRAGMENTATION_THRESHOLD_CONFIRM);
		break;
	case DOT11_WEP_DEFAULT_KEY_ID:
		if (!priv->wpa.wpa_enabled)
			hostif_sme_enqueue(priv, SME_WEP_INDEX_CONFIRM);
		break;
	case DOT11_WEP_DEFAULT_KEY_VALUE1:
		if (priv->wpa.rsn_enabled)
			hostif_sme_enqueue(priv, SME_SET_PMK_TSC);
		else
			hostif_sme_enqueue(priv, SME_WEP_KEY1_CONFIRM);
		break;
	case DOT11_WEP_DEFAULT_KEY_VALUE2:
		if (priv->wpa.rsn_enabled)
			hostif_sme_enqueue(priv, SME_SET_GMK1_TSC);
		else
			hostif_sme_enqueue(priv, SME_WEP_KEY2_CONFIRM);
		break;
	case DOT11_WEP_DEFAULT_KEY_VALUE3:
		if (priv->wpa.rsn_enabled)
			hostif_sme_enqueue(priv, SME_SET_GMK2_TSC);
		else
			hostif_sme_enqueue(priv, SME_WEP_KEY3_CONFIRM);
		break;
	case DOT11_WEP_DEFAULT_KEY_VALUE4:
		if (!priv->wpa.rsn_enabled)
			hostif_sme_enqueue(priv, SME_WEP_KEY4_CONFIRM);
		break;
	case DOT11_PRIVACY_INVOKED:
		if (!priv->wpa.rsn_enabled)
			hostif_sme_enqueue(priv, SME_WEP_FLAG_CONFIRM);
		break;
	case DOT11_RSN_ENABLED:
		hostif_sme_enqueue(priv, SME_RSN_ENABLED_CONFIRM);
		break;
	case LOCAL_RSN_MODE:
		hostif_sme_enqueue(priv, SME_RSN_MODE_CONFIRM);
		break;
	case LOCAL_MULTICAST_ADDRESS:
		hostif_sme_enqueue(priv, SME_MULTICAST_REQUEST);
		break;
	case LOCAL_MULTICAST_FILTER:
		hostif_sme_enqueue(priv, SME_MULTICAST_CONFIRM);
		break;
	case LOCAL_CURRENTADDRESS:
		priv->mac_address_valid = true;
		break;
	case DOT11_RSN_CONFIG_MULTICAST_CIPHER:
		hostif_sme_enqueue(priv, SME_RSN_MCAST_CONFIRM);
		break;
	case DOT11_RSN_CONFIG_UNICAST_CIPHER:
		hostif_sme_enqueue(priv, SME_RSN_UCAST_CONFIRM);
		break;
	case DOT11_RSN_CONFIG_AUTH_SUITE:
		hostif_sme_enqueue(priv, SME_RSN_AUTH_CONFIRM);
		break;
	case DOT11_GMK1_TSC:
		if (atomic_read(&priv->psstatus.snooze_guard))
			atomic_set(&priv->psstatus.snooze_guard, 0);
		break;
	case DOT11_GMK2_TSC:
		if (atomic_read(&priv->psstatus.snooze_guard))
			atomic_set(&priv->psstatus.snooze_guard, 0);
		break;
	case DOT11_PMK_TSC:
	case LOCAL_PMK:
	case LOCAL_GAIN:
	case LOCAL_WPS_ENABLE:
	case LOCAL_WPS_PROBE_REQ:
	case LOCAL_REGION:
	default:
		break;
	}
}

static
void hostif_power_mgmt_confirm(struct ks_wlan_private *priv)
{
	if (priv->reg.power_mgmt > POWER_MGMT_ACTIVE &&
	    priv->reg.operation_mode == MODE_INFRASTRUCTURE) {
		atomic_set(&priv->psstatus.confirm_wait, 0);
		priv->dev_state = DEVICE_STATE_SLEEP;
		ks_wlan_hw_power_save(priv);
	} else {
		priv->dev_state = DEVICE_STATE_READY;
	}
}

static
void hostif_sleep_confirm(struct ks_wlan_private *priv)
{
	atomic_set(&priv->sleepstatus.doze_request, 1);
	queue_delayed_work(priv->wq, &priv->rw_dwork, 1);
}

static
void hostif_start_confirm(struct ks_wlan_private *priv)
{
	union iwreq_data wrqu;

	wrqu.data.length = 0;
	wrqu.data.flags = 0;
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
	if (is_connect_status(priv->connect_status)) {
		eth_zero_addr(wrqu.ap_addr.sa_data);
		wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
	}
	netdev_dbg(priv->net_dev, " scan_ind_count=%d\n", priv->scan_ind_count);
	hostif_sme_enqueue(priv, SME_START_CONFIRM);
}

static
void hostif_connect_indication(struct ks_wlan_private *priv)
{
	u16 connect_code;
	unsigned int tmp = 0;
	unsigned int old_status = priv->connect_status;
	struct net_device *netdev = priv->net_dev;
	union iwreq_data wrqu0;

	connect_code = get_word(priv);

	switch (connect_code) {
	case RESULT_CONNECT:
		if (!(priv->connect_status & FORCE_DISCONNECT))
			netif_carrier_on(netdev);
		tmp = FORCE_DISCONNECT & priv->connect_status;
		priv->connect_status = tmp + CONNECT_STATUS;
		break;
	case RESULT_DISCONNECT:
		netif_carrier_off(netdev);
		tmp = FORCE_DISCONNECT & priv->connect_status;
		priv->connect_status = tmp + DISCONNECT_STATUS;
		break;
	default:
		netdev_dbg(priv->net_dev, "unknown connect_code=%d :: scan_ind_count=%d\n",
			   connect_code, priv->scan_ind_count);
		netif_carrier_off(netdev);
		tmp = FORCE_DISCONNECT & priv->connect_status;
		priv->connect_status = tmp + DISCONNECT_STATUS;
		break;
	}

	get_current_ap(priv, (struct link_ap_info *)priv->rxp);
	if (is_connect_status(priv->connect_status) &&
	    is_disconnect_status(old_status)) {
		/* for power save */
		atomic_set(&priv->psstatus.snooze_guard, 0);
		atomic_set(&priv->psstatus.confirm_wait, 0);
	}
	ks_wlan_do_power_save(priv);

	wrqu0.data.length = 0;
	wrqu0.data.flags = 0;
	wrqu0.ap_addr.sa_family = ARPHRD_ETHER;
	if (is_disconnect_status(priv->connect_status) &&
	    is_connect_status(old_status)) {
		eth_zero_addr(wrqu0.ap_addr.sa_data);
		netdev_dbg(priv->net_dev, "disconnect :: scan_ind_count=%d\n",
			   priv->scan_ind_count);
		wireless_send_event(netdev, SIOCGIWAP, &wrqu0, NULL);
	}
	priv->scan_ind_count = 0;
}

static
void hostif_scan_indication(struct ks_wlan_private *priv)
{
	int i;
	struct ap_info *ap_info;

	netdev_dbg(priv->net_dev,
		   "scan_ind_count = %d\n", priv->scan_ind_count);
	ap_info = (struct ap_info *)(priv->rxp);

	if (priv->scan_ind_count) {
		/* bssid check */
		for (i = 0; i < priv->aplist.size; i++) {
			u8 *bssid = priv->aplist.ap[i].bssid;

			if (ether_addr_equal(ap_info->bssid, bssid))
				continue;

			if (ap_info->frame_type == IEEE80211_STYPE_PROBE_RESP)
				get_ap_information(priv, ap_info,
						   &priv->aplist.ap[i]);
			return;
		}
	}
	priv->scan_ind_count++;
	if (priv->scan_ind_count < LOCAL_APLIST_MAX + 1) {
		netdev_dbg(priv->net_dev, " scan_ind_count=%d :: aplist.size=%d\n",
			priv->scan_ind_count, priv->aplist.size);
		get_ap_information(priv, (struct ap_info *)(priv->rxp),
				   &(priv->aplist.ap[priv->scan_ind_count - 1]));
		priv->aplist.size = priv->scan_ind_count;
	} else {
		netdev_dbg(priv->net_dev, " count over :: scan_ind_count=%d\n",
			   priv->scan_ind_count);
	}
}

static
void hostif_stop_confirm(struct ks_wlan_private *priv)
{
	unsigned int tmp = 0;
	unsigned int old_status = priv->connect_status;
	struct net_device *netdev = priv->net_dev;
	union iwreq_data wrqu0;

	if (priv->dev_state == DEVICE_STATE_SLEEP)
		priv->dev_state = DEVICE_STATE_READY;

	/* disconnect indication */
	if (is_connect_status(priv->connect_status)) {
		netif_carrier_off(netdev);
		tmp = FORCE_DISCONNECT & priv->connect_status;
		priv->connect_status = tmp | DISCONNECT_STATUS;
		netdev_info(netdev, "IWEVENT: disconnect\n");

		wrqu0.data.length = 0;
		wrqu0.data.flags = 0;
		wrqu0.ap_addr.sa_family = ARPHRD_ETHER;
		if (is_disconnect_status(priv->connect_status) &&
		    is_connect_status(old_status)) {
			eth_zero_addr(wrqu0.ap_addr.sa_data);
			netdev_info(netdev, "IWEVENT: disconnect\n");
			wireless_send_event(netdev, SIOCGIWAP, &wrqu0, NULL);
		}
		priv->scan_ind_count = 0;
	}

	hostif_sme_enqueue(priv, SME_STOP_CONFIRM);
}

static
void hostif_ps_adhoc_set_confirm(struct ks_wlan_private *priv)
{
	priv->infra_status = 0;	/* infrastructure mode cancel */
	hostif_sme_enqueue(priv, SME_MODE_SET_CONFIRM);
}

static
void hostif_infrastructure_set_confirm(struct ks_wlan_private *priv)
{
	u16 result_code;

	result_code = get_word(priv);
	priv->infra_status = 1;	/* infrastructure mode set */
	hostif_sme_enqueue(priv, SME_MODE_SET_CONFIRM);
}

static
void hostif_adhoc_set_confirm(struct ks_wlan_private *priv)
{
	priv->infra_status = 1;	/* infrastructure mode set */
	hostif_sme_enqueue(priv, SME_MODE_SET_CONFIRM);
}

static
void hostif_associate_indication(struct ks_wlan_private *priv)
{
	struct association_request *assoc_req;
	struct association_response *assoc_resp;
	unsigned char *pb;
	union iwreq_data wrqu;
	char buf[IW_CUSTOM_MAX];
	char *pbuf = &buf[0];
	int i;

	static const char associnfo_leader0[] = "ASSOCINFO(ReqIEs=";
	static const char associnfo_leader1[] = " RespIEs=";

	assoc_req = (struct association_request *)(priv->rxp);
	assoc_resp = (struct association_response *)(assoc_req + 1);
	pb = (unsigned char *)(assoc_resp + 1);

	memset(&wrqu, 0, sizeof(wrqu));
	memcpy(pbuf, associnfo_leader0, sizeof(associnfo_leader0) - 1);
	wrqu.data.length += sizeof(associnfo_leader0) - 1;
	pbuf += sizeof(associnfo_leader0) - 1;

	for (i = 0; i < le16_to_cpu(assoc_req->req_ies_size); i++)
		pbuf += sprintf(pbuf, "%02x", *(pb + i));
	wrqu.data.length += (le16_to_cpu(assoc_req->req_ies_size)) * 2;

	memcpy(pbuf, associnfo_leader1, sizeof(associnfo_leader1) - 1);
	wrqu.data.length += sizeof(associnfo_leader1) - 1;
	pbuf += sizeof(associnfo_leader1) - 1;

	pb += le16_to_cpu(assoc_req->req_ies_size);
	for (i = 0; i < le16_to_cpu(assoc_resp->resp_ies_size); i++)
		pbuf += sprintf(pbuf, "%02x", *(pb + i));
	wrqu.data.length += (le16_to_cpu(assoc_resp->resp_ies_size)) * 2;

	pbuf += sprintf(pbuf, ")");
	wrqu.data.length += 1;

	wireless_send_event(priv->net_dev, IWEVCUSTOM, &wrqu, buf);
}

static
void hostif_bss_scan_confirm(struct ks_wlan_private *priv)
{
	u32 result_code;
	struct net_device *dev = priv->net_dev;
	union iwreq_data wrqu;

	result_code = get_dword(priv);
	netdev_dbg(priv->net_dev, "result=%d :: scan_ind_count=%d\n",
		   result_code, priv->scan_ind_count);

	priv->sme_i.sme_flag &= ~SME_AP_SCAN;
	hostif_sme_enqueue(priv, SME_BSS_SCAN_CONFIRM);

	wrqu.data.length = 0;
	wrqu.data.flags = 0;
	wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
	priv->scan_ind_count = 0;
}

static
void hostif_phy_information_confirm(struct ks_wlan_private *priv)
{
	struct iw_statistics *wstats = &priv->wstats;
	u8 rssi, signal, noise;
	u8 link_speed;
	u32 transmitted_frame_count, received_fragment_count;
	u32 failed_count, fcs_error_count;

	rssi = get_byte(priv);
	signal = get_byte(priv);
	noise = get_byte(priv);
	link_speed = get_byte(priv);
	transmitted_frame_count = get_dword(priv);
	received_fragment_count = get_dword(priv);
	failed_count = get_dword(priv);
	fcs_error_count = get_dword(priv);

	netdev_dbg(priv->net_dev, "phyinfo confirm rssi=%d signal=%d\n",
		   rssi, signal);
	priv->current_rate = (link_speed & RATE_MASK);
	wstats->qual.qual = signal;
	wstats->qual.level = 256 - rssi;
	wstats->qual.noise = 0;	/* invalid noise value */
	wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;

	netdev_dbg(priv->net_dev, "\n    rssi=%u\n"
		   "    signal=%u\n"
		   "    link_speed=%ux500Kbps\n"
		   "    transmitted_frame_count=%u\n"
		   "    received_fragment_count=%u\n"
		   "    failed_count=%u\n"
		   "    fcs_error_count=%u\n",
		   rssi, signal, link_speed, transmitted_frame_count,
		   received_fragment_count, failed_count, fcs_error_count);
	/* wake_up_interruptible_all(&priv->confirm_wait); */
	complete(&priv->confirm_wait);
}

static
void hostif_mic_failure_confirm(struct ks_wlan_private *priv)
{
	netdev_dbg(priv->net_dev, "mic_failure=%u\n",
		   priv->wpa.mic_failure.failure);
	hostif_sme_enqueue(priv, SME_MIC_FAILURE_CONFIRM);
}

static
void hostif_event_check(struct ks_wlan_private *priv)
{
	u16 event;

	event = get_word(priv);
	switch (event) {
	case HIF_DATA_IND:
		hostif_data_indication(priv);
		break;
	case HIF_MIB_GET_CONF:
		hostif_mib_get_confirm(priv);
		break;
	case HIF_MIB_SET_CONF:
		hostif_mib_set_confirm(priv);
		break;
	case HIF_POWER_MGMT_CONF:
		hostif_power_mgmt_confirm(priv);
		break;
	case HIF_SLEEP_CONF:
		hostif_sleep_confirm(priv);
		break;
	case HIF_START_CONF:
		hostif_start_confirm(priv);
		break;
	case HIF_CONNECT_IND:
		hostif_connect_indication(priv);
		break;
	case HIF_STOP_CONF:
		hostif_stop_confirm(priv);
		break;
	case HIF_PS_ADH_SET_CONF:
		hostif_ps_adhoc_set_confirm(priv);
		break;
	case HIF_INFRA_SET_CONF:
	case HIF_INFRA_SET2_CONF:
		hostif_infrastructure_set_confirm(priv);
		break;
	case HIF_ADH_SET_CONF:
	case HIF_ADH_SET2_CONF:
		hostif_adhoc_set_confirm(priv);
		break;
	case HIF_ASSOC_INFO_IND:
		hostif_associate_indication(priv);
		break;
	case HIF_MIC_FAILURE_CONF:
		hostif_mic_failure_confirm(priv);
		break;
	case HIF_SCAN_CONF:
		hostif_bss_scan_confirm(priv);
		break;
	case HIF_PHY_INFO_CONF:
	case HIF_PHY_INFO_IND:
		hostif_phy_information_confirm(priv);
		break;
	case HIF_SCAN_IND:
		hostif_scan_indication(priv);
		break;
	case HIF_AP_SET_CONF:
	default:
		netdev_err(priv->net_dev, "undefined event[%04X]\n", event);
		/* wake_up_all(&priv->confirm_wait); */
		complete(&priv->confirm_wait);
		break;
	}

	/* add event to hostt buffer */
	priv->hostt.buff[priv->hostt.qtail] = event;
	priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE;
}

/* allocate size bytes, set header size and event */
static void *hostif_generic_request(size_t size, int event)
{
	struct hostif_hdr *p;

	p = kzalloc(hif_align_size(size), GFP_ATOMIC);
	if (!p)
		return NULL;

	p->size = cpu_to_le16(size - sizeof(p->size));
	p->event = cpu_to_le16(event);

	return p;
}

int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *skb)
{
	unsigned int skb_len = 0;
	unsigned char *buffer = NULL;
	unsigned int length = 0;
	struct hostif_data_request *pp;
	unsigned char *p;
	int result = 0;
	unsigned short eth_proto;
	struct ether_hdr *eth_hdr;
	struct michael_mic michael_mic;
	unsigned short keyinfo = 0;
	struct ieee802_1x_hdr *aa1x_hdr;
	struct wpa_eapol_key *eap_key;
	struct ethhdr *eth;
	size_t size;
	int ret;

	skb_len = skb->len;
	if (skb_len > ETH_FRAME_LEN) {
		netdev_err(priv->net_dev, "bad length skb_len=%d\n", skb_len);
		ret = -EOVERFLOW;
		goto err_kfree_skb;
	}

	if (is_disconnect_status(priv->connect_status) ||
	    (priv->connect_status & FORCE_DISCONNECT) ||
	    priv->wpa.mic_failure.stop) {
		if (netif_queue_stopped(priv->net_dev))
			netif_wake_queue(priv->net_dev);
		if (skb)
			dev_kfree_skb(skb);

		return 0;
	}

	/* power save wakeup */
	if (atomic_read(&priv->psstatus.status) == PS_SNOOZE) {
		if (!netif_queue_stopped(priv->net_dev))
			netif_stop_queue(priv->net_dev);
	}

	size = sizeof(*pp) + 6 + skb_len + 8;
	pp = kmalloc(hif_align_size(size), GFP_ATOMIC);
	if (!pp) {
		ret = -ENOMEM;
		goto err_kfree_skb;
	}

	p = (unsigned char *)pp->data;

	buffer = skb->data;
	length = skb->len;

	/* skb check */
	eth = (struct ethhdr *)skb->data;
	if (!ether_addr_equal(&priv->eth_addr[0], eth->h_source)) {
		netdev_err(priv->net_dev,
			   "Invalid mac address: ethernet->h_source=%pM\n",
			   eth->h_source);
		ret = -ENXIO;
		goto err_kfree;
	}

	/* dest and src MAC address copy */
	size = ETH_ALEN * 2;
	memcpy(p, buffer, size);
	p += size;
	buffer += size;
	length -= size;

	/* EtherType/Length check */
	if (*(buffer + 1) + (*buffer << 8) > 1500) {
		/* ProtocolEAP = *(buffer+1) + (*buffer << 8); */
		/* SAP/CTL/OUI(6 byte) add */
		*p++ = 0xAA;	/* DSAP */
		*p++ = 0xAA;	/* SSAP */
		*p++ = 0x03;	/* CTL */
		*p++ = 0x00;	/* OUI ("000000") */
		*p++ = 0x00;	/* OUI ("000000") */
		*p++ = 0x00;	/* OUI ("000000") */
		skb_len += 6;
	} else {
		/* Length(2 byte) delete */
		buffer += 2;
		length -= 2;
		skb_len -= 2;
	}

	/* pp->data copy */
	memcpy(p, buffer, length);

	p += length;

	/* for WPA */
	eth_hdr = (struct ether_hdr *)&pp->data[0];
	eth_proto = ntohs(eth_hdr->h_proto);

	/* for MIC FAILURE REPORT check */
	if (eth_proto == ETH_P_PAE &&
	    priv->wpa.mic_failure.failure > 0) {
		aa1x_hdr = (struct ieee802_1x_hdr *)(eth_hdr + 1);
		if (aa1x_hdr->type == IEEE802_1X_TYPE_EAPOL_KEY) {
			eap_key = (struct wpa_eapol_key *)(aa1x_hdr + 1);
			keyinfo = ntohs(eap_key->key_info);
		}
	}

	if (priv->wpa.rsn_enabled && priv->wpa.key[0].key_len) {
		/* no encryption */
		if (eth_proto == ETH_P_PAE &&
		    priv->wpa.key[1].key_len == 0 &&
		    priv->wpa.key[2].key_len == 0 &&
		    priv->wpa.key[3].key_len == 0) {
			pp->auth_type = cpu_to_le16(TYPE_AUTH);
		} else {
			if (priv->wpa.pairwise_suite == IW_AUTH_CIPHER_TKIP) {
				michael_mic_function(&michael_mic,
						     priv->wpa.key[0].tx_mic_key,
						     &pp->data[0], skb_len,
						     0,	michael_mic.result);
				memcpy(p, michael_mic.result, 8);
				length += 8;
				skb_len += 8;
				p += 8;
				pp->auth_type =
				    cpu_to_le16(TYPE_DATA);

			} else if (priv->wpa.pairwise_suite ==
				   IW_AUTH_CIPHER_CCMP) {
				pp->auth_type =
				    cpu_to_le16(TYPE_DATA);
			}
		}
	} else {
		if (eth_proto == ETH_P_PAE)
			pp->auth_type = cpu_to_le16(TYPE_AUTH);
		else
			pp->auth_type = cpu_to_le16(TYPE_DATA);
	}

	/* header value set */
	pp->header.size =
	    cpu_to_le16((sizeof(*pp) - sizeof(pp->header.size) + skb_len));
	pp->header.event = cpu_to_le16(HIF_DATA_REQ);

	/* tx request */
	result = ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp) + skb_len),
			       send_packet_complete, skb);

	/* MIC FAILURE REPORT check */
	if (eth_proto == ETH_P_PAE &&
	    priv->wpa.mic_failure.failure > 0) {
		if (keyinfo & WPA_KEY_INFO_ERROR &&
		    keyinfo & WPA_KEY_INFO_REQUEST) {
			netdev_err(priv->net_dev,
				   "MIC ERROR Report SET : %04X\n", keyinfo);
			hostif_sme_enqueue(priv, SME_MIC_FAILURE_REQUEST);
		}
		if (priv->wpa.mic_failure.failure == 2)
			priv->wpa.mic_failure.stop = 1;
	}

	return result;

err_kfree:
	kfree(pp);
err_kfree_skb:
	dev_kfree_skb(skb);

	return ret;
}

static inline void ps_confirm_wait_inc(struct ks_wlan_private *priv)
{
	if (atomic_read(&priv->psstatus.status) > PS_ACTIVE_SET)
		atomic_inc(&priv->psstatus.confirm_wait);
}

static inline void send_request_to_device(struct ks_wlan_private *priv,
					  void *data, size_t size)
{
	ps_confirm_wait_inc(priv);
	ks_wlan_hw_tx(priv, data, size, NULL, NULL);
}

static void hostif_mib_get_request(struct ks_wlan_private *priv,
				   u32 mib_attribute)
{
	struct hostif_mib_get_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_MIB_GET_REQ);
	if (!pp)
		return;

	pp->mib_attribute = cpu_to_le32(mib_attribute);

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

static void hostif_mib_set_request(struct ks_wlan_private *priv,
				   enum mib_attribute attr,
				   enum mib_data_type type,
				   void *data, size_t size)
{
	struct hostif_mib_set_request_t *pp;

	if (priv->dev_state < DEVICE_STATE_BOOT)
		return;

	pp = hostif_generic_request(sizeof(*pp), HIF_MIB_SET_REQ);
	if (!pp)
		return;

	pp->mib_attribute = cpu_to_le32(attr);
	pp->mib_value.size = cpu_to_le16(size);
	pp->mib_value.type = cpu_to_le16(type);
	memcpy(&pp->mib_value.body, data, size);

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp) + size));
}

static inline void hostif_mib_set_request_int(struct ks_wlan_private *priv,
					      enum mib_attribute attr, int val)
{
	__le32 v = cpu_to_le32(val);
	size_t size = sizeof(v);

	hostif_mib_set_request(priv, attr, MIB_VALUE_TYPE_INT, &v, size);
}

static inline void hostif_mib_set_request_bool(struct ks_wlan_private *priv,
					       enum mib_attribute attr,
					       bool val)
{
	__le32 v = cpu_to_le32(val);
	size_t size = sizeof(v);

	hostif_mib_set_request(priv, attr, MIB_VALUE_TYPE_BOOL, &v, size);
}

static inline void hostif_mib_set_request_ostring(struct ks_wlan_private *priv,
						  enum mib_attribute attr,
						  void *data, size_t size)
{
	hostif_mib_set_request(priv, attr, MIB_VALUE_TYPE_OSTRING, data, size);
}

static
void hostif_start_request(struct ks_wlan_private *priv, unsigned char mode)
{
	struct hostif_start_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_START_REQ);
	if (!pp)
		return;

	pp->mode = cpu_to_le16(mode);

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));

	priv->aplist.size = 0;
	priv->scan_ind_count = 0;
}

static __le16 ks_wlan_cap(struct ks_wlan_private *priv)
{
	u16 capability = 0x0000;

	if (priv->reg.preamble == SHORT_PREAMBLE)
		capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;

	capability &= ~(WLAN_CAPABILITY_PBCC);	/* pbcc not support */

	if (priv->reg.phy_type != D_11B_ONLY_MODE) {
		capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
		capability &= ~(WLAN_CAPABILITY_DSSS_OFDM);
	}

	return cpu_to_le16(capability);
}

static void init_request(struct ks_wlan_private *priv,
			 struct hostif_request *req)
{
	req->phy_type = cpu_to_le16(priv->reg.phy_type);
	req->cts_mode = cpu_to_le16(priv->reg.cts_mode);
	req->scan_type = cpu_to_le16(priv->reg.scan_type);
	req->rate_set.size = priv->reg.rate_set.size;
	req->capability = ks_wlan_cap(priv);
	memcpy(&req->rate_set.body[0], &priv->reg.rate_set.body[0],
	       priv->reg.rate_set.size);
}

static
void hostif_ps_adhoc_set_request(struct ks_wlan_private *priv)
{
	struct hostif_ps_adhoc_set_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_PS_ADH_SET_REQ);
	if (!pp)
		return;

	init_request(priv, &pp->request);
	pp->channel = cpu_to_le16(priv->reg.channel);

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

static
void hostif_infrastructure_set_request(struct ks_wlan_private *priv, int event)
{
	struct hostif_infrastructure_set_request *pp;

	pp = hostif_generic_request(sizeof(*pp), event);
	if (!pp)
		return;

	init_request(priv, &pp->request);
	pp->ssid.size = priv->reg.ssid.size;
	memcpy(&pp->ssid.body[0], &priv->reg.ssid.body[0], priv->reg.ssid.size);
	pp->beacon_lost_count =
	    cpu_to_le16(priv->reg.beacon_lost_count);
	pp->auth_type = cpu_to_le16(priv->reg.authenticate_type);

	pp->channel_list.body[0] = 1;
	pp->channel_list.body[1] = 8;
	pp->channel_list.body[2] = 2;
	pp->channel_list.body[3] = 9;
	pp->channel_list.body[4] = 3;
	pp->channel_list.body[5] = 10;
	pp->channel_list.body[6] = 4;
	pp->channel_list.body[7] = 11;
	pp->channel_list.body[8] = 5;
	pp->channel_list.body[9] = 12;
	pp->channel_list.body[10] = 6;
	pp->channel_list.body[11] = 13;
	pp->channel_list.body[12] = 7;
	if (priv->reg.phy_type == D_11G_ONLY_MODE) {
		pp->channel_list.size = 13;
	} else {
		pp->channel_list.body[13] = 14;
		pp->channel_list.size = 14;
	}

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

static
void hostif_adhoc_set_request(struct ks_wlan_private *priv)
{
	struct hostif_adhoc_set_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_ADH_SET_REQ);
	if (!pp)
		return;

	init_request(priv, &pp->request);
	pp->channel = cpu_to_le16(priv->reg.channel);
	pp->ssid.size = priv->reg.ssid.size;
	memcpy(&pp->ssid.body[0], &priv->reg.ssid.body[0], priv->reg.ssid.size);

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

static
void hostif_adhoc_set2_request(struct ks_wlan_private *priv)
{
	struct hostif_adhoc_set2_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_ADH_SET_REQ);
	if (!pp)
		return;

	init_request(priv, &pp->request);
	pp->ssid.size = priv->reg.ssid.size;
	memcpy(&pp->ssid.body[0], &priv->reg.ssid.body[0], priv->reg.ssid.size);

	pp->channel_list.body[0] = priv->reg.channel;
	pp->channel_list.size = 1;
	memcpy(pp->bssid, priv->reg.bssid, ETH_ALEN);

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

static
void hostif_stop_request(struct ks_wlan_private *priv)
{
	struct hostif_stop_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_STOP_REQ);
	if (!pp)
		return;

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

static
void hostif_phy_information_request(struct ks_wlan_private *priv)
{
	struct hostif_phy_information_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_PHY_INFO_REQ);
	if (!pp)
		return;

	if (priv->reg.phy_info_timer) {
		pp->type = cpu_to_le16(TIME_TYPE);
		pp->time = cpu_to_le16(priv->reg.phy_info_timer);
	} else {
		pp->type = cpu_to_le16(NORMAL_TYPE);
		pp->time = cpu_to_le16(0);
	}

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

static
void hostif_power_mgmt_request(struct ks_wlan_private *priv,
			       u32 mode, u32 wake_up, u32 receive_dtims)
{
	struct hostif_power_mgmt_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_POWER_MGMT_REQ);
	if (!pp)
		return;

	pp->mode = cpu_to_le32(mode);
	pp->wake_up = cpu_to_le32(wake_up);
	pp->receive_dtims = cpu_to_le32(receive_dtims);

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

static
void hostif_sleep_request(struct ks_wlan_private *priv,
			  enum sleep_mode_type mode)
{
	struct hostif_sleep_request *pp;

	if (mode == SLP_SLEEP) {
		pp = hostif_generic_request(sizeof(*pp), HIF_SLEEP_REQ);
		if (!pp)
			return;

		send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
	} else if (mode == SLP_ACTIVE) {
		atomic_set(&priv->sleepstatus.wakeup_request, 1);
		queue_delayed_work(priv->wq, &priv->rw_dwork, 1);
	} else {
		netdev_err(priv->net_dev, "invalid mode %ld\n", (long)mode);
		return;
	}
}

static
void hostif_bss_scan_request(struct ks_wlan_private *priv,
			     unsigned long scan_type, u8 *scan_ssid,
			     u8 scan_ssid_len)
{
	struct hostif_bss_scan_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_SCAN_REQ);
	if (!pp)
		return;

	pp->scan_type = scan_type;

	pp->ch_time_min = cpu_to_le32(110);	/* default value */
	pp->ch_time_max = cpu_to_le32(130);	/* default value */
	pp->channel_list.body[0] = 1;
	pp->channel_list.body[1] = 8;
	pp->channel_list.body[2] = 2;
	pp->channel_list.body[3] = 9;
	pp->channel_list.body[4] = 3;
	pp->channel_list.body[5] = 10;
	pp->channel_list.body[6] = 4;
	pp->channel_list.body[7] = 11;
	pp->channel_list.body[8] = 5;
	pp->channel_list.body[9] = 12;
	pp->channel_list.body[10] = 6;
	pp->channel_list.body[11] = 13;
	pp->channel_list.body[12] = 7;
	if (priv->reg.phy_type == D_11G_ONLY_MODE) {
		pp->channel_list.size = 13;
	} else {
		pp->channel_list.body[13] = 14;
		pp->channel_list.size = 14;
	}
	pp->ssid.size = 0;

	/* specified SSID SCAN */
	if (scan_ssid_len > 0 && scan_ssid_len <= 32) {
		pp->ssid.size = scan_ssid_len;
		memcpy(&pp->ssid.body[0], scan_ssid, scan_ssid_len);
	}

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));

	priv->aplist.size = 0;
	priv->scan_ind_count = 0;
}

static
void hostif_mic_failure_request(struct ks_wlan_private *priv,
				u16 failure_count, u16 timer)
{
	struct hostif_mic_failure_request *pp;

	pp = hostif_generic_request(sizeof(*pp), HIF_MIC_FAILURE_REQ);
	if (!pp)
		return;

	pp->failure_count = cpu_to_le16(failure_count);
	pp->timer = cpu_to_le16(timer);

	send_request_to_device(priv, pp, hif_align_size(sizeof(*pp)));
}

/* Device I/O Receive indicate */
static void devio_rec_ind(struct ks_wlan_private *priv, unsigned char *p,
			  unsigned int size)
{
	if (!priv->is_device_open)
		return;

	spin_lock(&priv->dev_read_lock);
	priv->dev_data[atomic_read(&priv->rec_count)] = p;
	priv->dev_size[atomic_read(&priv->rec_count)] = size;

	if (atomic_read(&priv->event_count) != DEVICE_STOCK_COUNT) {
		/* rx event count inc */
		atomic_inc(&priv->event_count);
	}
	atomic_inc(&priv->rec_count);
	if (atomic_read(&priv->rec_count) == DEVICE_STOCK_COUNT)
		atomic_set(&priv->rec_count, 0);

	wake_up_interruptible_all(&priv->devread_wait);

	spin_unlock(&priv->dev_read_lock);
}

void hostif_receive(struct ks_wlan_private *priv, unsigned char *p,
		    unsigned int size)
{
	devio_rec_ind(priv, p, size);

	priv->rxp = p;
	priv->rx_size = size;

	if (get_word(priv) == priv->rx_size)
		hostif_event_check(priv);
}

static void hostif_sme_set_wep(struct ks_wlan_private *priv, int type)
{
	switch (type) {
	case SME_WEP_INDEX_REQUEST:
		hostif_mib_set_request_int(priv, DOT11_WEP_DEFAULT_KEY_ID,
					   priv->reg.wep_index);
		break;
	case SME_WEP_KEY1_REQUEST:
		if (priv->wpa.wpa_enabled)
			return;
		hostif_mib_set_request_ostring(priv,
					       DOT11_WEP_DEFAULT_KEY_VALUE1,
					       &priv->reg.wep_key[0].val[0],
					       priv->reg.wep_key[0].size);
		break;
	case SME_WEP_KEY2_REQUEST:
		if (priv->wpa.wpa_enabled)
			return;
		hostif_mib_set_request_ostring(priv,
					       DOT11_WEP_DEFAULT_KEY_VALUE2,
					       &priv->reg.wep_key[1].val[0],
					       priv->reg.wep_key[1].size);
		break;
	case SME_WEP_KEY3_REQUEST:
		if (priv->wpa.wpa_enabled)
			return;
		hostif_mib_set_request_ostring(priv,
					       DOT11_WEP_DEFAULT_KEY_VALUE3,
					       &priv->reg.wep_key[2].val[0],
					       priv->reg.wep_key[2].size);
		break;
	case SME_WEP_KEY4_REQUEST:
		if (priv->wpa.wpa_enabled)
			return;
		hostif_mib_set_request_ostring(priv,
					       DOT11_WEP_DEFAULT_KEY_VALUE4,
					       &priv->reg.wep_key[3].val[0],
					       priv->reg.wep_key[3].size);
		break;
	case SME_WEP_FLAG_REQUEST:
		hostif_mib_set_request_bool(priv, DOT11_PRIVACY_INVOKED,
					    priv->reg.privacy_invoked);
		break;
	}
}

struct wpa_suite {
	__le16 size;
	unsigned char suite[4][CIPHER_ID_LEN];
} __packed;

struct rsn_mode {
	__le32 rsn_mode;
	__le16 rsn_capability;
} __packed;

static void hostif_sme_set_rsn(struct ks_wlan_private *priv, int type)
{
	struct wpa_suite wpa_suite;
	struct rsn_mode rsn_mode;
	size_t size;
	u32 mode;
	const u8 *buf = NULL;

	memset(&wpa_suite, 0, sizeof(wpa_suite));

	switch (type) {
	case SME_RSN_UCAST_REQUEST:
		wpa_suite.size = cpu_to_le16(1);
		switch (priv->wpa.pairwise_suite) {
		case IW_AUTH_CIPHER_NONE:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_NONE : CIPHER_ID_WPA_NONE;
			break;
		case IW_AUTH_CIPHER_WEP40:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_WEP40 : CIPHER_ID_WPA_WEP40;
			break;
		case IW_AUTH_CIPHER_TKIP:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_TKIP : CIPHER_ID_WPA_TKIP;
			break;
		case IW_AUTH_CIPHER_CCMP:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_CCMP : CIPHER_ID_WPA_CCMP;
			break;
		case IW_AUTH_CIPHER_WEP104:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_WEP104 : CIPHER_ID_WPA_WEP104;
			break;
		}

		if (buf)
			memcpy(&wpa_suite.suite[0][0], buf, CIPHER_ID_LEN);
		size = sizeof(wpa_suite.size) +
		       (CIPHER_ID_LEN * le16_to_cpu(wpa_suite.size));
		hostif_mib_set_request_ostring(priv,
					       DOT11_RSN_CONFIG_UNICAST_CIPHER,
					       &wpa_suite, size);
		break;
	case SME_RSN_MCAST_REQUEST:
		switch (priv->wpa.group_suite) {
		case IW_AUTH_CIPHER_NONE:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_NONE : CIPHER_ID_WPA_NONE;
			break;
		case IW_AUTH_CIPHER_WEP40:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_WEP40 : CIPHER_ID_WPA_WEP40;
			break;
		case IW_AUTH_CIPHER_TKIP:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_TKIP : CIPHER_ID_WPA_TKIP;
			break;
		case IW_AUTH_CIPHER_CCMP:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_CCMP : CIPHER_ID_WPA_CCMP;
			break;
		case IW_AUTH_CIPHER_WEP104:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				CIPHER_ID_WPA2_WEP104 : CIPHER_ID_WPA_WEP104;
			break;
		}
		if (buf)
			memcpy(&wpa_suite.suite[0][0], buf, CIPHER_ID_LEN);
		hostif_mib_set_request_ostring(priv,
					       DOT11_RSN_CONFIG_MULTICAST_CIPHER,
					       &wpa_suite.suite[0][0],
					       CIPHER_ID_LEN);
		break;
	case SME_RSN_AUTH_REQUEST:
		wpa_suite.size = cpu_to_le16(1);
		switch (priv->wpa.key_mgmt_suite) {
		case IW_AUTH_KEY_MGMT_802_1X:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				KEY_MGMT_ID_WPA2_1X : KEY_MGMT_ID_WPA_1X;
			break;
		case IW_AUTH_KEY_MGMT_PSK:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				KEY_MGMT_ID_WPA2_PSK : KEY_MGMT_ID_WPA_PSK;
			break;
		case 0:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				KEY_MGMT_ID_WPA2_NONE : KEY_MGMT_ID_WPA_NONE;
			break;
		case 4:
			buf = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
				KEY_MGMT_ID_WPA2_WPANONE :
				KEY_MGMT_ID_WPA_WPANONE;
			break;
		}

		if (buf)
			memcpy(&wpa_suite.suite[0][0], buf, KEY_MGMT_ID_LEN);
		size = sizeof(wpa_suite.size) +
		       (KEY_MGMT_ID_LEN * le16_to_cpu(wpa_suite.size));
		hostif_mib_set_request_ostring(priv,
					       DOT11_RSN_CONFIG_AUTH_SUITE,
					       &wpa_suite, size);
		break;
	case SME_RSN_ENABLED_REQUEST:
		hostif_mib_set_request_bool(priv, DOT11_RSN_ENABLED,
					    priv->wpa.rsn_enabled);
		break;
	case SME_RSN_MODE_REQUEST:
		mode = (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) ?
			RSN_MODE_WPA2 :
			(priv->wpa.version == IW_AUTH_WPA_VERSION_WPA) ?
			 RSN_MODE_WPA : RSN_MODE_NONE;
		rsn_mode.rsn_mode = cpu_to_le32(mode);
		rsn_mode.rsn_capability = cpu_to_le16(0);
		hostif_mib_set_request_ostring(priv, LOCAL_RSN_MODE,
					       &rsn_mode, sizeof(rsn_mode));
		break;
	}
}

static
void hostif_sme_mode_setup(struct ks_wlan_private *priv)
{
	unsigned char rate_size;
	unsigned char rate_octet[RATE_SET_MAX_SIZE];
	int i = 0;

	/* rate setting if rate segging is auto for changing phy_type (#94) */
	if (priv->reg.tx_rate == TX_RATE_FULL_AUTO) {
		if (priv->reg.phy_type == D_11B_ONLY_MODE) {
			priv->reg.rate_set.body[3] = TX_RATE_11M;
			priv->reg.rate_set.body[2] = TX_RATE_5M;
			priv->reg.rate_set.body[1] = TX_RATE_2M | BASIC_RATE;
			priv->reg.rate_set.body[0] = TX_RATE_1M | BASIC_RATE;
			priv->reg.rate_set.size = 4;
		} else {	/* D_11G_ONLY_MODE or D_11BG_COMPATIBLE_MODE */
			priv->reg.rate_set.body[11] = TX_RATE_54M;
			priv->reg.rate_set.body[10] = TX_RATE_48M;
			priv->reg.rate_set.body[9] = TX_RATE_36M;
			priv->reg.rate_set.body[8] = TX_RATE_18M;
			priv->reg.rate_set.body[7] = TX_RATE_9M;
			priv->reg.rate_set.body[6] = TX_RATE_24M | BASIC_RATE;
			priv->reg.rate_set.body[5] = TX_RATE_12M | BASIC_RATE;
			priv->reg.rate_set.body[4] = TX_RATE_6M | BASIC_RATE;
			priv->reg.rate_set.body[3] = TX_RATE_11M | BASIC_RATE;
			priv->reg.rate_set.body[2] = TX_RATE_5M | BASIC_RATE;
			priv->reg.rate_set.body[1] = TX_RATE_2M | BASIC_RATE;
			priv->reg.rate_set.body[0] = TX_RATE_1M | BASIC_RATE;
			priv->reg.rate_set.size = 12;
		}
	}

	/* rate mask by phy setting */
	if (priv->reg.phy_type == D_11B_ONLY_MODE) {
		for (i = 0; i < priv->reg.rate_set.size; i++) {
			if (!is_11b_rate(priv->reg.rate_set.body[i]))
				break;

			if ((priv->reg.rate_set.body[i] & RATE_MASK) >= TX_RATE_5M) {
				rate_octet[i] = priv->reg.rate_set.body[i] &
						RATE_MASK;
			} else {
				rate_octet[i] = priv->reg.rate_set.body[i];
			}
		}

	} else {	/* D_11G_ONLY_MODE or D_11BG_COMPATIBLE_MODE */
		for (i = 0; i < priv->reg.rate_set.size; i++) {
			if (!is_11bg_rate(priv->reg.rate_set.body[i]))
				break;

			if (is_ofdm_ext_rate(priv->reg.rate_set.body[i])) {
				rate_octet[i] = priv->reg.rate_set.body[i] &
						RATE_MASK;
			} else {
				rate_octet[i] = priv->reg.rate_set.body[i];
			}
		}
	}
	rate_size = i;
	if (rate_size == 0) {
		if (priv->reg.phy_type == D_11G_ONLY_MODE)
			rate_octet[0] = TX_RATE_6M | BASIC_RATE;
		else
			rate_octet[0] = TX_RATE_2M | BASIC_RATE;
		rate_size = 1;
	}

	/* rate set update */
	priv->reg.rate_set.size = rate_size;
	memcpy(&priv->reg.rate_set.body[0], &rate_octet[0], rate_size);

	switch (priv->reg.operation_mode) {
	case MODE_PSEUDO_ADHOC:
		hostif_ps_adhoc_set_request(priv);
		break;
	case MODE_INFRASTRUCTURE:
		if (!is_valid_ether_addr((u8 *)priv->reg.bssid)) {
			hostif_infrastructure_set_request(priv,
							  HIF_INFRA_SET_REQ);
		} else {
			hostif_infrastructure_set_request(priv,
							  HIF_INFRA_SET2_REQ);
			netdev_dbg(priv->net_dev,
				   "Infra bssid = %pM\n", priv->reg.bssid);
		}
		break;
	case MODE_ADHOC:
		if (!is_valid_ether_addr((u8 *)priv->reg.bssid)) {
			hostif_adhoc_set_request(priv);
		} else {
			hostif_adhoc_set2_request(priv);
			netdev_dbg(priv->net_dev,
				   "Adhoc bssid = %pM\n", priv->reg.bssid);
		}
		break;
	default:
		break;
	}
}

static
void hostif_sme_multicast_set(struct ks_wlan_private *priv)
{
	struct net_device *dev = priv->net_dev;
	int mc_count;
	struct netdev_hw_addr *ha;
	char set_address[NIC_MAX_MCAST_LIST * ETH_ALEN];
	int i = 0;

	spin_lock(&priv->multicast_spin);

	memset(set_address, 0, NIC_MAX_MCAST_LIST * ETH_ALEN);

	if (dev->flags & IFF_PROMISC) {
		hostif_mib_set_request_int(priv, LOCAL_MULTICAST_FILTER,
					   MCAST_FILTER_PROMISC);
		goto spin_unlock;
	}

	if ((netdev_mc_count(dev) > NIC_MAX_MCAST_LIST) ||
	    (dev->flags & IFF_ALLMULTI)) {
		hostif_mib_set_request_int(priv, LOCAL_MULTICAST_FILTER,
					   MCAST_FILTER_MCASTALL);
		goto spin_unlock;
	}

	if (priv->sme_i.sme_flag & SME_MULTICAST) {
		mc_count = netdev_mc_count(dev);
		netdev_for_each_mc_addr(ha, dev) {
			ether_addr_copy(&set_address[i * ETH_ALEN], ha->addr);
			i++;
		}
		priv->sme_i.sme_flag &= ~SME_MULTICAST;
		hostif_mib_set_request_ostring(priv, LOCAL_MULTICAST_ADDRESS,
					       &set_address[0],
					       ETH_ALEN * mc_count);
	} else {
		priv->sme_i.sme_flag |= SME_MULTICAST;
		hostif_mib_set_request_int(priv, LOCAL_MULTICAST_FILTER,
					   MCAST_FILTER_MCAST);
	}

spin_unlock:
	spin_unlock(&priv->multicast_spin);
}

static void hostif_sme_power_mgmt_set(struct ks_wlan_private *priv)
{
	u32 mode, wake_up, receive_dtims;

	if (priv->reg.power_mgmt != POWER_MGMT_SAVE1 &&
	    priv->reg.power_mgmt != POWER_MGMT_SAVE2) {
		mode = POWER_ACTIVE;
		wake_up = 0;
		receive_dtims = 0;
	} else {
		mode = (priv->reg.operation_mode == MODE_INFRASTRUCTURE) ?
			POWER_SAVE : POWER_ACTIVE;
		wake_up = 0;
		receive_dtims = (priv->reg.operation_mode == MODE_INFRASTRUCTURE &&
				 priv->reg.power_mgmt == POWER_MGMT_SAVE2);
	}

	hostif_power_mgmt_request(priv, mode, wake_up, receive_dtims);
}

static void hostif_sme_sleep_set(struct ks_wlan_private *priv)
{
	if (priv->sleep_mode != SLP_SLEEP &&
	    priv->sleep_mode != SLP_ACTIVE)
		return;

	hostif_sleep_request(priv, priv->sleep_mode);
}

static
void hostif_sme_set_key(struct ks_wlan_private *priv, int type)
{
	switch (type) {
	case SME_SET_FLAG:
		hostif_mib_set_request_bool(priv, DOT11_PRIVACY_INVOKED,
					    priv->reg.privacy_invoked);
		break;
	case SME_SET_TXKEY:
		hostif_mib_set_request_int(priv, DOT11_WEP_DEFAULT_KEY_ID,
					   priv->wpa.txkey);
		break;
	case SME_SET_KEY1:
		hostif_mib_set_request_ostring(priv,
					       DOT11_WEP_DEFAULT_KEY_VALUE1,
					       &priv->wpa.key[0].key_val[0],
					       priv->wpa.key[0].key_len);
		break;
	case SME_SET_KEY2:
		hostif_mib_set_request_ostring(priv,
					       DOT11_WEP_DEFAULT_KEY_VALUE2,
					       &priv->wpa.key[1].key_val[0],
					       priv->wpa.key[1].key_len);
		break;
	case SME_SET_KEY3:
		hostif_mib_set_request_ostring(priv,
					       DOT11_WEP_DEFAULT_KEY_VALUE3,
					       &priv->wpa.key[2].key_val[0],
					       priv->wpa.key[2].key_len);
		break;
	case SME_SET_KEY4:
		hostif_mib_set_request_ostring(priv,
					       DOT11_WEP_DEFAULT_KEY_VALUE4,
					       &priv->wpa.key[3].key_val[0],
					       priv->wpa.key[3].key_len);
		break;
	case SME_SET_PMK_TSC:
		hostif_mib_set_request_ostring(priv, DOT11_PMK_TSC,
					       &priv->wpa.key[0].rx_seq[0],
					       WPA_RX_SEQ_LEN);
		break;
	case SME_SET_GMK1_TSC:
		hostif_mib_set_request_ostring(priv, DOT11_GMK1_TSC,
					       &priv->wpa.key[1].rx_seq[0],
					       WPA_RX_SEQ_LEN);
		break;
	case SME_SET_GMK2_TSC:
		hostif_mib_set_request_ostring(priv, DOT11_GMK2_TSC,
					       &priv->wpa.key[2].rx_seq[0],
					       WPA_RX_SEQ_LEN);
		break;
	}
}

static
void hostif_sme_set_pmksa(struct ks_wlan_private *priv)
{
	struct pmk_cache {
		__le16 size;
		struct {
			u8 bssid[ETH_ALEN];
			u8 pmkid[IW_PMKID_LEN];
		} __packed list[PMK_LIST_MAX];
	} __packed pmkcache;
	struct pmk *pmk;
	size_t size;
	int i = 0;

	list_for_each_entry(pmk, &priv->pmklist.head, list) {
		if (i >= PMK_LIST_MAX)
			break;
		ether_addr_copy(pmkcache.list[i].bssid, pmk->bssid);
		memcpy(pmkcache.list[i].pmkid, pmk->pmkid, IW_PMKID_LEN);
		i++;
	}
	pmkcache.size = cpu_to_le16(priv->pmklist.size);
	size = sizeof(priv->pmklist.size) +
	       ((ETH_ALEN + IW_PMKID_LEN) * priv->pmklist.size);
	hostif_mib_set_request_ostring(priv, LOCAL_PMK, &pmkcache, size);
}

/* execute sme */
static void hostif_sme_execute(struct ks_wlan_private *priv, int event)
{
	u16 failure;

	switch (event) {
	case SME_START:
		if (priv->dev_state == DEVICE_STATE_BOOT)
			hostif_mib_get_request(priv, DOT11_MAC_ADDRESS);
		break;
	case SME_MULTICAST_REQUEST:
		hostif_sme_multicast_set(priv);
		break;
	case SME_MACADDRESS_SET_REQUEST:
		hostif_mib_set_request_ostring(priv, LOCAL_CURRENTADDRESS,
					       &priv->eth_addr[0], ETH_ALEN);
		break;
	case SME_BSS_SCAN_REQUEST:
		hostif_bss_scan_request(priv, priv->reg.scan_type,
					priv->scan_ssid, priv->scan_ssid_len);
		break;
	case SME_POW_MNGMT_REQUEST:
		hostif_sme_power_mgmt_set(priv);
		break;
	case SME_PHY_INFO_REQUEST:
		hostif_phy_information_request(priv);
		break;
	case SME_MIC_FAILURE_REQUEST:
		failure = priv->wpa.mic_failure.failure;
		if (failure != 1 && failure != 2) {
			netdev_err(priv->net_dev,
				   "SME_MIC_FAILURE_REQUEST: failure count=%u error?\n",
				   failure);
			return;
		}
		hostif_mic_failure_request(priv, failure - 1, (failure == 1) ?
					    0 : priv->wpa.mic_failure.counter);
		break;
	case SME_MIC_FAILURE_CONFIRM:
		if (priv->wpa.mic_failure.failure == 2) {
			if (priv->wpa.mic_failure.stop)
				priv->wpa.mic_failure.stop = 0;
			priv->wpa.mic_failure.failure = 0;
			hostif_start_request(priv, priv->reg.operation_mode);
		}
		break;
	case SME_GET_MAC_ADDRESS:
		if (priv->dev_state == DEVICE_STATE_BOOT)
			hostif_mib_get_request(priv, DOT11_PRODUCT_VERSION);
		break;
	case SME_GET_PRODUCT_VERSION:
		if (priv->dev_state == DEVICE_STATE_BOOT)
			priv->dev_state = DEVICE_STATE_PREINIT;
		break;
	case SME_STOP_REQUEST:
		hostif_stop_request(priv);
		break;
	case SME_RTS_THRESHOLD_REQUEST:
		hostif_mib_set_request_int(priv, DOT11_RTS_THRESHOLD,
					   priv->reg.rts);
		break;
	case SME_FRAGMENTATION_THRESHOLD_REQUEST:
		hostif_mib_set_request_int(priv, DOT11_FRAGMENTATION_THRESHOLD,
					   priv->reg.fragment);
		break;
	case SME_WEP_INDEX_REQUEST:
	case SME_WEP_KEY1_REQUEST:
	case SME_WEP_KEY2_REQUEST:
	case SME_WEP_KEY3_REQUEST:
	case SME_WEP_KEY4_REQUEST:
	case SME_WEP_FLAG_REQUEST:
		hostif_sme_set_wep(priv, event);
		break;
	case SME_RSN_UCAST_REQUEST:
	case SME_RSN_MCAST_REQUEST:
	case SME_RSN_AUTH_REQUEST:
	case SME_RSN_ENABLED_REQUEST:
	case SME_RSN_MODE_REQUEST:
		hostif_sme_set_rsn(priv, event);
		break;
	case SME_SET_FLAG:
	case SME_SET_TXKEY:
	case SME_SET_KEY1:
	case SME_SET_KEY2:
	case SME_SET_KEY3:
	case SME_SET_KEY4:
	case SME_SET_PMK_TSC:
	case SME_SET_GMK1_TSC:
	case SME_SET_GMK2_TSC:
		hostif_sme_set_key(priv, event);
		break;
	case SME_SET_PMKSA:
		hostif_sme_set_pmksa(priv);
		break;
	case SME_WPS_ENABLE_REQUEST:
		hostif_mib_set_request_int(priv, LOCAL_WPS_ENABLE,
					   priv->wps.wps_enabled);
		break;
	case SME_WPS_PROBE_REQUEST:
		hostif_mib_set_request_ostring(priv, LOCAL_WPS_PROBE_REQ,
					       priv->wps.ie, priv->wps.ielen);
		break;
	case SME_MODE_SET_REQUEST:
		hostif_sme_mode_setup(priv);
		break;
	case SME_SET_GAIN:
		hostif_mib_set_request_ostring(priv, LOCAL_GAIN,
					       &priv->gain, sizeof(priv->gain));
		break;
	case SME_GET_GAIN:
		hostif_mib_get_request(priv, LOCAL_GAIN);
		break;
	case SME_GET_EEPROM_CKSUM:
		priv->eeprom_checksum = EEPROM_FW_NOT_SUPPORT;	/* initialize */
		hostif_mib_get_request(priv, LOCAL_EEPROM_SUM);
		break;
	case SME_START_REQUEST:
		hostif_start_request(priv, priv->reg.operation_mode);
		break;
	case SME_START_CONFIRM:
		/* for power save */
		atomic_set(&priv->psstatus.snooze_guard, 0);
		atomic_set(&priv->psstatus.confirm_wait, 0);
		if (priv->dev_state == DEVICE_STATE_PREINIT)
			priv->dev_state = DEVICE_STATE_INIT;
		/* wake_up_interruptible_all(&priv->confirm_wait); */
		complete(&priv->confirm_wait);
		break;
	case SME_SLEEP_REQUEST:
		hostif_sme_sleep_set(priv);
		break;
	case SME_SET_REGION:
		hostif_mib_set_request_int(priv, LOCAL_REGION, priv->region);
		break;
	case SME_MULTICAST_CONFIRM:
	case SME_BSS_SCAN_CONFIRM:
	case SME_POW_MNGMT_CONFIRM:
	case SME_PHY_INFO_CONFIRM:
	case SME_STOP_CONFIRM:
	case SME_RTS_THRESHOLD_CONFIRM:
	case SME_FRAGMENTATION_THRESHOLD_CONFIRM:
	case SME_WEP_INDEX_CONFIRM:
	case SME_WEP_KEY1_CONFIRM:
	case SME_WEP_KEY2_CONFIRM:
	case SME_WEP_KEY3_CONFIRM:
	case SME_WEP_KEY4_CONFIRM:
	case SME_WEP_FLAG_CONFIRM:
	case SME_RSN_UCAST_CONFIRM:
	case SME_RSN_MCAST_CONFIRM:
	case SME_RSN_AUTH_CONFIRM:
	case SME_RSN_ENABLED_CONFIRM:
	case SME_RSN_MODE_CONFIRM:
	case SME_MODE_SET_CONFIRM:
	case SME_TERMINATE:
	default:
		break;
	}
}

static
void hostif_sme_task(unsigned long dev)
{
	struct ks_wlan_private *priv = (struct ks_wlan_private *)dev;

	if (priv->dev_state < DEVICE_STATE_BOOT)
		return;

	if (cnt_smeqbody(priv) <= 0)
		return;

	hostif_sme_execute(priv, priv->sme_i.event_buff[priv->sme_i.qhead]);
	inc_smeqhead(priv);
	if (cnt_smeqbody(priv) > 0)
		tasklet_schedule(&priv->sme_task);
}

/* send to Station Management Entity module */
void hostif_sme_enqueue(struct ks_wlan_private *priv, u16 event)
{
	/* enqueue sme event */
	if (cnt_smeqbody(priv) < (SME_EVENT_BUFF_SIZE - 1)) {
		priv->sme_i.event_buff[priv->sme_i.qtail] = event;
		inc_smeqtail(priv);
	} else {
		/* in case of buffer overflow */
		netdev_err(priv->net_dev, "sme queue buffer overflow\n");
	}

	tasklet_schedule(&priv->sme_task);
}

static inline void hostif_aplist_init(struct ks_wlan_private *priv)
{
	size_t size = LOCAL_APLIST_MAX * sizeof(struct local_ap);

	priv->aplist.size = 0;
	memset(&priv->aplist.ap[0], 0, size);
}

static inline void hostif_status_init(struct ks_wlan_private *priv)
{
	priv->infra_status = 0;
	priv->current_rate = 4;
	priv->connect_status = DISCONNECT_STATUS;
}

static inline void hostif_sme_init(struct ks_wlan_private *priv)
{
	priv->sme_i.sme_status = SME_IDLE;
	priv->sme_i.qhead = 0;
	priv->sme_i.qtail = 0;
	spin_lock_init(&priv->sme_i.sme_spin);
	priv->sme_i.sme_flag = 0;
	tasklet_init(&priv->sme_task, hostif_sme_task, (unsigned long)priv);
}

static inline void hostif_wpa_init(struct ks_wlan_private *priv)
{
	memset(&priv->wpa, 0, sizeof(priv->wpa));
	priv->wpa.rsn_enabled = false;
	priv->wpa.mic_failure.failure = 0;
	priv->wpa.mic_failure.last_failure_time = 0;
	priv->wpa.mic_failure.stop = 0;
}

static inline void hostif_power_save_init(struct ks_wlan_private *priv)
{
	atomic_set(&priv->psstatus.status, PS_NONE);
	atomic_set(&priv->psstatus.confirm_wait, 0);
	atomic_set(&priv->psstatus.snooze_guard, 0);
	init_completion(&priv->psstatus.wakeup_wait);
	INIT_WORK(&priv->wakeup_work, ks_wlan_hw_wakeup_task);
}

static inline void hostif_pmklist_init(struct ks_wlan_private *priv)
{
	int i;

	memset(&priv->pmklist, 0, sizeof(priv->pmklist));
	INIT_LIST_HEAD(&priv->pmklist.head);
	for (i = 0; i < PMK_LIST_MAX; i++)
		INIT_LIST_HEAD(&priv->pmklist.pmk[i].list);
}

static inline void hostif_counters_init(struct ks_wlan_private *priv)
{
	priv->dev_count = 0;
	atomic_set(&priv->event_count, 0);
	atomic_set(&priv->rec_count, 0);
}

int hostif_init(struct ks_wlan_private *priv)
{
	hostif_aplist_init(priv);
	hostif_status_init(priv);

	spin_lock_init(&priv->multicast_spin);
	spin_lock_init(&priv->dev_read_lock);
	init_waitqueue_head(&priv->devread_wait);

	hostif_counters_init(priv);
	hostif_power_save_init(priv);
	hostif_wpa_init(priv);
	hostif_pmklist_init(priv);
	hostif_sme_init(priv);

	return 0;
}

void hostif_exit(struct ks_wlan_private *priv)
{
	tasklet_kill(&priv->sme_task);
}
