// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
 * All rights reserved.
 */

#include "cfg80211.h"

#define FRAME_TYPE_ID			0
#define ACTION_CAT_ID			24
#define ACTION_SUBTYPE_ID		25
#define P2P_PUB_ACTION_SUBTYPE		30

#define ACTION_FRAME			0xd0
#define GO_INTENT_ATTR_ID		0x04
#define CHANLIST_ATTR_ID		0x0b
#define OPERCHAN_ATTR_ID		0x11
#define PUB_ACTION_ATTR_ID		0x04
#define P2PELEM_ATTR_ID			0xdd

#define GO_NEG_REQ			0x00
#define GO_NEG_RSP			0x01
#define GO_NEG_CONF			0x02
#define P2P_INV_REQ			0x03
#define P2P_INV_RSP			0x04
#define PUBLIC_ACT_VENDORSPEC		0x09
#define GAS_INITIAL_REQ			0x0a
#define GAS_INITIAL_RSP			0x0b

#define WILC_INVALID_CHANNEL		0

static const struct ieee80211_txrx_stypes
	wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
	[NL80211_IFTYPE_STATION] = {
		.tx = 0xffff,
		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
			BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
	},
	[NL80211_IFTYPE_AP] = {
		.tx = 0xffff,
		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
			BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
			BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
			BIT(IEEE80211_STYPE_DISASSOC >> 4) |
			BIT(IEEE80211_STYPE_AUTH >> 4) |
			BIT(IEEE80211_STYPE_DEAUTH >> 4) |
			BIT(IEEE80211_STYPE_ACTION >> 4)
	},
	[NL80211_IFTYPE_P2P_CLIENT] = {
		.tx = 0xffff,
		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
			BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
			BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
			BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
			BIT(IEEE80211_STYPE_DISASSOC >> 4) |
			BIT(IEEE80211_STYPE_AUTH >> 4) |
			BIT(IEEE80211_STYPE_DEAUTH >> 4)
	}
};

static const struct wiphy_wowlan_support wowlan_support = {
	.flags = WIPHY_WOWLAN_ANY
};

struct wilc_p2p_mgmt_data {
	int size;
	u8 *buff;
};

static const u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
static const u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};

static void cfg_scan_result(enum scan_event scan_event,
			    struct wilc_rcvd_net_info *info, void *user_void)
{
	struct wilc_priv *priv = user_void;

	if (!priv->cfg_scanning)
		return;

	if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
		s32 freq;
		struct ieee80211_channel *channel;
		struct cfg80211_bss *bss;
		struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;

		if (!wiphy || !info)
			return;

		freq = ieee80211_channel_to_frequency((s32)info->ch,
						      NL80211_BAND_2GHZ);
		channel = ieee80211_get_channel(wiphy, freq);
		if (!channel)
			return;

		bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt,
						info->frame_len,
						(s32)info->rssi * 100,
						GFP_KERNEL);
		if (!bss)
			cfg80211_put_bss(wiphy, bss);
	} else if (scan_event == SCAN_EVENT_DONE) {
		mutex_lock(&priv->scan_req_lock);

		if (priv->scan_req) {
			struct cfg80211_scan_info info = {
				.aborted = false,
			};

			cfg80211_scan_done(priv->scan_req, &info);
			priv->cfg_scanning = false;
			priv->scan_req = NULL;
		}
		mutex_unlock(&priv->scan_req_lock);
	} else if (scan_event == SCAN_EVENT_ABORTED) {
		mutex_lock(&priv->scan_req_lock);

		if (priv->scan_req) {
			struct cfg80211_scan_info info = {
				.aborted = false,
			};

			cfg80211_scan_done(priv->scan_req, &info);
			priv->cfg_scanning = false;
			priv->scan_req = NULL;
		}
		mutex_unlock(&priv->scan_req_lock);
	}
}

static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
			       void *priv_data)
{
	struct wilc_priv *priv = priv_data;
	struct net_device *dev = priv->dev;
	struct wilc_vif *vif = netdev_priv(dev);
	struct wilc *wl = vif->wilc;
	struct host_if_drv *wfi_drv = priv->hif_drv;
	struct wilc_conn_info *conn_info = &wfi_drv->conn_info;
	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;

	vif->connecting = false;

	if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
		u16 connect_status = conn_info->status;

		if (mac_status == WILC_MAC_STATUS_DISCONNECTED &&
		    connect_status == WLAN_STATUS_SUCCESS) {
			connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
			wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);

			if (vif->iftype != WILC_CLIENT_MODE)
				wl->sta_ch = WILC_INVALID_CHANNEL;

			netdev_err(dev, "Unspecified failure\n");
		}

		if (connect_status == WLAN_STATUS_SUCCESS)
			memcpy(priv->associated_bss, conn_info->bssid,
			       ETH_ALEN);

		cfg80211_ref_bss(wiphy, vif->bss);
		cfg80211_connect_bss(dev, conn_info->bssid, vif->bss,
				     conn_info->req_ies,
				     conn_info->req_ies_len,
				     conn_info->resp_ies,
				     conn_info->resp_ies_len,
				     connect_status, GFP_KERNEL,
				     NL80211_TIMEOUT_UNSPECIFIED);

		vif->bss = NULL;
	} else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
		u16 reason = 0;

		priv->p2p.local_random = 0x01;
		priv->p2p.recv_random = 0x00;
		priv->p2p.is_wilc_ie = false;
		eth_zero_addr(priv->associated_bss);
		wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);

		if (vif->iftype != WILC_CLIENT_MODE) {
			wl->sta_ch = WILC_INVALID_CHANNEL;
		} else {
			if (wfi_drv->ifc_up)
				reason = 3;
			else
				reason = 1;
		}

		cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
	}
}

struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
{
	struct wilc_vif *vif;

	vif = list_first_or_null_rcu(&wl->vif_list, typeof(*vif), list);
	if (!vif)
		return ERR_PTR(-EINVAL);

	return vif;
}

static int set_channel(struct wiphy *wiphy,
		       struct cfg80211_chan_def *chandef)
{
	struct wilc *wl = wiphy_priv(wiphy);
	struct wilc_vif *vif;
	u32 channelnum;
	int result;
	int srcu_idx;

	srcu_idx = srcu_read_lock(&wl->srcu);
	vif = wilc_get_wl_to_vif(wl);
	if (IS_ERR(vif)) {
		srcu_read_unlock(&wl->srcu, srcu_idx);
		return PTR_ERR(vif);
	}

	channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);

	wl->op_ch = channelnum;
	result = wilc_set_mac_chnl_num(vif, channelnum);
	if (result)
		netdev_err(vif->ndev, "Error in setting channel\n");

	srcu_read_unlock(&wl->srcu, srcu_idx);
	return result;
}

