cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cfg80211.c (46536B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
      4 * All rights reserved.
      5 */
      6
      7#include "cfg80211.h"
      8
      9#define GO_NEG_REQ			0x00
     10#define GO_NEG_RSP			0x01
     11#define GO_NEG_CONF			0x02
     12#define P2P_INV_REQ			0x03
     13#define P2P_INV_RSP			0x04
     14
     15#define WILC_INVALID_CHANNEL		0
     16
     17/* Operation at 2.4 GHz with channels 1-13 */
     18#define WILC_WLAN_OPERATING_CLASS_2_4GHZ		0x51
     19
     20static const struct ieee80211_txrx_stypes
     21	wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
     22	[NL80211_IFTYPE_STATION] = {
     23		.tx = 0xffff,
     24		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
     25			BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
     26	},
     27	[NL80211_IFTYPE_AP] = {
     28		.tx = 0xffff,
     29		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
     30			BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
     31			BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
     32			BIT(IEEE80211_STYPE_DISASSOC >> 4) |
     33			BIT(IEEE80211_STYPE_AUTH >> 4) |
     34			BIT(IEEE80211_STYPE_DEAUTH >> 4) |
     35			BIT(IEEE80211_STYPE_ACTION >> 4)
     36	},
     37	[NL80211_IFTYPE_P2P_CLIENT] = {
     38		.tx = 0xffff,
     39		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
     40			BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
     41			BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
     42			BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
     43			BIT(IEEE80211_STYPE_DISASSOC >> 4) |
     44			BIT(IEEE80211_STYPE_AUTH >> 4) |
     45			BIT(IEEE80211_STYPE_DEAUTH >> 4)
     46	}
     47};
     48
     49#ifdef CONFIG_PM
     50static const struct wiphy_wowlan_support wowlan_support = {
     51	.flags = WIPHY_WOWLAN_ANY
     52};
     53#endif
     54
     55struct wilc_p2p_mgmt_data {
     56	int size;
     57	u8 *buff;
     58};
     59
     60struct wilc_p2p_pub_act_frame {
     61	u8 category;
     62	u8 action;
     63	u8 oui[3];
     64	u8 oui_type;
     65	u8 oui_subtype;
     66	u8 dialog_token;
     67	u8 elem[];
     68} __packed;
     69
     70struct wilc_vendor_specific_ie {
     71	u8 tag_number;
     72	u8 tag_len;
     73	u8 oui[3];
     74	u8 oui_type;
     75	u8 attr[];
     76} __packed;
     77
     78struct wilc_attr_entry {
     79	u8  attr_type;
     80	__le16 attr_len;
     81	u8 val[];
     82} __packed;
     83
     84struct wilc_attr_oper_ch {
     85	u8 attr_type;
     86	__le16 attr_len;
     87	u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
     88	u8 op_class;
     89	u8 op_channel;
     90} __packed;
     91
     92struct wilc_attr_ch_list {
     93	u8 attr_type;
     94	__le16 attr_len;
     95	u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
     96	u8 elem[];
     97} __packed;
     98
     99struct wilc_ch_list_elem {
    100	u8 op_class;
    101	u8 no_of_channels;
    102	u8 ch_list[];
    103} __packed;
    104
    105static void cfg_scan_result(enum scan_event scan_event,
    106			    struct wilc_rcvd_net_info *info, void *user_void)
    107{
    108	struct wilc_priv *priv = user_void;
    109
    110	if (!priv->cfg_scanning)
    111		return;
    112
    113	if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
    114		s32 freq;
    115		struct ieee80211_channel *channel;
    116		struct cfg80211_bss *bss;
    117		struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
    118
    119		if (!wiphy || !info)
    120			return;
    121
    122		freq = ieee80211_channel_to_frequency((s32)info->ch,
    123						      NL80211_BAND_2GHZ);
    124		channel = ieee80211_get_channel(wiphy, freq);
    125		if (!channel)
    126			return;
    127
    128		bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt,
    129						info->frame_len,
    130						(s32)info->rssi * 100,
    131						GFP_KERNEL);
    132		cfg80211_put_bss(wiphy, bss);
    133	} else if (scan_event == SCAN_EVENT_DONE) {
    134		mutex_lock(&priv->scan_req_lock);
    135
    136		if (priv->scan_req) {
    137			struct cfg80211_scan_info info = {
    138				.aborted = false,
    139			};
    140
    141			cfg80211_scan_done(priv->scan_req, &info);
    142			priv->cfg_scanning = false;
    143			priv->scan_req = NULL;
    144		}
    145		mutex_unlock(&priv->scan_req_lock);
    146	} else if (scan_event == SCAN_EVENT_ABORTED) {
    147		mutex_lock(&priv->scan_req_lock);
    148
    149		if (priv->scan_req) {
    150			struct cfg80211_scan_info info = {
    151				.aborted = false,
    152			};
    153
    154			cfg80211_scan_done(priv->scan_req, &info);
    155			priv->cfg_scanning = false;
    156			priv->scan_req = NULL;
    157		}
    158		mutex_unlock(&priv->scan_req_lock);
    159	}
    160}
    161
    162static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
    163			       void *priv_data)
    164{
    165	struct wilc_priv *priv = priv_data;
    166	struct net_device *dev = priv->dev;
    167	struct wilc_vif *vif = netdev_priv(dev);
    168	struct wilc *wl = vif->wilc;
    169	struct host_if_drv *wfi_drv = priv->hif_drv;
    170	struct wilc_conn_info *conn_info = &wfi_drv->conn_info;
    171	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
    172
    173	vif->connecting = false;
    174
    175	if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
    176		u16 connect_status = conn_info->status;
    177
    178		if (mac_status == WILC_MAC_STATUS_DISCONNECTED &&
    179		    connect_status == WLAN_STATUS_SUCCESS) {
    180			connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
    181			wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
    182
    183			if (vif->iftype != WILC_CLIENT_MODE)
    184				wl->sta_ch = WILC_INVALID_CHANNEL;
    185
    186			netdev_err(dev, "Unspecified failure\n");
    187		}
    188
    189		if (connect_status == WLAN_STATUS_SUCCESS)
    190			memcpy(priv->associated_bss, conn_info->bssid,
    191			       ETH_ALEN);
    192
    193		cfg80211_ref_bss(wiphy, vif->bss);
    194		cfg80211_connect_bss(dev, conn_info->bssid, vif->bss,
    195				     conn_info->req_ies,
    196				     conn_info->req_ies_len,
    197				     conn_info->resp_ies,
    198				     conn_info->resp_ies_len,
    199				     connect_status, GFP_KERNEL,
    200				     NL80211_TIMEOUT_UNSPECIFIED);
    201
    202		vif->bss = NULL;
    203	} else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
    204		u16 reason = 0;
    205
    206		eth_zero_addr(priv->associated_bss);
    207		wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
    208
    209		if (vif->iftype != WILC_CLIENT_MODE) {
    210			wl->sta_ch = WILC_INVALID_CHANNEL;
    211		} else {
    212			if (wfi_drv->ifc_up)
    213				reason = 3;
    214			else
    215				reason = 1;
    216		}
    217
    218		cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
    219	}
    220}
    221
    222struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
    223{
    224	struct wilc_vif *vif;
    225
    226	vif = list_first_or_null_rcu(&wl->vif_list, typeof(*vif), list);
    227	if (!vif)
    228		return ERR_PTR(-EINVAL);
    229
    230	return vif;
    231}
    232
    233static int set_channel(struct wiphy *wiphy,
    234		       struct cfg80211_chan_def *chandef)
    235{
    236	struct wilc *wl = wiphy_priv(wiphy);
    237	struct wilc_vif *vif;
    238	u32 channelnum;
    239	int result;
    240	int srcu_idx;
    241
    242	srcu_idx = srcu_read_lock(&wl->srcu);
    243	vif = wilc_get_wl_to_vif(wl);
    244	if (IS_ERR(vif)) {
    245		srcu_read_unlock(&wl->srcu, srcu_idx);
    246		return PTR_ERR(vif);
    247	}
    248
    249	channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
    250
    251	wl->op_ch = channelnum;
    252	result = wilc_set_mac_chnl_num(vif, channelnum);
    253	if (result)
    254		netdev_err(vif->ndev, "Error in setting channel\n");
    255
    256	srcu_read_unlock(&wl->srcu, srcu_idx);
    257	return result;
    258}
    259
    260static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
    261{
    262	struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
    263	struct wilc_priv *priv = &vif->priv;
    264	u32 i;
    265	int ret = 0;
    266	u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
    267	u8 scan_type;
    268
    269	if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
    270		netdev_err(vif->ndev, "Requested scanned channels over\n");
    271		return -EINVAL;
    272	}
    273
    274	priv->scan_req = request;
    275	priv->cfg_scanning = true;
    276	for (i = 0; i < request->n_channels; i++) {
    277		u16 freq = request->channels[i]->center_freq;
    278
    279		scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
    280	}
    281
    282	if (request->n_ssids)
    283		scan_type = WILC_FW_ACTIVE_SCAN;
    284	else
    285		scan_type = WILC_FW_PASSIVE_SCAN;
    286
    287	ret = wilc_scan(vif, WILC_FW_USER_SCAN, scan_type, scan_ch_list,
    288			request->n_channels, cfg_scan_result, (void *)priv,
    289			request);
    290
    291	if (ret) {
    292		priv->scan_req = NULL;
    293		priv->cfg_scanning = false;
    294	}
    295
    296	return ret;
    297}
    298
    299static int connect(struct wiphy *wiphy, struct net_device *dev,
    300		   struct cfg80211_connect_params *sme)
    301{
    302	struct wilc_vif *vif = netdev_priv(dev);
    303	struct wilc_priv *priv = &vif->priv;
    304	struct host_if_drv *wfi_drv = priv->hif_drv;
    305	int ret;
    306	u32 i;
    307	u8 security = WILC_FW_SEC_NO;
    308	enum authtype auth_type = WILC_FW_AUTH_ANY;
    309	u32 cipher_group;
    310	struct cfg80211_bss *bss;
    311	void *join_params;
    312	u8 ch;
    313
    314	vif->connecting = true;
    315
    316	memset(priv->wep_key, 0, sizeof(priv->wep_key));
    317	memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
    318
    319	cipher_group = sme->crypto.cipher_group;
    320	if (cipher_group != 0) {
    321		if (cipher_group == WLAN_CIPHER_SUITE_WEP40) {
    322			security = WILC_FW_SEC_WEP;
    323
    324			priv->wep_key_len[sme->key_idx] = sme->key_len;
    325			memcpy(priv->wep_key[sme->key_idx], sme->key,
    326			       sme->key_len);
    327
    328			wilc_set_wep_default_keyid(vif, sme->key_idx);
    329			wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
    330						 sme->key_idx);
    331		} else if (cipher_group == WLAN_CIPHER_SUITE_WEP104) {
    332			security = WILC_FW_SEC_WEP_EXTENDED;
    333
    334			priv->wep_key_len[sme->key_idx] = sme->key_len;
    335			memcpy(priv->wep_key[sme->key_idx], sme->key,
    336			       sme->key_len);
    337
    338			wilc_set_wep_default_keyid(vif, sme->key_idx);
    339			wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
    340						 sme->key_idx);
    341		} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
    342			if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
    343				security = WILC_FW_SEC_WPA2_TKIP;
    344			else
    345				security = WILC_FW_SEC_WPA2_AES;
    346		} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
    347			if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
    348				security = WILC_FW_SEC_WPA_TKIP;
    349			else
    350				security = WILC_FW_SEC_WPA_AES;
    351		} else {
    352			ret = -ENOTSUPP;
    353			netdev_err(dev, "%s: Unsupported cipher\n",
    354				   __func__);
    355			goto out_error;
    356		}
    357	}
    358
    359	if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
    360	    (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
    361		for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
    362			u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];
    363
    364			if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
    365				security |= WILC_FW_TKIP;
    366			else
    367				security |= WILC_FW_AES;
    368		}
    369	}
    370
    371	switch (sme->auth_type) {
    372	case NL80211_AUTHTYPE_OPEN_SYSTEM:
    373		auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
    374		break;
    375
    376	case NL80211_AUTHTYPE_SHARED_KEY:
    377		auth_type = WILC_FW_AUTH_SHARED_KEY;
    378		break;
    379
    380	default:
    381		break;
    382	}
    383
    384	if (sme->crypto.n_akm_suites) {
    385		if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
    386			auth_type = WILC_FW_AUTH_IEEE8021;
    387	}
    388
    389	if (wfi_drv->usr_scan_req.scan_result) {
    390		netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
    391		ret = -EBUSY;
    392		goto out_error;
    393	}
    394
    395	bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid,
    396			       sme->ssid_len, IEEE80211_BSS_TYPE_ANY,
    397			       IEEE80211_PRIVACY(sme->privacy));
    398	if (!bss) {
    399		ret = -EINVAL;
    400		goto out_error;
    401	}
    402
    403	if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) {
    404		ret = -EALREADY;
    405		goto out_put_bss;
    406	}
    407
    408	join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
    409	if (!join_params) {
    410		netdev_err(dev, "%s: failed to construct join param\n",
    411			   __func__);
    412		ret = -EINVAL;
    413		goto out_put_bss;
    414	}
    415
    416	ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
    417	vif->wilc->op_ch = ch;
    418	if (vif->iftype != WILC_CLIENT_MODE)
    419		vif->wilc->sta_ch = ch;
    420
    421	wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE);
    422
    423	wfi_drv->conn_info.security = security;
    424	wfi_drv->conn_info.auth_type = auth_type;
    425	wfi_drv->conn_info.ch = ch;
    426	wfi_drv->conn_info.conn_result = cfg_connect_result;
    427	wfi_drv->conn_info.arg = priv;
    428	wfi_drv->conn_info.param = join_params;
    429
    430	ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
    431	if (ret) {
    432		netdev_err(dev, "wilc_set_join_req(): Error\n");
    433		ret = -ENOENT;
    434		if (vif->iftype != WILC_CLIENT_MODE)
    435			vif->wilc->sta_ch = WILC_INVALID_CHANNEL;
    436		wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE);
    437		wfi_drv->conn_info.conn_result = NULL;
    438		kfree(join_params);
    439		goto out_put_bss;
    440	}
    441	kfree(join_params);
    442	vif->bss = bss;
    443	cfg80211_put_bss(wiphy, bss);
    444	return 0;
    445
    446out_put_bss:
    447	cfg80211_put_bss(wiphy, bss);
    448
    449out_error:
    450	vif->connecting = false;
    451	return ret;
    452}
    453
    454static int disconnect(struct wiphy *wiphy, struct net_device *dev,
    455		      u16 reason_code)
    456{
    457	struct wilc_vif *vif = netdev_priv(dev);
    458	struct wilc_priv *priv = &vif->priv;
    459	struct wilc *wilc = vif->wilc;
    460	int ret;
    461
    462	vif->connecting = false;
    463
    464	if (!wilc)
    465		return -EIO;
    466
    467	if (wilc->close) {
    468		/* already disconnected done */
    469		cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
    470		return 0;
    471	}
    472
    473	if (vif->iftype != WILC_CLIENT_MODE)
    474		wilc->sta_ch = WILC_INVALID_CHANNEL;
    475	wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
    476
    477	priv->hif_drv->p2p_timeout = 0;
    478
    479	ret = wilc_disconnect(vif);
    480	if (ret != 0) {
    481		netdev_err(priv->dev, "Error in disconnecting\n");
    482		ret = -EINVAL;
    483	}
    484
    485	vif->bss = NULL;
    486
    487	return ret;
    488}
    489
    490static inline void wilc_wfi_cfg_copy_wep_info(struct wilc_priv *priv,
    491					      u8 key_index,
    492					      struct key_params *params)
    493{
    494	priv->wep_key_len[key_index] = params->key_len;
    495	memcpy(priv->wep_key[key_index], params->key, params->key_len);
    496}
    497
    498static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
    499{
    500	if (!priv->wilc_gtk[idx]) {
    501		priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
    502					      GFP_KERNEL);
    503		if (!priv->wilc_gtk[idx])
    504			return -ENOMEM;
    505	}
    506
    507	if (!priv->wilc_ptk[idx]) {
    508		priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
    509					      GFP_KERNEL);
    510		if (!priv->wilc_ptk[idx])
    511			return -ENOMEM;
    512	}
    513
    514	return 0;
    515}
    516
    517static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
    518				      struct key_params *params)
    519{
    520	kfree(key_info->key);
    521
    522	key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
    523	if (!key_info->key)
    524		return -ENOMEM;
    525
    526	kfree(key_info->seq);
    527
    528	if (params->seq_len > 0) {
    529		key_info->seq = kmemdup(params->seq, params->seq_len,
    530					GFP_KERNEL);
    531		if (!key_info->seq)
    532			return -ENOMEM;
    533	}
    534
    535	key_info->cipher = params->cipher;
    536	key_info->key_len = params->key_len;
    537	key_info->seq_len = params->seq_len;
    538
    539	return 0;
    540}
    541
    542static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
    543		   bool pairwise, const u8 *mac_addr, struct key_params *params)
    544
    545{
    546	int ret = 0, keylen = params->key_len;
    547	const u8 *rx_mic = NULL;
    548	const u8 *tx_mic = NULL;
    549	u8 mode = WILC_FW_SEC_NO;
    550	u8 op_mode;
    551	struct wilc_vif *vif = netdev_priv(netdev);
    552	struct wilc_priv *priv = &vif->priv;
    553
    554	switch (params->cipher) {
    555	case WLAN_CIPHER_SUITE_WEP40:
    556	case WLAN_CIPHER_SUITE_WEP104:
    557		if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
    558			wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
    559
    560			if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
    561				mode = WILC_FW_SEC_WEP;
    562			else
    563				mode = WILC_FW_SEC_WEP_EXTENDED;
    564
    565			ret = wilc_add_wep_key_bss_ap(vif, params->key,
    566						      params->key_len,
    567						      key_index, mode,
    568						      WILC_FW_AUTH_OPEN_SYSTEM);
    569			break;
    570		}
    571		if (memcmp(params->key, priv->wep_key[key_index],
    572			   params->key_len)) {
    573			wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
    574
    575			ret = wilc_add_wep_key_bss_sta(vif, params->key,
    576						       params->key_len,
    577						       key_index);
    578		}
    579
    580		break;
    581
    582	case WLAN_CIPHER_SUITE_TKIP:
    583	case WLAN_CIPHER_SUITE_CCMP:
    584		if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
    585		    priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
    586			struct wilc_wfi_key *key;
    587
    588			ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
    589			if (ret)
    590				return -ENOMEM;
    591
    592			if (params->key_len > 16 &&
    593			    params->cipher == WLAN_CIPHER_SUITE_TKIP) {
    594				tx_mic = params->key + 24;
    595				rx_mic = params->key + 16;
    596				keylen = params->key_len - 16;
    597			}
    598
    599			if (!pairwise) {
    600				if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
    601					mode = WILC_FW_SEC_WPA_TKIP;
    602				else
    603					mode = WILC_FW_SEC_WPA2_AES;
    604
    605				priv->wilc_groupkey = mode;
    606
    607				key = priv->wilc_gtk[key_index];
    608			} else {
    609				if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
    610					mode = WILC_FW_SEC_WPA_TKIP;
    611				else
    612					mode = priv->wilc_groupkey | WILC_FW_AES;
    613
    614				key = priv->wilc_ptk[key_index];
    615			}
    616			ret = wilc_wfi_cfg_copy_wpa_info(key, params);
    617			if (ret)
    618				return -ENOMEM;
    619
    620			op_mode = WILC_AP_MODE;
    621		} else {
    622			if (params->key_len > 16 &&
    623			    params->cipher == WLAN_CIPHER_SUITE_TKIP) {
    624				rx_mic = params->key + 24;
    625				tx_mic = params->key + 16;
    626				keylen = params->key_len - 16;
    627			}
    628
    629			op_mode = WILC_STATION_MODE;
    630		}
    631
    632		if (!pairwise)
    633			ret = wilc_add_rx_gtk(vif, params->key, keylen,
    634					      key_index, params->seq_len,
    635					      params->seq, rx_mic, tx_mic,
    636					      op_mode, mode);
    637		else
    638			ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
    639					   rx_mic, tx_mic, op_mode, mode,
    640					   key_index);
    641
    642		break;
    643
    644	default:
    645		netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
    646		ret = -ENOTSUPP;
    647	}
    648
    649	return ret;
    650}
    651
    652static int del_key(struct wiphy *wiphy, struct net_device *netdev,
    653		   u8 key_index,
    654		   bool pairwise,
    655		   const u8 *mac_addr)
    656{
    657	struct wilc_vif *vif = netdev_priv(netdev);
    658	struct wilc_priv *priv = &vif->priv;
    659
    660	if (priv->wilc_gtk[key_index]) {
    661		kfree(priv->wilc_gtk[key_index]->key);
    662		priv->wilc_gtk[key_index]->key = NULL;
    663		kfree(priv->wilc_gtk[key_index]->seq);
    664		priv->wilc_gtk[key_index]->seq = NULL;
    665
    666		kfree(priv->wilc_gtk[key_index]);
    667		priv->wilc_gtk[key_index] = NULL;
    668	}
    669
    670	if (priv->wilc_ptk[key_index]) {
    671		kfree(priv->wilc_ptk[key_index]->key);
    672		priv->wilc_ptk[key_index]->key = NULL;
    673		kfree(priv->wilc_ptk[key_index]->seq);
    674		priv->wilc_ptk[key_index]->seq = NULL;
    675		kfree(priv->wilc_ptk[key_index]);
    676		priv->wilc_ptk[key_index] = NULL;
    677	}
    678
    679	if (key_index <= 3 && priv->wep_key_len[key_index]) {
    680		memset(priv->wep_key[key_index], 0,
    681		       priv->wep_key_len[key_index]);
    682		priv->wep_key_len[key_index] = 0;
    683		wilc_remove_wep_key(vif, key_index);
    684	}
    685
    686	return 0;
    687}
    688
    689static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
    690		   bool pairwise, const u8 *mac_addr, void *cookie,
    691		   void (*callback)(void *cookie, struct key_params *))
    692{
    693	struct wilc_vif *vif = netdev_priv(netdev);
    694	struct wilc_priv *priv = &vif->priv;
    695	struct  key_params key_params;
    696
    697	if (!pairwise) {
    698		key_params.key = priv->wilc_gtk[key_index]->key;
    699		key_params.cipher = priv->wilc_gtk[key_index]->cipher;
    700		key_params.key_len = priv->wilc_gtk[key_index]->key_len;
    701		key_params.seq = priv->wilc_gtk[key_index]->seq;
    702		key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
    703	} else {
    704		key_params.key = priv->wilc_ptk[key_index]->key;
    705		key_params.cipher = priv->wilc_ptk[key_index]->cipher;
    706		key_params.key_len = priv->wilc_ptk[key_index]->key_len;
    707		key_params.seq = priv->wilc_ptk[key_index]->seq;
    708		key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
    709	}
    710
    711	callback(cookie, &key_params);
    712
    713	return 0;
    714}
    715
    716static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
    717			   u8 key_index, bool unicast, bool multicast)
    718{
    719	struct wilc_vif *vif = netdev_priv(netdev);
    720
    721	wilc_set_wep_default_keyid(vif, key_index);
    722
    723	return 0;
    724}
    725
    726static int get_station(struct wiphy *wiphy, struct net_device *dev,
    727		       const u8 *mac, struct station_info *sinfo)
    728{
    729	struct wilc_vif *vif = netdev_priv(dev);
    730	struct wilc_priv *priv = &vif->priv;
    731	struct wilc *wilc = vif->wilc;
    732	u32 i = 0;
    733	u32 associatedsta = ~0;
    734	u32 inactive_time = 0;
    735
    736	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
    737		for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
    738			if (!(memcmp(mac,
    739				     priv->assoc_stainfo.sta_associated_bss[i],
    740				     ETH_ALEN))) {
    741				associatedsta = i;
    742				break;
    743			}
    744		}
    745
    746		if (associatedsta == ~0) {
    747			netdev_err(dev, "sta required is not associated\n");
    748			return -ENOENT;
    749		}
    750
    751		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
    752
    753		wilc_get_inactive_time(vif, mac, &inactive_time);
    754		sinfo->inactive_time = 1000 * inactive_time;
    755	} else if (vif->iftype == WILC_STATION_MODE) {
    756		struct rf_info stats;
    757
    758		if (!wilc->initialized)
    759			return -EBUSY;
    760
    761		wilc_get_statistics(vif, &stats);
    762
    763		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
    764				 BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
    765				 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
    766				 BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
    767				 BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
    768
    769		sinfo->signal = stats.rssi;
    770		sinfo->rx_packets = stats.rx_cnt;
    771		sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
    772		sinfo->tx_failed = stats.tx_fail_cnt;
    773		sinfo->txrate.legacy = stats.link_speed * 10;
    774
    775		if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
    776		    stats.link_speed != DEFAULT_LINK_SPEED)
    777			wilc_enable_tcp_ack_filter(vif, true);
    778		else if (stats.link_speed != DEFAULT_LINK_SPEED)
    779			wilc_enable_tcp_ack_filter(vif, false);
    780	}
    781	return 0;
    782}
    783
    784static int change_bss(struct wiphy *wiphy, struct net_device *dev,
    785		      struct bss_parameters *params)
    786{
    787	return 0;
    788}
    789
    790static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
    791{
    792	int ret = -EINVAL;
    793	struct cfg_param_attr cfg_param_val;
    794	struct wilc *wl = wiphy_priv(wiphy);
    795	struct wilc_vif *vif;
    796	struct wilc_priv *priv;
    797	int srcu_idx;
    798
    799	srcu_idx = srcu_read_lock(&wl->srcu);
    800	vif = wilc_get_wl_to_vif(wl);
    801	if (IS_ERR(vif))
    802		goto out;
    803
    804	priv = &vif->priv;
    805	cfg_param_val.flag = 0;
    806
    807	if (changed & WIPHY_PARAM_RETRY_SHORT) {
    808		netdev_dbg(vif->ndev,
    809			   "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
    810			   wiphy->retry_short);
    811		cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
    812		cfg_param_val.short_retry_limit = wiphy->retry_short;
    813	}
    814	if (changed & WIPHY_PARAM_RETRY_LONG) {
    815		netdev_dbg(vif->ndev,
    816			   "Setting WIPHY_PARAM_RETRY_LONG %d\n",
    817			   wiphy->retry_long);
    818		cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
    819		cfg_param_val.long_retry_limit = wiphy->retry_long;
    820	}
    821	if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
    822		if (wiphy->frag_threshold > 255 &&
    823		    wiphy->frag_threshold < 7937) {
    824			netdev_dbg(vif->ndev,
    825				   "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
    826				   wiphy->frag_threshold);
    827			cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
    828			cfg_param_val.frag_threshold = wiphy->frag_threshold;
    829		} else {
    830			netdev_err(vif->ndev,
    831				   "Fragmentation threshold out of range\n");
    832			goto out;
    833		}
    834	}
    835
    836	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
    837		if (wiphy->rts_threshold > 255) {
    838			netdev_dbg(vif->ndev,
    839				   "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
    840				   wiphy->rts_threshold);
    841			cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
    842			cfg_param_val.rts_threshold = wiphy->rts_threshold;
    843		} else {
    844			netdev_err(vif->ndev, "RTS threshold out of range\n");
    845			goto out;
    846		}
    847	}
    848
    849	ret = wilc_hif_set_cfg(vif, &cfg_param_val);
    850	if (ret)
    851		netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
    852
    853out:
    854	srcu_read_unlock(&wl->srcu, srcu_idx);
    855	return ret;
    856}
    857
    858static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
    859		     struct cfg80211_pmksa *pmksa)
    860{
    861	struct wilc_vif *vif = netdev_priv(netdev);
    862	struct wilc_priv *priv = &vif->priv;
    863	u32 i;
    864	int ret = 0;
    865	u8 flag = 0;
    866
    867	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
    868		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
    869			    ETH_ALEN)) {
    870			flag = PMKID_FOUND;
    871			break;
    872		}
    873	}
    874	if (i < WILC_MAX_NUM_PMKIDS) {
    875		memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
    876		       ETH_ALEN);
    877		memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
    878		       WLAN_PMKID_LEN);
    879		if (!(flag == PMKID_FOUND))
    880			priv->pmkid_list.numpmkid++;
    881	} else {
    882		netdev_err(netdev, "Invalid PMKID index\n");
    883		ret = -EINVAL;
    884	}
    885
    886	if (!ret)
    887		ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
    888
    889	return ret;
    890}
    891
    892static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
    893		     struct cfg80211_pmksa *pmksa)
    894{
    895	u32 i;
    896	struct wilc_vif *vif = netdev_priv(netdev);
    897	struct wilc_priv *priv = &vif->priv;
    898
    899	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
    900		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
    901			    ETH_ALEN)) {
    902			memset(&priv->pmkid_list.pmkidlist[i], 0,
    903			       sizeof(struct wilc_pmkid));
    904			break;
    905		}
    906	}
    907
    908	if (i == priv->pmkid_list.numpmkid)
    909		return -EINVAL;
    910
    911	for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
    912		memcpy(priv->pmkid_list.pmkidlist[i].bssid,
    913		       priv->pmkid_list.pmkidlist[i + 1].bssid,
    914		       ETH_ALEN);
    915		memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
    916		       priv->pmkid_list.pmkidlist[i + 1].pmkid,
    917		       WLAN_PMKID_LEN);
    918	}
    919	priv->pmkid_list.numpmkid--;
    920
    921	return 0;
    922}
    923
    924static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
    925{
    926	struct wilc_vif *vif = netdev_priv(netdev);
    927
    928	memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
    929
    930	return 0;
    931}
    932
    933static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
    934{
    935	struct wilc_attr_entry *e;
    936	struct wilc_attr_ch_list *ch_list;
    937	struct wilc_attr_oper_ch *op_ch;
    938	u32 index = 0;
    939	u8 ch_list_idx = 0;
    940	u8 op_ch_idx = 0;
    941
    942	if (sta_ch == WILC_INVALID_CHANNEL)
    943		return;
    944
    945	while (index + sizeof(*e) <= len) {
    946		e = (struct wilc_attr_entry *)&buf[index];
    947		if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
    948			ch_list_idx = index;
    949		else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
    950			op_ch_idx = index;
    951		if (ch_list_idx && op_ch_idx)
    952			break;
    953		index += le16_to_cpu(e->attr_len) + sizeof(*e);
    954	}
    955
    956	if (ch_list_idx) {
    957		u16 attr_size;
    958		struct wilc_ch_list_elem *e;
    959		int i;
    960
    961		ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
    962		attr_size = le16_to_cpu(ch_list->attr_len);
    963		for (i = 0; i < attr_size;) {
    964			e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
    965			if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
    966				memset(e->ch_list, sta_ch, e->no_of_channels);
    967				break;
    968			}
    969			i += e->no_of_channels;
    970		}
    971	}
    972
    973	if (op_ch_idx) {
    974		op_ch = (struct wilc_attr_oper_ch *)&buf[op_ch_idx];
    975		op_ch->op_class = WILC_WLAN_OPERATING_CLASS_2_4GHZ;
    976		op_ch->op_channel = sta_ch;
    977	}
    978}
    979
    980void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
    981{
    982	struct wilc *wl = vif->wilc;
    983	struct wilc_priv *priv = &vif->priv;
    984	struct host_if_drv *wfi_drv = priv->hif_drv;
    985	struct ieee80211_mgmt *mgmt;
    986	struct wilc_vendor_specific_ie *p;
    987	struct wilc_p2p_pub_act_frame *d;
    988	int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
    989	const u8 *vendor_ie;
    990	u32 header, pkt_offset;
    991	s32 freq;
    992
    993	header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
    994	pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
    995
    996	if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
    997		bool ack = false;
    998		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buff;
    999
   1000		if (ieee80211_is_probe_resp(hdr->frame_control) ||
   1001		    pkt_offset & IS_MGMT_STATUS_SUCCES)
   1002			ack = true;
   1003
   1004		cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
   1005					size, ack, GFP_KERNEL);
   1006		return;
   1007	}
   1008
   1009	freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
   1010
   1011	mgmt = (struct ieee80211_mgmt *)buff;
   1012	if (!ieee80211_is_action(mgmt->frame_control))
   1013		goto out_rx_mgmt;
   1014
   1015	if (priv->cfg_scanning &&
   1016	    time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
   1017		netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
   1018		return;
   1019	}
   1020
   1021	if (!ieee80211_is_public_action((struct ieee80211_hdr *)buff, size))
   1022		goto out_rx_mgmt;
   1023
   1024	d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
   1025	if (d->oui_subtype != GO_NEG_REQ && d->oui_subtype != GO_NEG_RSP &&
   1026	    d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
   1027		goto out_rx_mgmt;
   1028
   1029	vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
   1030					    buff + ie_offset, size - ie_offset);
   1031	if (!vendor_ie)
   1032		goto out_rx_mgmt;
   1033
   1034	p = (struct wilc_vendor_specific_ie *)vendor_ie;
   1035	wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
   1036
   1037out_rx_mgmt:
   1038	cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
   1039}
   1040
   1041static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
   1042{
   1043	struct wilc_p2p_mgmt_data *pv_data = priv;
   1044
   1045	kfree(pv_data->buff);
   1046	kfree(pv_data);
   1047}
   1048
   1049static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
   1050{
   1051	struct wilc_vif *vif = data;
   1052	struct wilc_priv *priv = &vif->priv;
   1053	struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
   1054
   1055	if (cookie != params->listen_cookie)
   1056		return;
   1057
   1058	priv->p2p_listen_state = false;
   1059
   1060	cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
   1061					   params->listen_ch, GFP_KERNEL);
   1062}
   1063
   1064static int remain_on_channel(struct wiphy *wiphy,
   1065			     struct wireless_dev *wdev,
   1066			     struct ieee80211_channel *chan,
   1067			     unsigned int duration, u64 *cookie)
   1068{
   1069	int ret = 0;
   1070	struct wilc_vif *vif = netdev_priv(wdev->netdev);
   1071	struct wilc_priv *priv = &vif->priv;
   1072	u64 id;
   1073
   1074	if (wdev->iftype == NL80211_IFTYPE_AP) {
   1075		netdev_dbg(vif->ndev, "Required while in AP mode\n");
   1076		return ret;
   1077	}
   1078
   1079	id = ++priv->inc_roc_cookie;
   1080	if (id == 0)
   1081		id = ++priv->inc_roc_cookie;
   1082
   1083	ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
   1084				     wilc_wfi_remain_on_channel_expired,
   1085				     (void *)vif);
   1086	if (ret)
   1087		return ret;
   1088
   1089	vif->wilc->op_ch = chan->hw_value;
   1090
   1091	priv->remain_on_ch_params.listen_ch = chan;
   1092	priv->remain_on_ch_params.listen_cookie = id;
   1093	*cookie = id;
   1094	priv->p2p_listen_state = true;
   1095	priv->remain_on_ch_params.listen_duration = duration;
   1096
   1097	cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
   1098	mod_timer(&vif->hif_drv->remain_on_ch_timer,
   1099		  jiffies + msecs_to_jiffies(duration + 1000));
   1100
   1101	return ret;
   1102}
   1103
   1104static int cancel_remain_on_channel(struct wiphy *wiphy,
   1105				    struct wireless_dev *wdev,
   1106				    u64 cookie)
   1107{
   1108	struct wilc_vif *vif = netdev_priv(wdev->netdev);
   1109	struct wilc_priv *priv = &vif->priv;
   1110
   1111	if (cookie != priv->remain_on_ch_params.listen_cookie)
   1112		return -ENOENT;
   1113
   1114	return wilc_listen_state_expired(vif, cookie);
   1115}
   1116
   1117static int mgmt_tx(struct wiphy *wiphy,
   1118		   struct wireless_dev *wdev,
   1119		   struct cfg80211_mgmt_tx_params *params,
   1120		   u64 *cookie)
   1121{
   1122	struct ieee80211_channel *chan = params->chan;
   1123	unsigned int wait = params->wait;
   1124	const u8 *buf = params->buf;
   1125	size_t len = params->len;
   1126	const struct ieee80211_mgmt *mgmt;
   1127	struct wilc_p2p_mgmt_data *mgmt_tx;
   1128	struct wilc_vif *vif = netdev_priv(wdev->netdev);
   1129	struct wilc_priv *priv = &vif->priv;
   1130	struct host_if_drv *wfi_drv = priv->hif_drv;
   1131	struct wilc_vendor_specific_ie *p;
   1132	struct wilc_p2p_pub_act_frame *d;
   1133	int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
   1134	const u8 *vendor_ie;
   1135	int ret = 0;
   1136
   1137	*cookie = prandom_u32();
   1138	priv->tx_cookie = *cookie;
   1139	mgmt = (const struct ieee80211_mgmt *)buf;
   1140
   1141	if (!ieee80211_is_mgmt(mgmt->frame_control))
   1142		goto out;
   1143
   1144	mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
   1145	if (!mgmt_tx) {
   1146		ret = -ENOMEM;
   1147		goto out;
   1148	}
   1149
   1150	mgmt_tx->buff = kmemdup(buf, len, GFP_KERNEL);
   1151	if (!mgmt_tx->buff) {
   1152		ret = -ENOMEM;
   1153		kfree(mgmt_tx);
   1154		goto out;
   1155	}
   1156
   1157	mgmt_tx->size = len;
   1158
   1159	if (ieee80211_is_probe_resp(mgmt->frame_control)) {
   1160		wilc_set_mac_chnl_num(vif, chan->hw_value);
   1161		vif->wilc->op_ch = chan->hw_value;
   1162		goto out_txq_add_pkt;
   1163	}
   1164
   1165	if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len))
   1166		goto out_set_timeout;
   1167
   1168	d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
   1169	if (d->oui_type != WLAN_OUI_TYPE_WFA_P2P ||
   1170	    d->oui_subtype != GO_NEG_CONF) {
   1171		wilc_set_mac_chnl_num(vif, chan->hw_value);
   1172		vif->wilc->op_ch = chan->hw_value;
   1173	}
   1174
   1175	if (d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
   1176		goto out_set_timeout;
   1177
   1178	vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
   1179					    mgmt_tx->buff + ie_offset,
   1180					    len - ie_offset);
   1181	if (!vendor_ie)
   1182		goto out_set_timeout;
   1183
   1184	p = (struct wilc_vendor_specific_ie *)vendor_ie;
   1185	wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
   1186
   1187out_set_timeout:
   1188	wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
   1189
   1190out_txq_add_pkt:
   1191
   1192	wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
   1193				   mgmt_tx->buff, mgmt_tx->size,
   1194				   wilc_wfi_mgmt_tx_complete);
   1195
   1196out:
   1197
   1198	return ret;
   1199}
   1200
   1201static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
   1202			       struct wireless_dev *wdev,
   1203			       u64 cookie)
   1204{
   1205	struct wilc_vif *vif = netdev_priv(wdev->netdev);
   1206	struct wilc_priv *priv = &vif->priv;
   1207	struct host_if_drv *wfi_drv = priv->hif_drv;
   1208
   1209	wfi_drv->p2p_timeout = jiffies;
   1210
   1211	if (!priv->p2p_listen_state) {
   1212		struct wilc_wfi_p2p_listen_params *params;
   1213
   1214		params = &priv->remain_on_ch_params;
   1215
   1216		cfg80211_remain_on_channel_expired(wdev,
   1217						   params->listen_cookie,
   1218						   params->listen_ch,
   1219						   GFP_KERNEL);
   1220	}
   1221
   1222	return 0;
   1223}
   1224
   1225void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
   1226					  struct wireless_dev *wdev,
   1227					  struct mgmt_frame_regs *upd)
   1228{
   1229	struct wilc *wl = wiphy_priv(wiphy);
   1230	struct wilc_vif *vif = netdev_priv(wdev->netdev);
   1231	u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
   1232	u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4);
   1233
   1234	if (wl->initialized) {
   1235		bool prev = vif->mgmt_reg_stypes & presp_bit;
   1236		bool now = upd->interface_stypes & presp_bit;
   1237
   1238		if (now != prev)
   1239			wilc_frame_register(vif, IEEE80211_STYPE_PROBE_REQ, now);
   1240
   1241		prev = vif->mgmt_reg_stypes & action_bit;
   1242		now = upd->interface_stypes & action_bit;
   1243
   1244		if (now != prev)
   1245			wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now);
   1246	}
   1247
   1248	vif->mgmt_reg_stypes =
   1249		upd->interface_stypes & (presp_bit | action_bit);
   1250}
   1251
   1252static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
   1253			       s32 rssi_thold, u32 rssi_hyst)
   1254{
   1255	return 0;
   1256}
   1257
   1258static int dump_station(struct wiphy *wiphy, struct net_device *dev,
   1259			int idx, u8 *mac, struct station_info *sinfo)
   1260{
   1261	struct wilc_vif *vif = netdev_priv(dev);
   1262	int ret;
   1263
   1264	if (idx != 0)
   1265		return -ENOENT;
   1266
   1267	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
   1268
   1269	ret = wilc_get_rssi(vif, &sinfo->signal);
   1270	if (ret)
   1271		return ret;
   1272
   1273	memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
   1274	return 0;
   1275}
   1276
   1277static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
   1278			  bool enabled, int timeout)
   1279{
   1280	struct wilc_vif *vif = netdev_priv(dev);
   1281	struct wilc_priv *priv = &vif->priv;
   1282
   1283	if (!priv->hif_drv)
   1284		return -EIO;
   1285
   1286	wilc_set_power_mgmt(vif, enabled, timeout);
   1287
   1288	return 0;
   1289}
   1290
   1291static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
   1292			       enum nl80211_iftype type,
   1293			       struct vif_params *params)
   1294{
   1295	struct wilc *wl = wiphy_priv(wiphy);
   1296	struct wilc_vif *vif = netdev_priv(dev);
   1297	struct wilc_priv *priv = &vif->priv;
   1298
   1299	switch (type) {
   1300	case NL80211_IFTYPE_STATION:
   1301		vif->connecting = false;
   1302		dev->ieee80211_ptr->iftype = type;
   1303		priv->wdev.iftype = type;
   1304		vif->monitor_flag = 0;
   1305		if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
   1306			wilc_wfi_deinit_mon_interface(wl, true);
   1307		vif->iftype = WILC_STATION_MODE;
   1308
   1309		if (wl->initialized)
   1310			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
   1311						WILC_STATION_MODE, vif->idx);
   1312
   1313		memset(priv->assoc_stainfo.sta_associated_bss, 0,
   1314		       WILC_MAX_NUM_STA * ETH_ALEN);
   1315		break;
   1316
   1317	case NL80211_IFTYPE_P2P_CLIENT:
   1318		vif->connecting = false;
   1319		dev->ieee80211_ptr->iftype = type;
   1320		priv->wdev.iftype = type;
   1321		vif->monitor_flag = 0;
   1322		vif->iftype = WILC_CLIENT_MODE;
   1323
   1324		if (wl->initialized)
   1325			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
   1326						WILC_STATION_MODE, vif->idx);
   1327		break;
   1328
   1329	case NL80211_IFTYPE_AP:
   1330		dev->ieee80211_ptr->iftype = type;
   1331		priv->wdev.iftype = type;
   1332		vif->iftype = WILC_AP_MODE;
   1333
   1334		if (wl->initialized)
   1335			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
   1336						WILC_AP_MODE, vif->idx);
   1337		break;
   1338
   1339	case NL80211_IFTYPE_P2P_GO:
   1340		dev->ieee80211_ptr->iftype = type;
   1341		priv->wdev.iftype = type;
   1342		vif->iftype = WILC_GO_MODE;
   1343
   1344		if (wl->initialized)
   1345			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
   1346						WILC_AP_MODE, vif->idx);
   1347		break;
   1348
   1349	default:
   1350		netdev_err(dev, "Unknown interface type= %d\n", type);
   1351		return -EINVAL;
   1352	}
   1353
   1354	return 0;
   1355}
   1356
   1357static int start_ap(struct wiphy *wiphy, struct net_device *dev,
   1358		    struct cfg80211_ap_settings *settings)
   1359{
   1360	struct wilc_vif *vif = netdev_priv(dev);
   1361	int ret;
   1362
   1363	ret = set_channel(wiphy, &settings->chandef);
   1364	if (ret != 0)
   1365		netdev_err(dev, "Error in setting channel\n");
   1366
   1367	wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
   1368
   1369	return wilc_add_beacon(vif, settings->beacon_interval,
   1370				   settings->dtim_period, &settings->beacon);
   1371}
   1372
   1373static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
   1374			 struct cfg80211_beacon_data *beacon)
   1375{
   1376	struct wilc_vif *vif = netdev_priv(dev);
   1377
   1378	return wilc_add_beacon(vif, 0, 0, beacon);
   1379}
   1380
   1381static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
   1382{
   1383	int ret;
   1384	struct wilc_vif *vif = netdev_priv(dev);
   1385
   1386	wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
   1387
   1388	ret = wilc_del_beacon(vif);
   1389
   1390	if (ret)
   1391		netdev_err(dev, "Host delete beacon fail\n");
   1392
   1393	return ret;
   1394}
   1395
   1396static int add_station(struct wiphy *wiphy, struct net_device *dev,
   1397		       const u8 *mac, struct station_parameters *params)
   1398{
   1399	int ret = 0;
   1400	struct wilc_vif *vif = netdev_priv(dev);
   1401	struct wilc_priv *priv = &vif->priv;
   1402
   1403	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
   1404		memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
   1405		       ETH_ALEN);
   1406
   1407		ret = wilc_add_station(vif, mac, params);
   1408		if (ret)
   1409			netdev_err(dev, "Host add station fail\n");
   1410	}
   1411
   1412	return ret;
   1413}
   1414
   1415static int del_station(struct wiphy *wiphy, struct net_device *dev,
   1416		       struct station_del_parameters *params)
   1417{
   1418	const u8 *mac = params->mac;
   1419	int ret = 0;
   1420	struct wilc_vif *vif = netdev_priv(dev);
   1421	struct wilc_priv *priv = &vif->priv;
   1422	struct sta_info *info;
   1423
   1424	if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
   1425		return ret;
   1426
   1427	info = &priv->assoc_stainfo;
   1428
   1429	if (!mac)
   1430		ret = wilc_del_allstation(vif, info->sta_associated_bss);
   1431
   1432	ret = wilc_del_station(vif, mac);
   1433	if (ret)
   1434		netdev_err(dev, "Host delete station fail\n");
   1435	return ret;
   1436}
   1437
   1438static int change_station(struct wiphy *wiphy, struct net_device *dev,
   1439			  const u8 *mac, struct station_parameters *params)
   1440{
   1441	int ret = 0;
   1442	struct wilc_vif *vif = netdev_priv(dev);
   1443
   1444	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
   1445		ret = wilc_edit_station(vif, mac, params);
   1446		if (ret)
   1447			netdev_err(dev, "Host edit station fail\n");
   1448	}
   1449	return ret;
   1450}
   1451
   1452static struct wilc_vif *wilc_get_vif_from_type(struct wilc *wl, int type)
   1453{
   1454	struct wilc_vif *vif;
   1455
   1456	list_for_each_entry_rcu(vif, &wl->vif_list, list) {
   1457		if (vif->iftype == type)
   1458			return vif;
   1459	}
   1460
   1461	return NULL;
   1462}
   1463
   1464static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
   1465					     const char *name,
   1466					     unsigned char name_assign_type,
   1467					     enum nl80211_iftype type,
   1468					     struct vif_params *params)
   1469{
   1470	struct wilc *wl = wiphy_priv(wiphy);
   1471	struct wilc_vif *vif;
   1472	struct wireless_dev *wdev;
   1473	int iftype;
   1474
   1475	if (type == NL80211_IFTYPE_MONITOR) {
   1476		struct net_device *ndev;
   1477		int srcu_idx;
   1478
   1479		srcu_idx = srcu_read_lock(&wl->srcu);
   1480		vif = wilc_get_vif_from_type(wl, WILC_AP_MODE);
   1481		if (!vif) {
   1482			vif = wilc_get_vif_from_type(wl, WILC_GO_MODE);
   1483			if (!vif) {
   1484				srcu_read_unlock(&wl->srcu, srcu_idx);
   1485				goto validate_interface;
   1486			}
   1487		}
   1488
   1489		if (vif->monitor_flag) {
   1490			srcu_read_unlock(&wl->srcu, srcu_idx);
   1491			goto validate_interface;
   1492		}
   1493
   1494		ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
   1495		if (ndev) {
   1496			vif->monitor_flag = 1;
   1497		} else {
   1498			srcu_read_unlock(&wl->srcu, srcu_idx);
   1499			return ERR_PTR(-EINVAL);
   1500		}
   1501
   1502		wdev = &vif->priv.wdev;
   1503		srcu_read_unlock(&wl->srcu, srcu_idx);
   1504		return wdev;
   1505	}
   1506
   1507validate_interface:
   1508	mutex_lock(&wl->vif_mutex);
   1509	if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
   1510		pr_err("Reached maximum number of interface\n");
   1511		mutex_unlock(&wl->vif_mutex);
   1512		return ERR_PTR(-EINVAL);
   1513	}
   1514	mutex_unlock(&wl->vif_mutex);
   1515
   1516	switch (type) {
   1517	case NL80211_IFTYPE_STATION:
   1518		iftype = WILC_STATION_MODE;
   1519		break;
   1520	case NL80211_IFTYPE_AP:
   1521		iftype = WILC_AP_MODE;
   1522		break;
   1523	default:
   1524		return ERR_PTR(-EOPNOTSUPP);
   1525	}
   1526
   1527	vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
   1528	if (IS_ERR(vif))
   1529		return ERR_CAST(vif);
   1530
   1531	return &vif->priv.wdev;
   1532}
   1533
   1534static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
   1535{
   1536	struct wilc *wl = wiphy_priv(wiphy);
   1537	struct wilc_vif *vif;
   1538
   1539	if (wdev->iftype == NL80211_IFTYPE_AP ||
   1540	    wdev->iftype == NL80211_IFTYPE_P2P_GO)
   1541		wilc_wfi_deinit_mon_interface(wl, true);
   1542	vif = netdev_priv(wdev->netdev);
   1543	cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
   1544	cfg80211_unregister_netdevice(vif->ndev);
   1545	vif->monitor_flag = 0;
   1546
   1547	wilc_set_operation_mode(vif, 0, 0, 0);
   1548	mutex_lock(&wl->vif_mutex);
   1549	list_del_rcu(&vif->list);
   1550	wl->vif_num--;
   1551	mutex_unlock(&wl->vif_mutex);
   1552	synchronize_srcu(&wl->srcu);
   1553	return 0;
   1554}
   1555
   1556static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
   1557{
   1558	struct wilc *wl = wiphy_priv(wiphy);
   1559
   1560	if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
   1561		wl->suspend_event = true;
   1562	else
   1563		wl->suspend_event = false;
   1564
   1565	return 0;
   1566}
   1567
   1568static int wilc_resume(struct wiphy *wiphy)
   1569{
   1570	return 0;
   1571}
   1572
   1573static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
   1574{
   1575	struct wilc *wl = wiphy_priv(wiphy);
   1576	struct wilc_vif *vif;
   1577	int srcu_idx;
   1578
   1579	srcu_idx = srcu_read_lock(&wl->srcu);
   1580	vif = wilc_get_wl_to_vif(wl);
   1581	if (IS_ERR(vif)) {
   1582		srcu_read_unlock(&wl->srcu, srcu_idx);
   1583		return;
   1584	}
   1585
   1586	netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
   1587	wilc_set_wowlan_trigger(vif, enabled);
   1588	srcu_read_unlock(&wl->srcu, srcu_idx);
   1589}
   1590
   1591static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
   1592			enum nl80211_tx_power_setting type, int mbm)
   1593{
   1594	int ret;
   1595	int srcu_idx;
   1596	s32 tx_power = MBM_TO_DBM(mbm);
   1597	struct wilc *wl = wiphy_priv(wiphy);
   1598	struct wilc_vif *vif;
   1599
   1600	if (!wl->initialized)
   1601		return -EIO;
   1602
   1603	srcu_idx = srcu_read_lock(&wl->srcu);
   1604	vif = wilc_get_wl_to_vif(wl);
   1605	if (IS_ERR(vif)) {
   1606		srcu_read_unlock(&wl->srcu, srcu_idx);
   1607		return -EINVAL;
   1608	}
   1609
   1610	netdev_info(vif->ndev, "Setting tx power %d\n", tx_power);
   1611	if (tx_power < 0)
   1612		tx_power = 0;
   1613	else if (tx_power > 18)
   1614		tx_power = 18;
   1615	ret = wilc_set_tx_power(vif, tx_power);
   1616	if (ret)
   1617		netdev_err(vif->ndev, "Failed to set tx power\n");
   1618	srcu_read_unlock(&wl->srcu, srcu_idx);
   1619
   1620	return ret;
   1621}
   1622
   1623static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
   1624			int *dbm)
   1625{
   1626	int ret;
   1627	struct wilc_vif *vif = netdev_priv(wdev->netdev);
   1628	struct wilc *wl = vif->wilc;
   1629
   1630	/* If firmware is not started, return. */
   1631	if (!wl->initialized)
   1632		return -EIO;
   1633
   1634	ret = wilc_get_tx_power(vif, (u8 *)dbm);
   1635	if (ret)
   1636		netdev_err(vif->ndev, "Failed to get tx power\n");
   1637
   1638	return ret;
   1639}
   1640
   1641static const struct cfg80211_ops wilc_cfg80211_ops = {
   1642	.set_monitor_channel = set_channel,
   1643	.scan = scan,
   1644	.connect = connect,
   1645	.disconnect = disconnect,
   1646	.add_key = add_key,
   1647	.del_key = del_key,
   1648	.get_key = get_key,
   1649	.set_default_key = set_default_key,
   1650	.add_virtual_intf = add_virtual_intf,
   1651	.del_virtual_intf = del_virtual_intf,
   1652	.change_virtual_intf = change_virtual_intf,
   1653
   1654	.start_ap = start_ap,
   1655	.change_beacon = change_beacon,
   1656	.stop_ap = stop_ap,
   1657	.add_station = add_station,
   1658	.del_station = del_station,
   1659	.change_station = change_station,
   1660	.get_station = get_station,
   1661	.dump_station = dump_station,
   1662	.change_bss = change_bss,
   1663	.set_wiphy_params = set_wiphy_params,
   1664
   1665	.set_pmksa = set_pmksa,
   1666	.del_pmksa = del_pmksa,
   1667	.flush_pmksa = flush_pmksa,
   1668	.remain_on_channel = remain_on_channel,
   1669	.cancel_remain_on_channel = cancel_remain_on_channel,
   1670	.mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
   1671	.mgmt_tx = mgmt_tx,
   1672	.update_mgmt_frame_registrations = wilc_update_mgmt_frame_registrations,
   1673	.set_power_mgmt = set_power_mgmt,
   1674	.set_cqm_rssi_config = set_cqm_rssi_config,
   1675
   1676	.suspend = wilc_suspend,
   1677	.resume = wilc_resume,
   1678	.set_wakeup = wilc_set_wakeup,
   1679	.set_tx_power = set_tx_power,
   1680	.get_tx_power = get_tx_power,
   1681
   1682};
   1683
   1684static void wlan_init_locks(struct wilc *wl)
   1685{
   1686	mutex_init(&wl->hif_cs);
   1687	mutex_init(&wl->rxq_cs);
   1688	mutex_init(&wl->cfg_cmd_lock);
   1689	mutex_init(&wl->vif_mutex);
   1690	mutex_init(&wl->deinit_lock);
   1691
   1692	spin_lock_init(&wl->txq_spinlock);
   1693	mutex_init(&wl->txq_add_to_head_cs);
   1694
   1695	init_completion(&wl->txq_event);
   1696	init_completion(&wl->cfg_event);
   1697	init_completion(&wl->sync_event);
   1698	init_completion(&wl->txq_thread_started);
   1699	init_srcu_struct(&wl->srcu);
   1700}
   1701
   1702void wlan_deinit_locks(struct wilc *wilc)
   1703{
   1704	mutex_destroy(&wilc->hif_cs);
   1705	mutex_destroy(&wilc->rxq_cs);
   1706	mutex_destroy(&wilc->cfg_cmd_lock);
   1707	mutex_destroy(&wilc->txq_add_to_head_cs);
   1708	mutex_destroy(&wilc->vif_mutex);
   1709	mutex_destroy(&wilc->deinit_lock);
   1710	cleanup_srcu_struct(&wilc->srcu);
   1711}
   1712
   1713int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
   1714		       const struct wilc_hif_func *ops)
   1715{
   1716	struct wilc *wl;
   1717	struct wilc_vif *vif;
   1718	int ret, i;
   1719
   1720	wl = wilc_create_wiphy(dev);
   1721	if (!wl)
   1722		return -EINVAL;
   1723
   1724	wlan_init_locks(wl);
   1725
   1726	ret = wilc_wlan_cfg_init(wl);
   1727	if (ret)
   1728		goto free_wl;
   1729
   1730	*wilc = wl;
   1731	wl->io_type = io_type;
   1732	wl->hif_func = ops;
   1733
   1734	for (i = 0; i < NQUEUES; i++)
   1735		INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
   1736
   1737	INIT_LIST_HEAD(&wl->rxq_head.list);
   1738	INIT_LIST_HEAD(&wl->vif_list);
   1739
   1740	vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
   1741				   NL80211_IFTYPE_STATION, false);
   1742	if (IS_ERR(vif)) {
   1743		ret = PTR_ERR(vif);
   1744		goto free_cfg;
   1745	}
   1746
   1747	return 0;
   1748
   1749free_cfg:
   1750	wilc_wlan_cfg_deinit(wl);
   1751
   1752free_wl:
   1753	wlan_deinit_locks(wl);
   1754	wiphy_unregister(wl->wiphy);
   1755	wiphy_free(wl->wiphy);
   1756	return ret;
   1757}
   1758EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
   1759
   1760struct wilc *wilc_create_wiphy(struct device *dev)
   1761{
   1762	struct wiphy *wiphy;
   1763	struct wilc *wl;
   1764	int ret;
   1765
   1766	wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
   1767	if (!wiphy)
   1768		return NULL;
   1769
   1770	wl = wiphy_priv(wiphy);
   1771
   1772	memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
   1773	memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
   1774	wl->band.bitrates = wl->bitrates;
   1775	wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
   1776	wl->band.channels = wl->channels;
   1777	wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
   1778
   1779	wl->band.ht_cap.ht_supported = 1;
   1780	wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
   1781	wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
   1782	wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
   1783	wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
   1784
   1785	wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
   1786
   1787	wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
   1788#ifdef CONFIG_PM
   1789	wiphy->wowlan = &wowlan_support;
   1790#endif
   1791	wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
   1792	wiphy->max_scan_ie_len = 1000;
   1793	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
   1794	memcpy(wl->cipher_suites, wilc_cipher_suites,
   1795	       sizeof(wilc_cipher_suites));
   1796	wiphy->cipher_suites = wl->cipher_suites;
   1797	wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
   1798	wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
   1799
   1800	wiphy->max_remain_on_channel_duration = 500;
   1801	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
   1802				BIT(NL80211_IFTYPE_AP) |
   1803				BIT(NL80211_IFTYPE_MONITOR) |
   1804				BIT(NL80211_IFTYPE_P2P_GO) |
   1805				BIT(NL80211_IFTYPE_P2P_CLIENT);
   1806	wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
   1807
   1808	set_wiphy_dev(wiphy, dev);
   1809	wl->wiphy = wiphy;
   1810	ret = wiphy_register(wiphy);
   1811	if (ret) {
   1812		wiphy_free(wiphy);
   1813		return NULL;
   1814	}
   1815	return wl;
   1816}
   1817
   1818int wilc_init_host_int(struct net_device *net)
   1819{
   1820	int ret;
   1821	struct wilc_vif *vif = netdev_priv(net);
   1822	struct wilc_priv *priv = &vif->priv;
   1823
   1824	priv->p2p_listen_state = false;
   1825
   1826	mutex_init(&priv->scan_req_lock);
   1827	ret = wilc_init(net, &priv->hif_drv);
   1828	if (ret)
   1829		netdev_err(net, "Error while initializing hostinterface\n");
   1830
   1831	return ret;
   1832}
   1833
   1834void wilc_deinit_host_int(struct net_device *net)
   1835{
   1836	int ret;
   1837	struct wilc_vif *vif = netdev_priv(net);
   1838	struct wilc_priv *priv = &vif->priv;
   1839
   1840	priv->p2p_listen_state = false;
   1841
   1842	flush_workqueue(vif->wilc->hif_workqueue);
   1843	mutex_destroy(&priv->scan_req_lock);
   1844	ret = wilc_deinit(vif);
   1845
   1846	if (ret)
   1847		netdev_err(net, "Error while deinitializing host interface\n");
   1848}
   1849