Linux Audio

Check our new training course

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