static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
{
	struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
	struct wilc_priv *priv = &vif->priv;
	u32 i;
	int ret = 0;
	u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
	u8 scan_type;

	if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
		netdev_err(vif->ndev, "Requested scanned channels over\n");
		return -EINVAL;
	}

	priv->scan_req = request;
	priv->cfg_scanning = true;
	for (i = 0; i < request->n_channels; i++) {
		u16 freq = request->channels[i]->center_freq;

		scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
	}

	if (request->n_ssids)
		scan_type = WILC_FW_ACTIVE_SCAN;
	else
		scan_type = WILC_FW_PASSIVE_SCAN;

	ret = wilc_scan(vif, WILC_FW_USER_SCAN, scan_type, scan_ch_list,
			request->n_channels, cfg_scan_result, (void *)priv,
			request);

	if (ret) {
		priv->scan_req = NULL;
		priv->cfg_scanning = false;
	}

	return ret;
}

static int connect(struct wiphy *wiphy, struct net_device *dev,
		   struct cfg80211_connect_params *sme)
{
	struct wilc_vif *vif = netdev_priv(dev);
	struct wilc_priv *priv = &vif->priv;
	struct host_if_drv *wfi_drv = priv->hif_drv;
	int ret;
	u32 i;
	u8 security = WILC_FW_SEC_NO;
	enum authtype auth_type = WILC_FW_AUTH_ANY;
	u32 cipher_group;
	struct cfg80211_bss *bss;
	void *join_params;
	u8 ch;

	vif->connecting = true;

	memset(priv->wep_key, 0, sizeof(priv->wep_key));
	memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));

	cipher_group = sme->crypto.cipher_group;
	if (cipher_group != 0) {
		if (cipher_group == WLAN_CIPHER_SUITE_WEP40) {
			security = WILC_FW_SEC_WEP;

			priv->wep_key_len[sme->key_idx] = sme->key_len;
			memcpy(priv->wep_key[sme->key_idx], sme->key,
			       sme->key_len);

			wilc_set_wep_default_keyid(vif, sme->key_idx);
			wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
						 sme->key_idx);
		} else if (cipher_group == WLAN_CIPHER_SUITE_WEP104) {
			security = WILC_FW_SEC_WEP_EXTENDED;

			priv->wep_key_len[sme->key_idx] = sme->key_len;
			memcpy(priv->wep_key[sme->key_idx], sme->key,
			       sme->key_len);

			wilc_set_wep_default_keyid(vif, sme->key_idx);
			wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
						 sme->key_idx);
		} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
			if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
				security = WILC_FW_SEC_WPA2_TKIP;
			else
				security = WILC_FW_SEC_WPA2_AES;
		} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
			if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
				security = WILC_FW_SEC_WPA_TKIP;
			else
				security = WILC_FW_SEC_WPA_AES;
		} else {
			ret = -ENOTSUPP;
			netdev_err(dev, "%s: Unsupported cipher\n",
				   __func__);
			goto out_error;
		}
	}

	if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
	    (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
		for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
			u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];

			if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
				security |= WILC_FW_TKIP;
			else
				security |= WILC_FW_AES;
		}
	}

	switch (sme->auth_type) {
	case NL80211_AUTHTYPE_OPEN_SYSTEM:
		auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
		break;

	case NL80211_AUTHTYPE_SHARED_KEY:
		auth_type = WILC_FW_AUTH_SHARED_KEY;
		break;

	default:
		break;
	}

	if (sme->crypto.n_akm_suites) {
		if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
			auth_type = WILC_FW_AUTH_IEEE8021;
	}

	if (wfi_drv->usr_scan_req.scan_result) {
		netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
		ret = -EBUSY;
		goto out_error;
	}

	bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid,
			       sme->ssid_len, IEEE80211_BSS_TYPE_ANY,
			       IEEE80211_PRIVACY(sme->privacy));
	if (!bss) {
		ret = -EINVAL;
		goto out_error;
	}

	if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) {
		ret = -EALREADY;
		goto out_put_bss;
	}

	join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
	if (!join_params) {
		netdev_err(dev, "%s: failed to construct join param\n",
			   __func__);
		ret = -EINVAL;
		goto out_put_bss;
	}

	ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
	vif->wilc->op_ch = ch;
	if (vif->iftype != WILC_CLIENT_MODE)
		vif->wilc->sta_ch = ch;

	wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE);

	wfi_drv->conn_info.security = security;
	wfi_drv->conn_info.auth_type = auth_type;
	wfi_drv->conn_info.ch = ch;
	wfi_drv->conn_info.conn_result = cfg_connect_result;
	wfi_drv->conn_info.arg = priv;
	wfi_drv->conn_info.param = join_params;

	ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
	if (ret) {
		netdev_err(dev, "wilc_set_join_req(): Error\n");
		ret = -ENOENT;
		if (vif->iftype != WILC_CLIENT_MODE)
			vif->wilc->sta_ch = WILC_INVALID_CHANNEL;
		wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE);
		wfi_drv->conn_info.conn_result = NULL;
		kfree(join_params);
		goto out_put_bss;
	}
	kfree(join_params);
	vif->bss = bss;
	cfg80211_put_bss(wiphy, bss);
	return 0;

out_put_bss:
	cfg80211_put_bss(wiphy, bss);

out_error:
	vif->connecting = false;
	return ret;
}

static int disconnect(struct wiphy *wiphy, struct net_device *dev,
		      u16 reason_code)
{
	struct wilc_vif *vif = netdev_priv(dev);
	struct wilc_priv *priv = &vif->priv;
	struct wilc *wilc = vif->wilc;
	int ret;

	vif->connecting = false;

	if (!wilc)
		return -EIO;

	if (wilc->close) {
		/* already disconnected done */
		cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
		return 0;
	}

	if (vif->iftype != WILC_CLIENT_MODE)
		wilc->sta_ch = WILC_INVALID_CHANNEL;
	wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);

	priv->p2p.local_random = 0x01;
	priv->p2p.recv_random = 0x00;
	priv->p2p.is_wilc_ie = false;
	priv->hif_drv->p2p_timeout = 0;

	ret = wilc_disconnect(vif);
	if (ret != 0) {
		netdev_err(priv->dev, "Error in disconnecting\n");
		ret = -EINVAL;
	}

	vif->bss = NULL;

	return ret;
}

static inline void wilc_wfi_cfg_copy_wep_info(struct wilc_priv *priv,
					      u8 key_index,
					      struct key_params *params)
{
	priv->wep_key_len[key_index] = params->key_len;
	memcpy(priv->wep_key[key_index], params->key, params->key_len);
}

static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
{
	if (!priv->wilc_gtk[idx]) {
		priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
					      GFP_KERNEL);
		if (!priv->wilc_gtk[idx])
			return -ENOMEM;
	}

	if (!priv->wilc_ptk[idx]) {
		priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
					      GFP_KERNEL);
		if (!priv->wilc_ptk[idx])
			return -ENOMEM;
	}

	return 0;
}

