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	u32 i = 0;
732	u32 associatedsta = ~0;
733	u32 inactive_time = 0;
734
735	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
736		for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
737			if (!(memcmp(mac,
738				     priv->assoc_stainfo.sta_associated_bss[i],
739				     ETH_ALEN))) {
740				associatedsta = i;
741				break;
742			}
743		}
744
745		if (associatedsta == ~0) {
746			netdev_err(dev, "sta required is not associated\n");
747			return -ENOENT;
748		}
749
750		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
751
752		wilc_get_inactive_time(vif, mac, &inactive_time);
753		sinfo->inactive_time = 1000 * inactive_time;
754	} else if (vif->iftype == WILC_STATION_MODE) {
755		struct rf_info stats;
756
757		wilc_get_statistics(vif, &stats);
758
759		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
760				 BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
761				 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
762				 BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
763				 BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
764
765		sinfo->signal = stats.rssi;
766		sinfo->rx_packets = stats.rx_cnt;
767		sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
768		sinfo->tx_failed = stats.tx_fail_cnt;
769		sinfo->txrate.legacy = stats.link_speed * 10;
770
771		if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
772		    stats.link_speed != DEFAULT_LINK_SPEED)
773			wilc_enable_tcp_ack_filter(vif, true);
774		else if (stats.link_speed != DEFAULT_LINK_SPEED)
775			wilc_enable_tcp_ack_filter(vif, false);
776	}
777	return 0;
778}
779
780static int change_bss(struct wiphy *wiphy, struct net_device *dev,
781		      struct bss_parameters *params)
782{
783	return 0;
784}
785
786static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
787{
788	int ret = -EINVAL;
789	struct cfg_param_attr cfg_param_val;
790	struct wilc *wl = wiphy_priv(wiphy);
791	struct wilc_vif *vif;
792	struct wilc_priv *priv;
793	int srcu_idx;
794
795	srcu_idx = srcu_read_lock(&wl->srcu);
796	vif = wilc_get_wl_to_vif(wl);
797	if (IS_ERR(vif))
798		goto out;
799
800	priv = &vif->priv;
801	cfg_param_val.flag = 0;
802
803	if (changed & WIPHY_PARAM_RETRY_SHORT) {
804		netdev_dbg(vif->ndev,
805			   "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
806			   wiphy->retry_short);
807		cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
808		cfg_param_val.short_retry_limit = wiphy->retry_short;
809	}
810	if (changed & WIPHY_PARAM_RETRY_LONG) {
811		netdev_dbg(vif->ndev,
812			   "Setting WIPHY_PARAM_RETRY_LONG %d\n",
813			   wiphy->retry_long);
814		cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
815		cfg_param_val.long_retry_limit = wiphy->retry_long;
816	}
817	if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
818		if (wiphy->frag_threshold > 255 &&
819		    wiphy->frag_threshold < 7937) {
820			netdev_dbg(vif->ndev,
821				   "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
822				   wiphy->frag_threshold);
823			cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
824			cfg_param_val.frag_threshold = wiphy->frag_threshold;
825		} else {
826			netdev_err(vif->ndev,
827				   "Fragmentation threshold out of range\n");
828			goto out;
829		}
830	}
831
832	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
833		if (wiphy->rts_threshold > 255) {
834			netdev_dbg(vif->ndev,
835				   "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
836				   wiphy->rts_threshold);
837			cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
838			cfg_param_val.rts_threshold = wiphy->rts_threshold;
839		} else {
840			netdev_err(vif->ndev, "RTS threshold out of range\n");
841			goto out;
842		}
843	}
844
845	ret = wilc_hif_set_cfg(vif, &cfg_param_val);
846	if (ret)
847		netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
848
849out:
850	srcu_read_unlock(&wl->srcu, srcu_idx);
851	return ret;
852}
853
854static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
855		     struct cfg80211_pmksa *pmksa)
856{
857	struct wilc_vif *vif = netdev_priv(netdev);
858	struct wilc_priv *priv = &vif->priv;
859	u32 i;
860	int ret = 0;
861	u8 flag = 0;
862
863	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
864		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
865			    ETH_ALEN)) {
866			flag = PMKID_FOUND;
867			break;
868		}
869	}
870	if (i < WILC_MAX_NUM_PMKIDS) {
871		memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
872		       ETH_ALEN);
873		memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
874		       WLAN_PMKID_LEN);
875		if (!(flag == PMKID_FOUND))
876			priv->pmkid_list.numpmkid++;
877	} else {
878		netdev_err(netdev, "Invalid PMKID index\n");
879		ret = -EINVAL;
880	}
881
882	if (!ret)
883		ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
884
885	return ret;
886}
887
888static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
889		     struct cfg80211_pmksa *pmksa)
890{
891	u32 i;
892	struct wilc_vif *vif = netdev_priv(netdev);
893	struct wilc_priv *priv = &vif->priv;
894
895	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
896		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
897			    ETH_ALEN)) {
898			memset(&priv->pmkid_list.pmkidlist[i], 0,
899			       sizeof(struct wilc_pmkid));
900			break;
901		}
902	}
903
904	if (i == priv->pmkid_list.numpmkid)
905		return -EINVAL;
906
907	for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
908		memcpy(priv->pmkid_list.pmkidlist[i].bssid,
909		       priv->pmkid_list.pmkidlist[i + 1].bssid,
910		       ETH_ALEN);
911		memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
912		       priv->pmkid_list.pmkidlist[i + 1].pmkid,
913		       WLAN_PMKID_LEN);
914	}
915	priv->pmkid_list.numpmkid--;
916
917	return 0;
918}
919
920static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
921{
922	struct wilc_vif *vif = netdev_priv(netdev);
923
924	memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
925
926	return 0;
927}
928
929static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
930{
931	struct wilc_attr_entry *e;
932	struct wilc_attr_ch_list *ch_list;
933	struct wilc_attr_oper_ch *op_ch;
934	u32 index = 0;
935	u8 ch_list_idx = 0;
936	u8 op_ch_idx = 0;
937
938	if (sta_ch == WILC_INVALID_CHANNEL)
939		return;
940
941	while (index + sizeof(*e) <= len) {
942		u16 attr_size;
943
944		e = (struct wilc_attr_entry *)&buf[index];
945		attr_size = le16_to_cpu(e->attr_len);
946
947		if (index + sizeof(*e) + attr_size > len)
948			return;
949
950		if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST &&
951		    attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e)))
952			ch_list_idx = index;
953		else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
954			 attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
955			op_ch_idx = index;
956
957		if (ch_list_idx && op_ch_idx)
958			break;
959
960		index += sizeof(*e) + attr_size;
961	}
962
963	if (ch_list_idx) {
964		unsigned int i;
965		u16 elem_size;
966
967		ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
968		/* the number of bytes following the final 'elem' member */
969		elem_size = le16_to_cpu(ch_list->attr_len) -
970			(sizeof(*ch_list) - sizeof(struct wilc_attr_entry));
971		for (i = 0; i < elem_size;) {
972			struct wilc_ch_list_elem *e;
973
974			e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
975
976			i += sizeof(*e);
977			if (i > elem_size)
978				break;
979
980			i += e->no_of_channels;
981			if (i > elem_size)
982				break;
983
984			if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
985				memset(e->ch_list, sta_ch, e->no_of_channels);
986				break;
987			}
988		}
989	}
990
991	if (op_ch_idx) {
992		op_ch = (struct wilc_attr_oper_ch *)&buf[op_ch_idx];
993		op_ch->op_class = WILC_WLAN_OPERATING_CLASS_2_4GHZ;
994		op_ch->op_channel = sta_ch;
995	}
996}
997
998void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
999{
1000	struct wilc *wl = vif->wilc;
1001	struct wilc_priv *priv = &vif->priv;
1002	struct host_if_drv *wfi_drv = priv->hif_drv;
1003	struct ieee80211_mgmt *mgmt;
1004	struct wilc_vendor_specific_ie *p;
1005	struct wilc_p2p_pub_act_frame *d;
1006	int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
1007	const u8 *vendor_ie;
1008	u32 header, pkt_offset;
1009	s32 freq;
1010
1011	header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
1012	pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
1013
1014	if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1015		bool ack = false;
1016		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buff;
1017
1018		if (ieee80211_is_probe_resp(hdr->frame_control) ||
1019		    pkt_offset & IS_MGMT_STATUS_SUCCES)
1020			ack = true;
1021
1022		cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
1023					size, ack, GFP_KERNEL);
1024		return;
1025	}
1026
1027	freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
1028
1029	mgmt = (struct ieee80211_mgmt *)buff;
1030	if (!ieee80211_is_action(mgmt->frame_control))
1031		goto out_rx_mgmt;
1032
1033	if (priv->cfg_scanning &&
1034	    time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
1035		netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
1036		return;
1037	}
1038
1039	if (!ieee80211_is_public_action((struct ieee80211_hdr *)buff, size))
1040		goto out_rx_mgmt;
1041
1042	d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
1043	if (d->oui_subtype != GO_NEG_REQ && d->oui_subtype != GO_NEG_RSP &&
1044	    d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
1045		goto out_rx_mgmt;
1046
1047	vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1048					    buff + ie_offset, size - ie_offset);
1049	if (!vendor_ie)
1050		goto out_rx_mgmt;
1051
1052	p = (struct wilc_vendor_specific_ie *)vendor_ie;
1053	wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
1054
1055out_rx_mgmt:
1056	cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1057}
1058
1059static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
1060{
1061	struct wilc_p2p_mgmt_data *pv_data = priv;
1062
1063	kfree(pv_data->buff);
1064	kfree(pv_data);
1065}
1066
1067static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
1068{
1069	struct wilc_vif *vif = data;
1070	struct wilc_priv *priv = &vif->priv;
1071	struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
1072
1073	if (cookie != params->listen_cookie)
1074		return;
1075
1076	priv->p2p_listen_state = false;
1077
1078	cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
1079					   params->listen_ch, GFP_KERNEL);
1080}
1081
1082static int remain_on_channel(struct wiphy *wiphy,
1083			     struct wireless_dev *wdev,
1084			     struct ieee80211_channel *chan,
1085			     unsigned int duration, u64 *cookie)
1086{
1087	int ret = 0;
1088	struct wilc_vif *vif = netdev_priv(wdev->netdev);
1089	struct wilc_priv *priv = &vif->priv;
1090	u64 id;
1091
1092	if (wdev->iftype == NL80211_IFTYPE_AP) {
1093		netdev_dbg(vif->ndev, "Required while in AP mode\n");
1094		return ret;
1095	}
1096
1097	id = ++priv->inc_roc_cookie;
1098	if (id == 0)
1099		id = ++priv->inc_roc_cookie;
1100
1101	ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
1102				     wilc_wfi_remain_on_channel_expired,
1103				     (void *)vif);
1104	if (ret)
1105		return ret;
1106
1107	vif->wilc->op_ch = chan->hw_value;
1108
1109	priv->remain_on_ch_params.listen_ch = chan;
1110	priv->remain_on_ch_params.listen_cookie = id;
1111	*cookie = id;
1112	priv->p2p_listen_state = true;
1113	priv->remain_on_ch_params.listen_duration = duration;
1114
1115	cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
1116	mod_timer(&vif->hif_drv->remain_on_ch_timer,
1117		  jiffies + msecs_to_jiffies(duration + 1000));
1118
1119	return ret;
1120}
1121
1122static int cancel_remain_on_channel(struct wiphy *wiphy,
1123				    struct wireless_dev *wdev,
1124				    u64 cookie)
1125{
1126	struct wilc_vif *vif = netdev_priv(wdev->netdev);
1127	struct wilc_priv *priv = &vif->priv;
1128
1129	if (cookie != priv->remain_on_ch_params.listen_cookie)
1130		return -ENOENT;
1131
1132	return wilc_listen_state_expired(vif, cookie);
1133}
1134
1135static int mgmt_tx(struct wiphy *wiphy,
1136		   struct wireless_dev *wdev,
1137		   struct cfg80211_mgmt_tx_params *params,
1138		   u64 *cookie)
1139{
1140	struct ieee80211_channel *chan = params->chan;
1141	unsigned int wait = params->wait;
1142	const u8 *buf = params->buf;
1143	size_t len = params->len;
1144	const struct ieee80211_mgmt *mgmt;
1145	struct wilc_p2p_mgmt_data *mgmt_tx;
1146	struct wilc_vif *vif = netdev_priv(wdev->netdev);
1147	struct wilc_priv *priv = &vif->priv;
1148	struct host_if_drv *wfi_drv = priv->hif_drv;
1149	struct wilc_vendor_specific_ie *p;
1150	struct wilc_p2p_pub_act_frame *d;
1151	int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
1152	const u8 *vendor_ie;
1153	int ret = 0;
1154
1155	*cookie = prandom_u32();
1156	priv->tx_cookie = *cookie;
1157	mgmt = (const struct ieee80211_mgmt *)buf;
1158
1159	if (!ieee80211_is_mgmt(mgmt->frame_control))
1160		goto out;
1161
1162	mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
1163	if (!mgmt_tx) {
1164		ret = -ENOMEM;
1165		goto out;
1166	}
1167
1168	mgmt_tx->buff = kmemdup(buf, len, GFP_KERNEL);
1169	if (!mgmt_tx->buff) {
1170		ret = -ENOMEM;
1171		kfree(mgmt_tx);
1172		goto out;
1173	}
1174
1175	mgmt_tx->size = len;
1176
1177	if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1178		wilc_set_mac_chnl_num(vif, chan->hw_value);
1179		vif->wilc->op_ch = chan->hw_value;
1180		goto out_txq_add_pkt;
1181	}
1182
1183	if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len))
1184		goto out_set_timeout;
1185
1186	d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
1187	if (d->oui_type != WLAN_OUI_TYPE_WFA_P2P ||
1188	    d->oui_subtype != GO_NEG_CONF) {
1189		wilc_set_mac_chnl_num(vif, chan->hw_value);
1190		vif->wilc->op_ch = chan->hw_value;
1191	}
1192
1193	if (d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
1194		goto out_set_timeout;
1195
1196	vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1197					    mgmt_tx->buff + ie_offset,
1198					    len - ie_offset);
1199	if (!vendor_ie)
1200		goto out_set_timeout;
1201
1202	p = (struct wilc_vendor_specific_ie *)vendor_ie;
1203	wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
1204
1205out_set_timeout:
1206	wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1207
1208out_txq_add_pkt:
1209
1210	wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1211				   mgmt_tx->buff, mgmt_tx->size,
1212				   wilc_wfi_mgmt_tx_complete);
1213
1214out:
1215
1216	return ret;
1217}
1218
1219static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1220			       struct wireless_dev *wdev,
1221			       u64 cookie)
1222{
1223	struct wilc_vif *vif = netdev_priv(wdev->netdev);
1224	struct wilc_priv *priv = &vif->priv;
1225	struct host_if_drv *wfi_drv = priv->hif_drv;
1226
1227	wfi_drv->p2p_timeout = jiffies;
1228
1229	if (!priv->p2p_listen_state) {
1230		struct wilc_wfi_p2p_listen_params *params;
1231
1232		params = &priv->remain_on_ch_params;
1233
1234		cfg80211_remain_on_channel_expired(wdev,
1235						   params->listen_cookie,
1236						   params->listen_ch,
1237						   GFP_KERNEL);
1238	}
1239
1240	return 0;
1241}
1242
1243void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
1244					  struct wireless_dev *wdev,
1245					  struct mgmt_frame_regs *upd)
1246{
1247	struct wilc *wl = wiphy_priv(wiphy);
1248	struct wilc_vif *vif = netdev_priv(wdev->netdev);
1249	u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
1250	u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4);
1251
1252	if (wl->initialized) {
1253		bool prev = vif->mgmt_reg_stypes & presp_bit;
1254		bool now = upd->interface_stypes & presp_bit;
1255
1256		if (now != prev)
1257			wilc_frame_register(vif, IEEE80211_STYPE_PROBE_REQ, now);
1258
1259		prev = vif->mgmt_reg_stypes & action_bit;
1260		now = upd->interface_stypes & action_bit;
1261
1262		if (now != prev)
1263			wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now);
1264	}
1265
1266	vif->mgmt_reg_stypes =
1267		upd->interface_stypes & (presp_bit | action_bit);
1268}
1269
1270static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1271			       s32 rssi_thold, u32 rssi_hyst)
1272{
1273	return 0;
1274}
1275
1276static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1277			int idx, u8 *mac, struct station_info *sinfo)
1278{
1279	struct wilc_vif *vif = netdev_priv(dev);
1280	int ret;
1281
1282	if (idx != 0)
1283		return -ENOENT;
1284
1285	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1286
1287	ret = wilc_get_rssi(vif, &sinfo->signal);
1288	if (ret)
1289		return ret;
1290
1291	memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
1292	return 0;
1293}
1294
1295static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1296			  bool enabled, int timeout)
1297{
1298	struct wilc_vif *vif = netdev_priv(dev);
1299	struct wilc_priv *priv = &vif->priv;
1300
1301	if (!priv->hif_drv)
1302		return -EIO;
1303
1304	wilc_set_power_mgmt(vif, enabled, timeout);
1305
1306	return 0;
1307}
1308
1309static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1310			       enum nl80211_iftype type,
1311			       struct vif_params *params)
1312{
1313	struct wilc *wl = wiphy_priv(wiphy);
1314	struct wilc_vif *vif = netdev_priv(dev);
1315	struct wilc_priv *priv = &vif->priv;
1316
1317	switch (type) {
1318	case NL80211_IFTYPE_STATION:
1319		vif->connecting = false;
1320		dev->ieee80211_ptr->iftype = type;
1321		priv->wdev.iftype = type;
1322		vif->monitor_flag = 0;
1323		if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
1324			wilc_wfi_deinit_mon_interface(wl, true);
1325		vif->iftype = WILC_STATION_MODE;
1326
1327		if (wl->initialized)
1328			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1329						WILC_STATION_MODE, vif->idx);
1330
1331		memset(priv->assoc_stainfo.sta_associated_bss, 0,
1332		       WILC_MAX_NUM_STA * ETH_ALEN);
1333		break;
1334
1335	case NL80211_IFTYPE_P2P_CLIENT:
1336		vif->connecting = false;
1337		dev->ieee80211_ptr->iftype = type;
1338		priv->wdev.iftype = type;
1339		vif->monitor_flag = 0;
1340		vif->iftype = WILC_CLIENT_MODE;
1341
1342		if (wl->initialized)
1343			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1344						WILC_STATION_MODE, vif->idx);
1345		break;
1346
1347	case NL80211_IFTYPE_AP:
1348		dev->ieee80211_ptr->iftype = type;
1349		priv->wdev.iftype = type;
1350		vif->iftype = WILC_AP_MODE;
1351
1352		if (wl->initialized)
1353			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1354						WILC_AP_MODE, vif->idx);
1355		break;
1356
1357	case NL80211_IFTYPE_P2P_GO:
1358		dev->ieee80211_ptr->iftype = type;
1359		priv->wdev.iftype = type;
1360		vif->iftype = WILC_GO_MODE;
1361
1362		if (wl->initialized)
1363			wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1364						WILC_AP_MODE, vif->idx);
1365		break;
1366
1367	default:
1368		netdev_err(dev, "Unknown interface type= %d\n", type);
1369		return -EINVAL;
1370	}
1371
1372	return 0;
1373}
1374
1375static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1376		    struct cfg80211_ap_settings *settings)
1377{
1378	struct wilc_vif *vif = netdev_priv(dev);
1379	int ret;
1380
1381	ret = set_channel(wiphy, &settings->chandef);
1382	if (ret != 0)
1383		netdev_err(dev, "Error in setting channel\n");
1384
1385	wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
1386
1387	return wilc_add_beacon(vif, settings->beacon_interval,
1388				   settings->dtim_period, &settings->beacon);
1389}
1390
1391static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1392			 struct cfg80211_beacon_data *beacon)
1393{
1394	struct wilc_vif *vif = netdev_priv(dev);
1395
1396	return wilc_add_beacon(vif, 0, 0, beacon);
1397}
1398
1399static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1400{
1401	int ret;
1402	struct wilc_vif *vif = netdev_priv(dev);
1403
1404	wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
1405
1406	ret = wilc_del_beacon(vif);
1407
1408	if (ret)
1409		netdev_err(dev, "Host delete beacon fail\n");
1410
1411	return ret;
1412}
1413
1414static int add_station(struct wiphy *wiphy, struct net_device *dev,
1415		       const u8 *mac, struct station_parameters *params)
1416{
1417	int ret = 0;
1418	struct wilc_vif *vif = netdev_priv(dev);
1419	struct wilc_priv *priv = &vif->priv;
1420
1421	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
1422		memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
1423		       ETH_ALEN);
1424
1425		ret = wilc_add_station(vif, mac, params);
1426		if (ret)
1427			netdev_err(dev, "Host add station fail\n");
1428	}
1429
1430	return ret;
1431}
1432
1433static int del_station(struct wiphy *wiphy, struct net_device *dev,
1434		       struct station_del_parameters *params)
1435{
1436	const u8 *mac = params->mac;
1437	int ret = 0;
1438	struct wilc_vif *vif = netdev_priv(dev);
1439	struct wilc_priv *priv = &vif->priv;
1440	struct sta_info *info;
1441
1442	if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
1443		return ret;
1444
1445	info = &priv->assoc_stainfo;
1446
1447	if (!mac)
1448		ret = wilc_del_allstation(vif, info->sta_associated_bss);
1449
1450	ret = wilc_del_station(vif, mac);
1451	if (ret)
1452		netdev_err(dev, "Host delete station fail\n");
1453	return ret;
1454}
1455
1456static int change_station(struct wiphy *wiphy, struct net_device *dev,
1457			  const u8 *mac, struct station_parameters *params)
1458{
1459	int ret = 0;
1460	struct wilc_vif *vif = netdev_priv(dev);
1461
1462	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
1463		ret = wilc_edit_station(vif, mac, params);
1464		if (ret)
1465			netdev_err(dev, "Host edit station fail\n");
1466	}
1467	return ret;
1468}
1469
1470static struct wilc_vif *wilc_get_vif_from_type(struct wilc *wl, int type)
1471{
1472	struct wilc_vif *vif;
1473
1474	list_for_each_entry_rcu(vif, &wl->vif_list, list) {
1475		if (vif->iftype == type)
1476			return vif;
1477	}
1478
1479	return NULL;
1480}
1481
1482static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
1483					     const char *name,
1484					     unsigned char name_assign_type,
1485					     enum nl80211_iftype type,
1486					     struct vif_params *params)
1487{
1488	struct wilc *wl = wiphy_priv(wiphy);
1489	struct wilc_vif *vif;
1490	struct wireless_dev *wdev;
1491	int iftype;
1492
1493	if (type == NL80211_IFTYPE_MONITOR) {
1494		struct net_device *ndev;
1495		int srcu_idx;
1496
1497		srcu_idx = srcu_read_lock(&wl->srcu);
1498		vif = wilc_get_vif_from_type(wl, WILC_AP_MODE);
1499		if (!vif) {
1500			vif = wilc_get_vif_from_type(wl, WILC_GO_MODE);
1501			if (!vif) {
1502				srcu_read_unlock(&wl->srcu, srcu_idx);
1503				goto validate_interface;
1504			}
1505		}
1506
1507		if (vif->monitor_flag) {
1508			srcu_read_unlock(&wl->srcu, srcu_idx);
1509			goto validate_interface;
1510		}
1511
1512		ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
1513		if (ndev) {
1514			vif->monitor_flag = 1;
1515		} else {
1516			srcu_read_unlock(&wl->srcu, srcu_idx);
1517			return ERR_PTR(-EINVAL);
1518		}
1519
1520		wdev = &vif->priv.wdev;
1521		srcu_read_unlock(&wl->srcu, srcu_idx);
1522		return wdev;
1523	}
1524
1525validate_interface:
1526	mutex_lock(&wl->vif_mutex);
1527	if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
1528		pr_err("Reached maximum number of interface\n");
1529		mutex_unlock(&wl->vif_mutex);
1530		return ERR_PTR(-EINVAL);
1531	}
1532	mutex_unlock(&wl->vif_mutex);
1533
1534	switch (type) {
1535	case NL80211_IFTYPE_STATION:
1536		iftype = WILC_STATION_MODE;
1537		break;
1538	case NL80211_IFTYPE_AP:
1539		iftype = WILC_AP_MODE;
1540		break;
1541	default:
1542		return ERR_PTR(-EOPNOTSUPP);
1543	}
1544
1545	vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
1546	if (IS_ERR(vif))
1547		return ERR_CAST(vif);
1548
1549	return &vif->priv.wdev;
1550}
1551
1552static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
1553{
1554	struct wilc *wl = wiphy_priv(wiphy);
1555	struct wilc_vif *vif;
1556
1557	if (wdev->iftype == NL80211_IFTYPE_AP ||
1558	    wdev->iftype == NL80211_IFTYPE_P2P_GO)
1559		wilc_wfi_deinit_mon_interface(wl, true);
1560	vif = netdev_priv(wdev->netdev);
1561	cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
1562	unregister_netdevice(vif->ndev);
1563	vif->monitor_flag = 0;
1564
1565	wilc_set_operation_mode(vif, 0, 0, 0);
1566	mutex_lock(&wl->vif_mutex);
1567	list_del_rcu(&vif->list);
1568	wl->vif_num--;
1569	mutex_unlock(&wl->vif_mutex);
1570	synchronize_srcu(&wl->srcu);
1571	return 0;
1572}
1573
1574static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
1575{
1576	struct wilc *wl = wiphy_priv(wiphy);
1577
1578	if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
1579		wl->suspend_event = true;
1580	else
1581		wl->suspend_event = false;
1582
1583	return 0;
1584}
1585
1586static int wilc_resume(struct wiphy *wiphy)
1587{
1588	return 0;
1589}
1590
1591static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
1592{
1593	struct wilc *wl = wiphy_priv(wiphy);
1594	struct wilc_vif *vif;
1595	int srcu_idx;
1596
1597	srcu_idx = srcu_read_lock(&wl->srcu);
1598	vif = wilc_get_wl_to_vif(wl);
1599	if (IS_ERR(vif)) {
1600		srcu_read_unlock(&wl->srcu, srcu_idx);
1601		return;
1602	}
1603
1604	netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
1605	srcu_read_unlock(&wl->srcu, srcu_idx);
1606}
1607
1608static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1609			enum nl80211_tx_power_setting type, int mbm)
1610{
1611	int ret;
1612	int srcu_idx;
1613	s32 tx_power = MBM_TO_DBM(mbm);
1614	struct wilc *wl = wiphy_priv(wiphy);
1615	struct wilc_vif *vif;
1616
1617	if (!wl->initialized)
1618		return -EIO;
1619
1620	srcu_idx = srcu_read_lock(&wl->srcu);
1621	vif = wilc_get_wl_to_vif(wl);
1622	if (IS_ERR(vif)) {
1623		srcu_read_unlock(&wl->srcu, srcu_idx);
1624		return -EINVAL;
1625	}
1626
1627	netdev_info(vif->ndev, "Setting tx power %d\n", tx_power);
1628	if (tx_power < 0)
1629		tx_power = 0;
1630	else if (tx_power > 18)
1631		tx_power = 18;
1632	ret = wilc_set_tx_power(vif, tx_power);
1633	if (ret)
1634		netdev_err(vif->ndev, "Failed to set tx power\n");
1635	srcu_read_unlock(&wl->srcu, srcu_idx);
1636
1637	return ret;
1638}
1639
1640static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1641			int *dbm)
1642{
1643	int ret;
1644	struct wilc_vif *vif = netdev_priv(wdev->netdev);
1645	struct wilc *wl = vif->wilc;
1646
1647	/* If firmware is not started, return. */
1648	if (!wl->initialized)
1649		return -EIO;
1650
1651	ret = wilc_get_tx_power(vif, (u8 *)dbm);
1652	if (ret)
1653		netdev_err(vif->ndev, "Failed to get tx power\n");
1654
1655	return ret;
1656}
1657
1658static const struct cfg80211_ops wilc_cfg80211_ops = {
1659	.set_monitor_channel = set_channel,
1660	.scan = scan,
1661	.connect = connect,
1662	.disconnect = disconnect,
1663	.add_key = add_key,
1664	.del_key = del_key,
1665	.get_key = get_key,
1666	.set_default_key = set_default_key,
1667	.add_virtual_intf = add_virtual_intf,
1668	.del_virtual_intf = del_virtual_intf,
1669	.change_virtual_intf = change_virtual_intf,
1670
1671	.start_ap = start_ap,
1672	.change_beacon = change_beacon,
1673	.stop_ap = stop_ap,
1674	.add_station = add_station,
1675	.del_station = del_station,
1676	.change_station = change_station,
1677	.get_station = get_station,
1678	.dump_station = dump_station,
1679	.change_bss = change_bss,
1680	.set_wiphy_params = set_wiphy_params,
1681
1682	.set_pmksa = set_pmksa,
1683	.del_pmksa = del_pmksa,
1684	.flush_pmksa = flush_pmksa,
1685	.remain_on_channel = remain_on_channel,
1686	.cancel_remain_on_channel = cancel_remain_on_channel,
1687	.mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
1688	.mgmt_tx = mgmt_tx,
1689	.update_mgmt_frame_registrations = wilc_update_mgmt_frame_registrations,
1690	.set_power_mgmt = set_power_mgmt,
1691	.set_cqm_rssi_config = set_cqm_rssi_config,
1692
1693	.suspend = wilc_suspend,
1694	.resume = wilc_resume,
1695	.set_wakeup = wilc_set_wakeup,
1696	.set_tx_power = set_tx_power,
1697	.get_tx_power = get_tx_power,
1698
1699};
1700
1701static void wlan_init_locks(struct wilc *wl)
1702{
1703	mutex_init(&wl->hif_cs);
1704	mutex_init(&wl->rxq_cs);
1705	mutex_init(&wl->cfg_cmd_lock);
1706	mutex_init(&wl->vif_mutex);
1707
1708	spin_lock_init(&wl->txq_spinlock);
1709	mutex_init(&wl->txq_add_to_head_cs);
1710
1711	init_completion(&wl->txq_event);
1712	init_completion(&wl->cfg_event);
1713	init_completion(&wl->sync_event);
1714	init_completion(&wl->txq_thread_started);
1715	init_srcu_struct(&wl->srcu);
1716}
1717
1718void wlan_deinit_locks(struct wilc *wilc)
1719{
1720	mutex_destroy(&wilc->hif_cs);
1721	mutex_destroy(&wilc->rxq_cs);
1722	mutex_destroy(&wilc->cfg_cmd_lock);
1723	mutex_destroy(&wilc->txq_add_to_head_cs);
1724	mutex_destroy(&wilc->vif_mutex);
1725	cleanup_srcu_struct(&wilc->srcu);
1726}
1727
1728int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
1729		       const struct wilc_hif_func *ops)
1730{
1731	struct wilc *wl;
1732	struct wilc_vif *vif;
1733	int ret;
1734
1735	wl = wilc_create_wiphy(dev);
1736	if (!wl)
1737		return -EINVAL;
1738
1739	wlan_init_locks(wl);
1740
1741	ret = wilc_wlan_cfg_init(wl);
1742	if (ret)
1743		goto free_wl;
1744
1745	*wilc = wl;
1746	wl->io_type = io_type;
1747	wl->hif_func = ops;
1748	wl->chip_ps_state = WILC_CHIP_WAKEDUP;
1749	INIT_LIST_HEAD(&wl->txq_head.list);
1750	INIT_LIST_HEAD(&wl->rxq_head.list);
1751	INIT_LIST_HEAD(&wl->vif_list);
1752
1753	wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
1754	if (!wl->hif_workqueue) {
1755		ret = -ENOMEM;
1756		goto free_cfg;
1757	}
1758	vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
1759				   NL80211_IFTYPE_STATION, false);
1760	if (IS_ERR(vif)) {
1761		ret = PTR_ERR(vif);
1762		goto free_hq;
1763	}
1764
1765	return 0;
1766
1767free_hq:
1768	destroy_workqueue(wl->hif_workqueue);
1769
1770free_cfg:
1771	wilc_wlan_cfg_deinit(wl);
1772
1773free_wl:
1774	wlan_deinit_locks(wl);
1775	wiphy_unregister(wl->wiphy);
1776	wiphy_free(wl->wiphy);
1777	return ret;
1778}
1779EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
1780
1781struct wilc *wilc_create_wiphy(struct device *dev)
1782{
1783	struct wiphy *wiphy;
1784	struct wilc *wl;
1785	int ret;
1786
1787	wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
1788	if (!wiphy)
1789		return NULL;
1790
1791	wl = wiphy_priv(wiphy);
1792
1793	memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
1794	memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
1795	wl->band.bitrates = wl->bitrates;
1796	wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
1797	wl->band.channels = wl->channels;
1798	wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
1799
1800	wl->band.ht_cap.ht_supported = 1;
1801	wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
1802	wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
1803	wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
1804	wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1805
1806	wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
1807
1808	wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
1809#ifdef CONFIG_PM
1810	wiphy->wowlan = &wowlan_support;
1811#endif
1812	wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
1813	wiphy->max_scan_ie_len = 1000;
1814	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1815	memcpy(wl->cipher_suites, wilc_cipher_suites,
1816	       sizeof(wilc_cipher_suites));
1817	wiphy->cipher_suites = wl->cipher_suites;
1818	wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
1819	wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
1820
1821	wiphy->max_remain_on_channel_duration = 500;
1822	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1823				BIT(NL80211_IFTYPE_AP) |
1824				BIT(NL80211_IFTYPE_MONITOR) |
1825				BIT(NL80211_IFTYPE_P2P_GO) |
1826				BIT(NL80211_IFTYPE_P2P_CLIENT);
1827	wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
1828
1829	set_wiphy_dev(wiphy, dev);
1830	wl->wiphy = wiphy;
1831	ret = wiphy_register(wiphy);
1832	if (ret) {
1833		wiphy_free(wiphy);
1834		return NULL;
1835	}
1836	return wl;
1837}
1838
1839int wilc_init_host_int(struct net_device *net)
1840{
1841	int ret;
1842	struct wilc_vif *vif = netdev_priv(net);
1843	struct wilc_priv *priv = &vif->priv;
1844
1845	priv->p2p_listen_state = false;
1846
1847	mutex_init(&priv->scan_req_lock);
1848	ret = wilc_init(net, &priv->hif_drv);
1849	if (ret)
1850		netdev_err(net, "Error while initializing hostinterface\n");
1851
1852	return ret;
1853}
1854
1855void wilc_deinit_host_int(struct net_device *net)
1856{
1857	int ret;
1858	struct wilc_vif *vif = netdev_priv(net);
1859	struct wilc_priv *priv = &vif->priv;
1860
1861	priv->p2p_listen_state = false;
1862
1863	flush_workqueue(vif->wilc->hif_workqueue);
1864	mutex_destroy(&priv->scan_req_lock);
1865	ret = wilc_deinit(vif);
1866
1867	if (ret)
1868		netdev_err(net, "Error while deinitializing host interface\n");
1869}
1870
1871