static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
				      struct key_params *params)
{
	kfree(key_info->key);

	key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
	if (!key_info->key)
		return -ENOMEM;

	kfree(key_info->seq);

	if (params->seq_len > 0) {
		key_info->seq = kmemdup(params->seq, params->seq_len,
					GFP_KERNEL);
		if (!key_info->seq)
			return -ENOMEM;
	}

	key_info->cipher = params->cipher;
	key_info->key_len = params->key_len;
	key_info->seq_len = params->seq_len;

	return 0;
}

static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
		   bool pairwise, const u8 *mac_addr, struct key_params *params)

{
	int ret = 0, keylen = params->key_len;
	const u8 *rx_mic = NULL;
	const u8 *tx_mic = NULL;
	u8 mode = WILC_FW_SEC_NO;
	u8 op_mode;
	struct wilc_vif *vif = netdev_priv(netdev);
	struct wilc_priv *priv = &vif->priv;

	switch (params->cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
		if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
			wilc_wfi_cfg_copy_wep_info(priv, key_index, params);

			if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
				mode = WILC_FW_SEC_WEP;
			else
				mode = WILC_FW_SEC_WEP_EXTENDED;

			ret = wilc_add_wep_key_bss_ap(vif, params->key,
						      params->key_len,
						      key_index, mode,
						      WILC_FW_AUTH_OPEN_SYSTEM);
			break;
		}
		if (memcmp(params->key, priv->wep_key[key_index],
			   params->key_len)) {
			wilc_wfi_cfg_copy_wep_info(priv, key_index, params);

			ret = wilc_add_wep_key_bss_sta(vif, params->key,
						       params->key_len,
						       key_index);
		}

		break;

	case WLAN_CIPHER_SUITE_TKIP:
	case WLAN_CIPHER_SUITE_CCMP:
		if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
		    priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
			struct wilc_wfi_key *key;

			ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
			if (ret)
				return -ENOMEM;

			if (params->key_len > 16 &&
			    params->cipher == WLAN_CIPHER_SUITE_TKIP) {
				tx_mic = params->key + 24;
				rx_mic = params->key + 16;
				keylen = params->key_len - 16;
			}

			if (!pairwise) {
				if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
					mode = WILC_FW_SEC_WPA_TKIP;
				else
					mode = WILC_FW_SEC_WPA2_AES;

				priv->wilc_groupkey = mode;

				key = priv->wilc_gtk[key_index];
			} else {
				if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
					mode = WILC_FW_SEC_WPA_TKIP;
				else
					mode = priv->wilc_groupkey | WILC_FW_AES;

				key = priv->wilc_ptk[key_index];
			}
			ret = wilc_wfi_cfg_copy_wpa_info(key, params);
			if (ret)
				return -ENOMEM;

			op_mode = WILC_AP_MODE;
		} else {
			if (params->key_len > 16 &&
			    params->cipher == WLAN_CIPHER_SUITE_TKIP) {
				rx_mic = params->key + 24;
				tx_mic = params->key + 16;
				keylen = params->key_len - 16;
			}

			op_mode = WILC_STATION_MODE;
		}

		if (!pairwise)
			ret = wilc_add_rx_gtk(vif, params->key, keylen,
					      key_index, params->seq_len,
					      params->seq, rx_mic, tx_mic,
					      op_mode, mode);
		else
			ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
					   rx_mic, tx_mic, op_mode, mode,
					   key_index);

		break;

	default:
		netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
		ret = -ENOTSUPP;
	}

	return ret;
}

static int del_key(struct wiphy *wiphy, struct net_device *netdev,
		   u8 key_index,
		   bool pairwise,
		   const u8 *mac_addr)
{
	struct wilc_vif *vif = netdev_priv(netdev);
	struct wilc_priv *priv = &vif->priv;

	if (priv->wilc_gtk[key_index]) {
		kfree(priv->wilc_gtk[key_index]->key);
		priv->wilc_gtk[key_index]->key = NULL;
		kfree(priv->wilc_gtk[key_index]->seq);
		priv->wilc_gtk[key_index]->seq = NULL;

		kfree(priv->wilc_gtk[key_index]);
		priv->wilc_gtk[key_index] = NULL;
	}

	if (priv->wilc_ptk[key_index]) {
		kfree(priv->wilc_ptk[key_index]->key);
		priv->wilc_ptk[key_index]->key = NULL;
		kfree(priv->wilc_ptk[key_index]->seq);
		priv->wilc_ptk[key_index]->seq = NULL;
		kfree(priv->wilc_ptk[key_index]);
		priv->wilc_ptk[key_index] = NULL;
	}

	if (key_index <= 3 && priv->wep_key_len[key_index]) {
		memset(priv->wep_key[key_index], 0,
		       priv->wep_key_len[key_index]);
		priv->wep_key_len[key_index] = 0;
		wilc_remove_wep_key(vif, key_index);
	}

	return 0;
}

static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
		   bool pairwise, const u8 *mac_addr, void *cookie,
		   void (*callback)(void *cookie, struct key_params *))
{
	struct wilc_vif *vif = netdev_priv(netdev);
	struct wilc_priv *priv = &vif->priv;
	struct  key_params key_params;

	if (!pairwise) {
		key_params.key = priv->wilc_gtk[key_index]->key;
		key_params.cipher = priv->wilc_gtk[key_index]->cipher;
		key_params.key_len = priv->wilc_gtk[key_index]->key_len;
		key_params.seq = priv->wilc_gtk[key_index]->seq;
		key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
	} else {
		key_params.key = priv->wilc_ptk[key_index]->key;
		key_params.cipher = priv->wilc_ptk[key_index]->cipher;
		key_params.key_len = priv->wilc_ptk[key_index]->key_len;
		key_params.seq = priv->wilc_ptk[key_index]->seq;
		key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
	}

	callback(cookie, &key_params);

	return 0;
}

static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
			   u8 key_index, bool unicast, bool multicast)
{
	struct wilc_vif *vif = netdev_priv(netdev);

	wilc_set_wep_default_keyid(vif, key_index);

	return 0;
}

static int get_station(struct wiphy *wiphy, struct net_device *dev,
		       const u8 *mac, struct station_info *sinfo)
{
	struct wilc_vif *vif = netdev_priv(dev);
	struct wilc_priv *priv = &vif->priv;
	u32 i = 0;
	u32 associatedsta = ~0;
	u32 inactive_time = 0;

	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
		for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
			if (!(memcmp(mac,
				     priv->assoc_stainfo.sta_associated_bss[i],
				     ETH_ALEN))) {
				associatedsta = i;
				break;
			}
		}

		if (associatedsta == ~0) {
			netdev_err(dev, "sta required is not associated\n");
			return -ENOENT;
		}

		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);

		wilc_get_inactive_time(vif, mac, &inactive_time);
		sinfo->inactive_time = 1000 * inactive_time;
	} else if (vif->iftype == WILC_STATION_MODE) {
		struct rf_info stats;

		wilc_get_statistics(vif, &stats);

		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
				 BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
				 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
				 BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
				 BIT_ULL(NL80211_STA_INFO_TX_BITRATE);

		sinfo->signal = stats.rssi;
		sinfo->rx_packets = stats.rx_cnt;
		sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
		sinfo->tx_failed = stats.tx_fail_cnt;
		sinfo->txrate.legacy = stats.link_speed * 10;

		if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
		    stats.link_speed != DEFAULT_LINK_SPEED)
			wilc_enable_tcp_ack_filter(vif, true);
		else if (stats.link_speed != DEFAULT_LINK_SPEED)
			wilc_enable_tcp_ack_filter(vif, false);
	}
	return 0;
}

static int change_bss(struct wiphy *wiphy, struct net_device *dev,
		      struct bss_parameters *params)
{
	return 0;
}

static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
	int ret = -EINVAL;
	struct cfg_param_attr cfg_param_val;
	struct wilc *wl = wiphy_priv(wiphy);
	struct wilc_vif *vif;
	struct wilc_priv *priv;
	int srcu_idx;

	srcu_idx = srcu_read_lock(&wl->srcu);
	vif = wilc_get_wl_to_vif(wl);
	if (IS_ERR(vif))
		goto out;

	priv = &vif->priv;
	cfg_param_val.flag = 0;

	if (changed & WIPHY_PARAM_RETRY_SHORT) {
		netdev_dbg(vif->ndev,
			   "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
			   wiphy->retry_short);
		cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
		cfg_param_val.short_retry_limit = wiphy->retry_short;
	}
	if (changed & WIPHY_PARAM_RETRY_LONG) {
		netdev_dbg(vif->ndev,
			   "Setting WIPHY_PARAM_RETRY_LONG %d\n",
			   wiphy->retry_long);
		cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
		cfg_param_val.long_retry_limit = wiphy->retry_long;
	}
	if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
		if (wiphy->frag_threshold > 255 &&
		    wiphy->frag_threshold < 7937) {
			netdev_dbg(vif->ndev,
				   "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
				   wiphy->frag_threshold);
			cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
			cfg_param_val.frag_threshold = wiphy->frag_threshold;
		} else {
			netdev_err(vif->ndev,
				   "Fragmentation threshold out of range\n");
			goto out;
		}
	}

	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
		if (wiphy->rts_threshold > 255) {
			netdev_dbg(vif->ndev,
				   "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
				   wiphy->rts_threshold);
			cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
			cfg_param_val.rts_threshold = wiphy->rts_threshold;
		} else {
			netdev_err(vif->ndev, "RTS threshold out of range\n");
			goto out;
		}
	}

	ret = wilc_hif_set_cfg(vif, &cfg_param_val);
	if (ret)
		netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");

out:
	srcu_read_unlock(&wl->srcu, srcu_idx);
	return ret;
}

static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
		     struct cfg80211_pmksa *pmksa)
{
	struct wilc_vif *vif = netdev_priv(netdev);
	struct wilc_priv *priv = &vif->priv;
	u32 i;
	int ret = 0;
	u8 flag = 0;

	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
			    ETH_ALEN)) {
			flag = PMKID_FOUND;
			break;
		}
	}
	if (i < WILC_MAX_NUM_PMKIDS) {
		memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
		       ETH_ALEN);
		memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
		       WLAN_PMKID_LEN);
		if (!(flag == PMKID_FOUND))
			priv->pmkid_list.numpmkid++;
	} else {
		netdev_err(netdev, "Invalid PMKID index\n");
		ret = -EINVAL;
	}

	if (!ret)
		ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);

	return ret;
}

static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
		     struct cfg80211_pmksa *pmksa)
{
	u32 i;
	int ret = 0;
	struct wilc_vif *vif = netdev_priv(netdev);
	struct wilc_priv *priv = &vif->priv;

	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
			    ETH_ALEN)) {
			memset(&priv->pmkid_list.pmkidlist[i], 0,
			       sizeof(struct wilc_pmkid));
			break;
		}
	}

	if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
		for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
			memcpy(priv->pmkid_list.pmkidlist[i].bssid,
			       priv->pmkid_list.pmkidlist[i + 1].bssid,
			       ETH_ALEN);
			memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
			       priv->pmkid_list.pmkidlist[i + 1].pmkid,
			       WLAN_PMKID_LEN);
		}
		priv->pmkid_list.numpmkid--;
	} else {
		ret = -EINVAL;
	}

	return ret;
}

static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
{
	struct wilc_vif *vif = netdev_priv(netdev);

	memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));

	return 0;
}

static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx,
					      u8 op_ch_attr_idx, u8 sta_ch)
{
	int i = 0;
	int j = 0;

	if (ch_list_attr_idx) {
		u8 limit = ch_list_attr_idx + 3 + buf[ch_list_attr_idx + 1];

		for (i = ch_list_attr_idx + 3; i < limit; i++) {
			if (buf[i] == 0x51) {
				for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
					buf[j] = sta_ch;
				break;
			}
		}
	}

	if (op_ch_attr_idx) {
		buf[op_ch_attr_idx + 6] = 0x51;
		buf[op_ch_attr_idx + 7] = sta_ch;
	}
}

static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len, u8 sta_ch)
{
	u32 index = 0;
	u8 op_channel_attr_index = 0;
	u8 channel_list_attr_index = 0;

	while (index < len) {
		if (buf[index] == GO_INTENT_ATTR_ID)
			buf[index + 3] = (buf[index + 3]  & 0x01) | (0x00 << 1);

		if (buf[index] ==  CHANLIST_ATTR_ID)
			channel_list_attr_index = index;
		else if (buf[index] ==  OPERCHAN_ATTR_ID)
			op_channel_attr_index = index;
		index += buf[index + 1] + 3;
	}
	if (sta_ch != WILC_INVALID_CHANNEL)
		wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index,
					   op_channel_attr_index, sta_ch);
}

static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch,
					 u8 iftype, u8 sta_ch)
{
	u32 index = 0;
	u8 op_channel_attr_index = 0;
	u8 channel_list_attr_index = 0;

	while (index < len) {
		if (buf[index] == GO_INTENT_ATTR_ID) {
			buf[index + 3] = (buf[index + 3]  & 0x01) | (0x0f << 1);

			break;
		}

		if (buf[index] ==  CHANLIST_ATTR_ID)
			channel_list_attr_index = index;
		else if (buf[index] ==  OPERCHAN_ATTR_ID)
			op_channel_attr_index = index;
		index += buf[index + 1] + 3;
	}
	if (sta_ch != WILC_INVALID_CHANNEL && oper_ch)
		wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index,
					   op_channel_attr_index, sta_ch);
}

static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff,
					      u32 size)
{
	int i;
	u8 subtype;
	struct wilc_vif *vif = netdev_priv(priv->dev);

	subtype = buff[P2P_PUB_ACTION_SUBTYPE];
	if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
	    !priv->p2p.is_wilc_ie) {
		for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
			if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
				priv->p2p.recv_random = buff[i + 6];
				priv->p2p.is_wilc_ie = true;
				break;
			}
		}
	}

	if (priv->p2p.local_random <= priv->p2p.recv_random) {
		netdev_dbg(vif->ndev,
			   "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n",
			   priv->p2p.local_random, priv->p2p.recv_random);
		return;
	}

	if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP ||
	    subtype == P2P_INV_REQ || subtype == P2P_INV_RSP) {
		for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
			if (buff[i] == P2PELEM_ATTR_ID &&
			    !(memcmp(p2p_oui, &buff[i + 2], 4))) {
				wilc_wfi_cfg_parse_rx_action(&buff[i + 6],
							     size - (i + 6),
							     vif->wilc->sta_ch);
				break;
			}
		}
	}
}

void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
{
	struct wilc *wl = vif->wilc;
	struct wilc_priv *priv = &vif->priv;
	struct host_if_drv *wfi_drv = priv->hif_drv;
	u32 header, pkt_offset;
	s32 freq;
	__le16 fc;

	header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
	pkt_offset = GET_PKT_OFFSET(header);

	if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
		bool ack = false;

		if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP ||
		    pkt_offset & IS_MGMT_STATUS_SUCCES)
			ack = true;

		cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
					size, ack, GFP_KERNEL);
		return;
	}

	freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);

	fc = ((struct ieee80211_hdr *)buff)->frame_control;
	if (!ieee80211_is_action(fc)) {
		cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
		return;
	}

	if (priv->cfg_scanning &&
	    time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
		netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
		return;
	}
	if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
		u8 subtype = buff[P2P_PUB_ACTION_SUBTYPE];

		switch (buff[ACTION_SUBTYPE_ID]) {
		case GAS_INITIAL_REQ:
		case GAS_INITIAL_RSP:
			break;

		case PUBLIC_ACT_VENDORSPEC:
			if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4))
				wilc_wfi_cfg_parse_rx_vendor_spec(priv, buff,
								  size);

			if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
			    priv->p2p.is_wilc_ie)
				size -= 7;

			break;

		default:
			netdev_dbg(vif->ndev,
				   "%s: Not handled action frame type:%x\n",
				   __func__, buff[ACTION_SUBTYPE_ID]);
			break;
		}
	}

	cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
}

static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
{
	struct wilc_p2p_mgmt_data *pv_data = priv;

	kfree(pv_data->buff);
	kfree(pv_data);
}

static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
{
	struct wilc_vif *vif = data;
	struct wilc_priv *priv = &vif->priv;
	struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;

	if (cookie != params->listen_cookie)
		return;

	priv->p2p_listen_state = false;

	cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
					   params->listen_ch, GFP_KERNEL);
}

static int remain_on_channel(struct wiphy *wiphy,
			     struct wireless_dev *wdev,
			     struct ieee80211_channel *chan,
			     unsigned int duration, u64 *cookie)
{
	int ret = 0;
	struct wilc_vif *vif = netdev_priv(wdev->netdev);
	struct wilc_priv *priv = &vif->priv;
	u64 id;

	if (wdev->iftype == NL80211_IFTYPE_AP) {
		netdev_dbg(vif->ndev, "Required while in AP mode\n");
		return ret;
	}

	id = ++priv->inc_roc_cookie;
	if (id == 0)
		id = ++priv->inc_roc_cookie;

	ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
				     wilc_wfi_remain_on_channel_expired,
				     (void *)vif);
	if (ret)
		return ret;

	vif->wilc->op_ch = chan->hw_value;

	priv->remain_on_ch_params.listen_ch = chan;
	priv->remain_on_ch_params.listen_cookie = id;
	*cookie = id;
	priv->p2p_listen_state = true;
	priv->remain_on_ch_params.listen_duration = duration;

	cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
	mod_timer(&vif->hif_drv->remain_on_ch_timer,
		  jiffies + msecs_to_jiffies(duration + 1000));

	return ret;
}

static int cancel_remain_on_channel(struct wiphy *wiphy,
				    struct wireless_dev *wdev,
				    u64 cookie)
{
	struct wilc_vif *vif = netdev_priv(wdev->netdev);
	struct wilc_priv *priv = &vif->priv;

	if (cookie != priv->remain_on_ch_params.listen_cookie)
		return -ENOENT;

	return wilc_listen_state_expired(vif, cookie);
}

static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv,
					struct wilc_p2p_mgmt_data *mgmt_tx,
					struct cfg80211_mgmt_tx_params *params,
					u8 iftype, u32 buf_len)
{
	const u8 *buf = params->buf;
	size_t len = params->len;
	u32 i;
	u8 subtype = buf[P2P_PUB_ACTION_SUBTYPE];
	struct wilc_vif *vif = netdev_priv(priv->dev);

	if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) {
		if (priv->p2p.local_random == 1 &&
		    priv->p2p.recv_random < priv->p2p.local_random) {
			get_random_bytes(&priv->p2p.local_random, 1);
			priv->p2p.local_random++;
		}
	}

	if (priv->p2p.local_random <= priv->p2p.recv_random ||
	    !(subtype == GO_NEG_REQ || subtype == GO_NEG_RSP ||
	      subtype == P2P_INV_REQ || subtype == P2P_INV_RSP))
		return;

	for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
		if (buf[i] == P2PELEM_ATTR_ID &&
		    !memcmp(p2p_oui, &buf[i + 2], 4)) {
			bool oper_ch = false;
			u8 *tx_buff = &mgmt_tx->buff[i + 6];

			if (subtype == P2P_INV_REQ || subtype == P2P_INV_RSP)
				oper_ch = true;

			wilc_wfi_cfg_parse_tx_action(tx_buff, len - (i + 6),
						     oper_ch, iftype,
						     vif->wilc->sta_ch);

			break;
		}
	}

	if (subtype != P2P_INV_REQ && subtype != P2P_INV_RSP) {
		int vendor_spec_len = sizeof(p2p_vendor_spec);

		memcpy(&mgmt_tx->buff[len], p2p_vendor_spec,
		       vendor_spec_len);
		mgmt_tx->buff[len + vendor_spec_len] = priv->p2p.local_random;
		mgmt_tx->size = buf_len;
	}
}

static int mgmt_tx(struct wiphy *wiphy,
		   struct wireless_dev *wdev,
		   struct cfg80211_mgmt_tx_params *params,
		   u64 *cookie)
{
	struct ieee80211_channel *chan = params->chan;
	unsigned int wait = params->wait;
	const u8 *buf = params->buf;
	size_t len = params->len;
	const struct ieee80211_mgmt *mgmt;
	struct wilc_p2p_mgmt_data *mgmt_tx;
	struct wilc_vif *vif = netdev_priv(wdev->netdev);
	struct wilc_priv *priv = &vif->priv;
	struct host_if_drv *wfi_drv = priv->hif_drv;
	u32 buf_len = len + sizeof(p2p_vendor_spec) +
			sizeof(priv->p2p.local_random);
	int ret = 0;

	*cookie = prandom_u32();
	priv->tx_cookie = *cookie;
	mgmt = (const struct ieee80211_mgmt *)buf;

	if (!ieee80211_is_mgmt(mgmt->frame_control))
		goto out;

	mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
	if (!mgmt_tx) {
		ret = -ENOMEM;
		goto out;
	}

	mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
	if (!mgmt_tx->buff) {
		ret = -ENOMEM;
		kfree(mgmt_tx);
		goto out;
	}

	memcpy(mgmt_tx->buff, buf, len);
	mgmt_tx->size = len;

	if (ieee80211_is_probe_resp(mgmt->frame_control)) {
		wilc_set_mac_chnl_num(vif, chan->hw_value);
		vif->wilc->op_ch = chan->hw_value;
		goto out_txq_add_pkt;
	}

	if (!ieee80211_is_action(mgmt->frame_control))
		goto out_txq_add_pkt;

	if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
		if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
		    buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
			wilc_set_mac_chnl_num(vif, chan->hw_value);
			vif->wilc->op_ch = chan->hw_value;
		}
		switch (buf[ACTION_SUBTYPE_ID]) {
		case GAS_INITIAL_REQ:
		case GAS_INITIAL_RSP:
			break;

		case PUBLIC_ACT_VENDORSPEC:
			if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4))
				wilc_wfi_cfg_tx_vendor_spec(priv, mgmt_tx,
							    params, vif->iftype,
							    buf_len);
			else
				netdev_dbg(vif->ndev,
					   "Not a P2P public action frame\n");

			break;

		default:
			netdev_dbg(vif->ndev,
				   "%s: Not handled action frame type:%x\n",
				   __func__, buf[ACTION_SUBTYPE_ID]);
			break;
		}
	}

	wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));

out_txq_add_pkt:

	wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
				   mgmt_tx->buff, mgmt_tx->size,
				   wilc_wfi_mgmt_tx_complete);

out:

	return ret;
}

static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
			       struct wireless_dev *wdev,
			       u64 cookie)
{
	struct wilc_vif *vif = netdev_priv(wdev->netdev);
	struct wilc_priv *priv = &vif->priv;
	struct host_if_drv *wfi_drv = priv->hif_drv;

	wfi_drv->p2p_timeout = jiffies;

	if (!priv->p2p_listen_state) {
		struct wilc_wfi_p2p_listen_params *params;

		params = &priv->remain_on_ch_params;

		cfg80211_remain_on_channel_expired(wdev,
						   params->listen_cookie,
						   params->listen_ch,
						   GFP_KERNEL);
	}

	return 0;
}

void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
			      u16 frame_type, bool reg)
{
	struct wilc *wl = wiphy_priv(wiphy);
	struct wilc_vif *vif = netdev_priv(wdev->netdev);

	if (!frame_type)
		return;

	switch (frame_type) {
	case IEEE80211_STYPE_PROBE_REQ:
		vif->frame_reg[0].type = frame_type;
		vif->frame_reg[0].reg = reg;
		break;

	case IEEE80211_STYPE_ACTION:
		vif->frame_reg[1].type = frame_type;
		vif->frame_reg[1].reg = reg;
		break;

	default:
		break;
	}

	if (!wl->initialized)
		return;
	wilc_frame_register(vif, frame_type, reg);
}

static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
			       s32 rssi_thold, u32 rssi_hyst)
{
	return 0;
}

static int dump_station(struct wiphy *wiphy, struct net_device *dev,
			int idx, u8 *mac, struct station_info *sinfo)
{
	struct wilc_vif *vif = netdev_priv(dev);
	int ret;

	if (idx != 0)
		return -ENOENT;

	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);

	ret = wilc_get_rssi(vif, &sinfo->signal);
	if (ret)
		return ret;

	memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
	return 0;
}

static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
			  bool enabled, int timeout)
{
	struct wilc_vif *vif = netdev_priv(dev);
	struct wilc_priv *priv = &vif->priv;

	if (!priv->hif_drv)
		return -EIO;

	wilc_set_power_mgmt(vif, enabled, timeout);

	return 0;
}

static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
			       enum nl80211_iftype type,
			       struct vif_params *params)
{
	struct wilc *wl = wiphy_priv(wiphy);
	struct wilc_vif *vif = netdev_priv(dev);
	struct wilc_priv *priv = &vif->priv;

	priv->p2p.local_random = 0x01;
	priv->p2p.recv_random = 0x00;
	priv->p2p.is_wilc_ie = false;

	switch (type) {
	case NL80211_IFTYPE_STATION:
		vif->connecting = false;
		dev->ieee80211_ptr->iftype = type;
		priv->wdev.iftype = type;
		vif->monitor_flag = 0;
		if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
			wilc_wfi_deinit_mon_interface(wl, true);
		vif->iftype = WILC_STATION_MODE;

		if (wl->initialized)
			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
						WILC_STATION_MODE, vif->idx);

		memset(priv->assoc_stainfo.sta_associated_bss, 0,
		       WILC_MAX_NUM_STA * ETH_ALEN);
		break;

	case NL80211_IFTYPE_P2P_CLIENT:
		vif->connecting = false;
		dev->ieee80211_ptr->iftype = type;
		priv->wdev.iftype = type;
		vif->monitor_flag = 0;
		vif->iftype = WILC_CLIENT_MODE;

		if (wl->initialized)
			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
						WILC_STATION_MODE, vif->idx);
		break;

	case NL80211_IFTYPE_AP:
		dev->ieee80211_ptr->iftype = type;
		priv->wdev.iftype = type;
		vif->iftype = WILC_AP_MODE;

		if (wl->initialized)
			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
						WILC_AP_MODE, vif->idx);
		break;

	case NL80211_IFTYPE_P2P_GO:
		dev->ieee80211_ptr->iftype = type;
		priv->wdev.iftype = type;
		vif->iftype = WILC_GO_MODE;

		if (wl->initialized)
			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
						WILC_AP_MODE, vif->idx);
		break;

	default:
		netdev_err(dev, "Unknown interface type= %d\n", type);
		return -EINVAL;
	}

	return 0;
}

static int start_ap(struct wiphy *wiphy, struct net_device *dev,
		    struct cfg80211_ap_settings *settings)
{
	struct wilc_vif *vif = netdev_priv(dev);
	int ret;

	ret = set_channel(wiphy, &settings->chandef);
	if (ret != 0)
		netdev_err(dev, "Error in setting channel\n");

	wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);

	return wilc_add_beacon(vif, settings->beacon_interval,
				   settings->dtim_period, &settings->beacon);
}

static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
			 struct cfg80211_beacon_data *beacon)
{
	struct wilc_vif *vif = netdev_priv(dev);

	return wilc_add_beacon(vif, 0, 0, beacon);
}

static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
{
	int ret;
	struct wilc_vif *vif = netdev_priv(dev);

	wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);

	ret = wilc_del_beacon(vif);

	if (ret)
		netdev_err(dev, "Host delete beacon fail\n");

	return ret;
}

static int add_station(struct wiphy *wiphy, struct net_device *dev,
		       const u8 *mac, struct station_parameters *params)
{
	int ret = 0;
	struct wilc_vif *vif = netdev_priv(dev);
	struct wilc_priv *priv = &vif->priv;

	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
		memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
		       ETH_ALEN);

		ret = wilc_add_station(vif, mac, params);
		if (ret)
			netdev_err(dev, "Host add station fail\n");
	}

	return ret;
}

static int del_station(struct wiphy *wiphy, struct net_device *dev,
		       struct station_del_parameters *params)
{
	const u8 *mac = params->mac;
	int ret = 0;
	struct wilc_vif *vif = netdev_priv(dev);
	struct wilc_priv *priv = &vif->priv;
	struct sta_info *info;

	if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
		return ret;

	info = &priv->assoc_stainfo;

	if (!mac)
		ret = wilc_del_allstation(vif, info->sta_associated_bss);

	ret = wilc_del_station(vif, mac);
	if (ret)
		netdev_err(dev, "Host delete station fail\n");
	return ret;
}

static int change_station(struct wiphy *wiphy, struct net_device *dev,
			  const u8 *mac, struct station_parameters *params)
{
	int ret = 0;
	struct wilc_vif *vif = netdev_priv(dev);

	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
		ret = wilc_edit_station(vif, mac, params);
		if (ret)
			netdev_err(dev, "Host edit station fail\n");
	}
	return ret;
}

static struct wilc_vif *wilc_get_vif_from_type(struct wilc *wl, int type)
{
	struct wilc_vif *vif;

	list_for_each_entry_rcu(vif, &wl->vif_list, list) {
		if (vif->iftype == type)
			return vif;
	}

	return NULL;
}

static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
					     const char *name,
					     unsigned char name_assign_type,
					     enum nl80211_iftype type,
					     struct vif_params *params)
{
	struct wilc *wl = wiphy_priv(wiphy);
	struct wilc_vif *vif;
	struct wireless_dev *wdev;
	int iftype;

	if (type == NL80211_IFTYPE_MONITOR) {
		struct net_device *ndev;
		int srcu_idx;

		srcu_idx = srcu_read_lock(&wl->srcu);
		vif = wilc_get_vif_from_type(wl, WILC_AP_MODE);
		if (!vif) {
			vif = wilc_get_vif_from_type(wl, WILC_GO_MODE);
			if (!vif) {
				srcu_read_unlock(&wl->srcu, srcu_idx);
				goto validate_interface;
			}
		}

		if (vif->monitor_flag) {
			srcu_read_unlock(&wl->srcu, srcu_idx);
			goto validate_interface;
		}

		ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
		if (ndev) {
			vif->monitor_flag = 1;
		} else {
			srcu_read_unlock(&wl->srcu, srcu_idx);
			return ERR_PTR(-EINVAL);
		}

		wdev = &vif->priv.wdev;
		srcu_read_unlock(&wl->srcu, srcu_idx);
		return wdev;
	}

validate_interface:
	mutex_lock(&wl->vif_mutex);
	if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
		pr_err("Reached maximum number of interface\n");
		mutex_unlock(&wl->vif_mutex);
		return ERR_PTR(-EINVAL);
	}
	mutex_unlock(&wl->vif_mutex);

	switch (type) {
	case NL80211_IFTYPE_STATION:
		iftype = WILC_STATION_MODE;
		break;
	case NL80211_IFTYPE_AP:
		iftype = WILC_AP_MODE;
		break;
	default:
		return ERR_PTR(-EOPNOTSUPP);
	}

	vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
	if (IS_ERR(vif))
		return ERR_CAST(vif);

	return &vif->priv.wdev;
}

static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
{
	struct wilc *wl = wiphy_priv(wiphy);
	struct wilc_vif *vif;

	if (wdev->iftype == NL80211_IFTYPE_AP ||
	    wdev->iftype == NL80211_IFTYPE_P2P_GO)
		wilc_wfi_deinit_mon_interface(wl, true);
	vif = netdev_priv(wdev->netdev);
	cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
	unregister_netdevice(vif->ndev);
	vif->monitor_flag = 0;

	wilc_set_operation_mode(vif, 0, 0, 0);
	mutex_lock(&wl->vif_mutex);
	list_del_rcu(&vif->list);
	wl->vif_num--;
	mutex_unlock(&wl->vif_mutex);
	synchronize_srcu(&wl->srcu);
	return 0;
}

static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
{
	struct wilc *wl = wiphy_priv(wiphy);

	if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
		wl->suspend_event = true;
	else
		wl->suspend_event = false;

	return 0;
}

static int wilc_resume(struct wiphy *wiphy)
{
	return 0;
}

static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
{
	struct wilc *wl = wiphy_priv(wiphy);
	struct wilc_vif *vif;
	int srcu_idx;

	srcu_idx = srcu_read_lock(&wl->srcu);
	vif = wilc_get_wl_to_vif(wl);
	if (IS_ERR(vif)) {
		srcu_read_unlock(&wl->srcu, srcu_idx);
		return;
	}

	netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
	srcu_read_unlock(&wl->srcu, srcu_idx);
}

static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
			enum nl80211_tx_power_setting type, int mbm)
{
	int ret;
	int srcu_idx;
	s32 tx_power = MBM_TO_DBM(mbm);
	struct wilc *wl = wiphy_priv(wiphy);
	struct wilc_vif *vif;

	if (!wl->initialized)
		return -EIO;

	srcu_idx = srcu_read_lock(&wl->srcu);
	vif = wilc_get_wl_to_vif(wl);
	if (IS_ERR(vif)) {
		srcu_read_unlock(&wl->srcu, srcu_idx);
		return -EINVAL;
	}

	netdev_info(vif->ndev, "Setting tx power %d\n", tx_power);
	if (tx_power < 0)
		tx_power = 0;
	else if (tx_power > 18)
		tx_power = 18;
	ret = wilc_set_tx_power(vif, tx_power);
	if (ret)
		netdev_err(vif->ndev, "Failed to set tx power\n");
	srcu_read_unlock(&wl->srcu, srcu_idx);

	return ret;
}

static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
			int *dbm)
{
	int ret;
	struct wilc_vif *vif = netdev_priv(wdev->netdev);
	struct wilc *wl = vif->wilc;

	/* If firmware is not started, return. */
	if (!wl->initialized)
		return -EIO;

	ret = wilc_get_tx_power(vif, (u8 *)dbm);
	if (ret)
		netdev_err(vif->ndev, "Failed to get tx power\n");

	return ret;
}

static const struct cfg80211_ops wilc_cfg80211_ops = {
	.set_monitor_channel = set_channel,
	.scan = scan,
	.connect = connect,
	.disconnect = disconnect,
	.add_key = add_key,
	.del_key = del_key,
	.get_key = get_key,
	.set_default_key = set_default_key,
	.add_virtual_intf = add_virtual_intf,
	.del_virtual_intf = del_virtual_intf,
	.change_virtual_intf = change_virtual_intf,

	.start_ap = start_ap,
	.change_beacon = change_beacon,
	.stop_ap = stop_ap,
	.add_station = add_station,
	.del_station = del_station,
	.change_station = change_station,
	.get_station = get_station,
	.dump_station = dump_station,
	.change_bss = change_bss,
	.set_wiphy_params = set_wiphy_params,

	.set_pmksa = set_pmksa,
	.del_pmksa = del_pmksa,
	.flush_pmksa = flush_pmksa,
	.remain_on_channel = remain_on_channel,
	.cancel_remain_on_channel = cancel_remain_on_channel,
	.mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
	.mgmt_tx = mgmt_tx,
	.mgmt_frame_register = wilc_mgmt_frame_register,
	.set_power_mgmt = set_power_mgmt,
	.set_cqm_rssi_config = set_cqm_rssi_config,

	.suspend = wilc_suspend,
	.resume = wilc_resume,
	.set_wakeup = wilc_set_wakeup,
	.set_tx_power = set_tx_power,
	.get_tx_power = get_tx_power,

};

static void wlan_init_locks(struct wilc *wl)
{
	mutex_init(&wl->hif_cs);
	mutex_init(&wl->rxq_cs);
	mutex_init(&wl->cfg_cmd_lock);
	mutex_init(&wl->vif_mutex);

	spin_lock_init(&wl->txq_spinlock);
	mutex_init(&wl->txq_add_to_head_cs);

	init_completion(&wl->txq_event);
	init_completion(&wl->cfg_event);
	init_completion(&wl->sync_event);
	init_completion(&wl->txq_thread_started);
	init_srcu_struct(&wl->srcu);
}

void wlan_deinit_locks(struct wilc *wilc)
{
	mutex_destroy(&wilc->hif_cs);
	mutex_destroy(&wilc->rxq_cs);
	mutex_destroy(&wilc->cfg_cmd_lock);
	mutex_destroy(&wilc->txq_add_to_head_cs);
	mutex_destroy(&wilc->vif_mutex);
	cleanup_srcu_struct(&wilc->srcu);
}

int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
		       const struct wilc_hif_func *ops)
{
	struct wilc *wl;
	struct wilc_vif *vif;
	int ret;

	wl = wilc_create_wiphy(dev);
	if (!wl)
		return -EINVAL;

	wlan_init_locks(wl);

	ret = wilc_wlan_cfg_init(wl);
	if (ret)
		goto free_wl;

	*wilc = wl;
	wl->io_type = io_type;
	wl->hif_func = ops;
	wl->chip_ps_state = WILC_CHIP_WAKEDUP;
	INIT_LIST_HEAD(&wl->txq_head.list);
	INIT_LIST_HEAD(&wl->rxq_head.list);
	INIT_LIST_HEAD(&wl->vif_list);

	wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
	if (!wl->hif_workqueue) {
		ret = -ENOMEM;
		goto free_cfg;
	}
	vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
				   NL80211_IFTYPE_STATION, false);
	if (IS_ERR(vif)) {
		ret = PTR_ERR(vif);
		goto free_hq;
	}

	return 0;

free_hq:
	destroy_workqueue(wl->hif_workqueue);

free_cfg:
	wilc_wlan_cfg_deinit(wl);

free_wl:
	wlan_deinit_locks(wl);
	wiphy_unregister(wl->wiphy);
	wiphy_free(wl->wiphy);
	return ret;
}
EXPORT_SYMBOL_GPL(wilc_cfg80211_init);

struct wilc *wilc_create_wiphy(struct device *dev)
{
	struct wiphy *wiphy;
	struct wilc *wl;
	int ret;

	wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
	if (!wiphy)
		return NULL;

	wl = wiphy_priv(wiphy);

	memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
	memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
	wl->band.bitrates = wl->bitrates;
	wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
	wl->band.channels = wl->channels;
	wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);

	wl->band.ht_cap.ht_supported = 1;
	wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
	wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
	wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
	wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;

	wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;

	wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
#ifdef CONFIG_PM
	wiphy->wowlan = &wowlan_support;
#endif
	wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
	wiphy->max_scan_ie_len = 1000;
	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
	memcpy(wl->cipher_suites, wilc_cipher_suites,
	       sizeof(wilc_cipher_suites));
	wiphy->cipher_suites = wl->cipher_suites;
	wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
	wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;

	wiphy->max_remain_on_channel_duration = 500;
	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
				BIT(NL80211_IFTYPE_AP) |
				BIT(NL80211_IFTYPE_MONITOR) |
				BIT(NL80211_IFTYPE_P2P_GO) |
				BIT(NL80211_IFTYPE_P2P_CLIENT);
	wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;

	set_wiphy_dev(wiphy, dev);
	wl->wiphy = wiphy;
	ret = wiphy_register(wiphy);
	if (ret) {
		wiphy_free(wiphy);
		return NULL;
	}
	return wl;
}

int wilc_init_host_int(struct net_device *net)
{
	int ret;
	struct wilc_vif *vif = netdev_priv(net);
	struct wilc_priv *priv = &vif->priv;

	priv->p2p_listen_state = false;

	mutex_init(&priv->scan_req_lock);
	ret = wilc_init(net, &priv->hif_drv);
	if (ret)
		netdev_err(net, "Error while initializing hostinterface\n");

	return ret;
}

void wilc_deinit_host_int(struct net_device *net)
{
	int ret;
	struct wilc_vif *vif = netdev_priv(net);
	struct wilc_priv *priv = &vif->priv;

	priv->p2p_listen_state = false;

	flush_workqueue(vif->wilc->hif_workqueue);
	mutex_destroy(&priv->scan_req_lock);
	ret = wilc_deinit(vif);

	if (ret)
		netdev_err(net, "Error while deinitializing host interface\n");
}

