• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "wilc_wfi_cfgoperations.h"
2 #include "host_interface.h"
3 #include <linux/errno.h>
4 
5 #define NO_ENCRYPT		0
6 #define ENCRYPT_ENABLED		BIT(0)
7 #define WEP			BIT(1)
8 #define WEP_EXTENDED		BIT(2)
9 #define WPA			BIT(3)
10 #define WPA2			BIT(4)
11 #define AES			BIT(5)
12 #define TKIP			BIT(6)
13 
14 #define FRAME_TYPE_ID			0
15 #define ACTION_CAT_ID			24
16 #define ACTION_SUBTYPE_ID		25
17 #define P2P_PUB_ACTION_SUBTYPE		30
18 
19 #define ACTION_FRAME			0xd0
20 #define GO_INTENT_ATTR_ID		0x04
21 #define CHANLIST_ATTR_ID		0x0b
22 #define OPERCHAN_ATTR_ID		0x11
23 #define PUB_ACTION_ATTR_ID		0x04
24 #define P2PELEM_ATTR_ID			0xdd
25 
26 #define GO_NEG_REQ			0x00
27 #define GO_NEG_RSP			0x01
28 #define GO_NEG_CONF			0x02
29 #define P2P_INV_REQ			0x03
30 #define P2P_INV_RSP			0x04
31 #define PUBLIC_ACT_VENDORSPEC		0x09
32 #define GAS_INTIAL_REQ			0x0a
33 #define GAS_INTIAL_RSP			0x0b
34 
35 #define INVALID_CHANNEL			0
36 
37 #define nl80211_SCAN_RESULT_EXPIRE	(3 * HZ)
38 #define SCAN_RESULT_EXPIRE		(40 * HZ)
39 
40 static const u32 cipher_suites[] = {
41 	WLAN_CIPHER_SUITE_WEP40,
42 	WLAN_CIPHER_SUITE_WEP104,
43 	WLAN_CIPHER_SUITE_TKIP,
44 	WLAN_CIPHER_SUITE_CCMP,
45 	WLAN_CIPHER_SUITE_AES_CMAC,
46 };
47 
48 static const struct ieee80211_txrx_stypes
49 	wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
50 	[NL80211_IFTYPE_STATION] = {
51 		.tx = 0xffff,
52 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
53 			BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
54 	},
55 	[NL80211_IFTYPE_AP] = {
56 		.tx = 0xffff,
57 		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
58 			BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
59 			BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
60 			BIT(IEEE80211_STYPE_DISASSOC >> 4) |
61 			BIT(IEEE80211_STYPE_AUTH >> 4) |
62 			BIT(IEEE80211_STYPE_DEAUTH >> 4) |
63 			BIT(IEEE80211_STYPE_ACTION >> 4)
64 	},
65 	[NL80211_IFTYPE_P2P_CLIENT] = {
66 		.tx = 0xffff,
67 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
68 			BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
69 			BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
70 			BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
71 			BIT(IEEE80211_STYPE_DISASSOC >> 4) |
72 			BIT(IEEE80211_STYPE_AUTH >> 4) |
73 			BIT(IEEE80211_STYPE_DEAUTH >> 4)
74 	}
75 };
76 
77 static const struct wiphy_wowlan_support wowlan_support = {
78 	.flags = WIPHY_WOWLAN_ANY
79 };
80 
81 #define WILC_WFI_DWELL_PASSIVE 100
82 #define WILC_WFI_DWELL_ACTIVE  40
83 
84 #define TCP_ACK_FILTER_LINK_SPEED_THRESH	54
85 #define DEFAULT_LINK_SPEED			72
86 
87 
88 #define IS_MANAGMEMENT				0x100
89 #define IS_MANAGMEMENT_CALLBACK			0x080
90 #define IS_MGMT_STATUS_SUCCES			0x040
91 #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
92 
93 extern int wilc_mac_open(struct net_device *ndev);
94 extern int wilc_mac_close(struct net_device *ndev);
95 
96 static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
97 static u32 last_scanned_cnt;
98 struct timer_list wilc_during_ip_timer;
99 static struct timer_list hAgingTimer;
100 static u8 op_ifcs;
101 
102 u8 wilc_initialized = 1;
103 
104 #define CHAN2G(_channel, _freq, _flags) {	 \
105 		.band             = NL80211_BAND_2GHZ, \
106 		.center_freq      = (_freq),		 \
107 		.hw_value         = (_channel),		 \
108 		.flags            = (_flags),		 \
109 		.max_antenna_gain = 0,			 \
110 		.max_power        = 30,			 \
111 }
112 
113 static struct ieee80211_channel ieee80211_2ghz_channels[] = {
114 	CHAN2G(1,  2412, 0),
115 	CHAN2G(2,  2417, 0),
116 	CHAN2G(3,  2422, 0),
117 	CHAN2G(4,  2427, 0),
118 	CHAN2G(5,  2432, 0),
119 	CHAN2G(6,  2437, 0),
120 	CHAN2G(7,  2442, 0),
121 	CHAN2G(8,  2447, 0),
122 	CHAN2G(9,  2452, 0),
123 	CHAN2G(10, 2457, 0),
124 	CHAN2G(11, 2462, 0),
125 	CHAN2G(12, 2467, 0),
126 	CHAN2G(13, 2472, 0),
127 	CHAN2G(14, 2484, 0),
128 };
129 
130 #define RATETAB_ENT(_rate, _hw_value, _flags) {	\
131 		.bitrate  = (_rate),			\
132 		.hw_value = (_hw_value),		\
133 		.flags    = (_flags),			\
134 }
135 
136 static struct ieee80211_rate ieee80211_bitrates[] = {
137 	RATETAB_ENT(10,  0,  0),
138 	RATETAB_ENT(20,  1,  0),
139 	RATETAB_ENT(55,  2,  0),
140 	RATETAB_ENT(110, 3,  0),
141 	RATETAB_ENT(60,  9,  0),
142 	RATETAB_ENT(90,  6,  0),
143 	RATETAB_ENT(120, 7,  0),
144 	RATETAB_ENT(180, 8,  0),
145 	RATETAB_ENT(240, 9,  0),
146 	RATETAB_ENT(360, 10, 0),
147 	RATETAB_ENT(480, 11, 0),
148 	RATETAB_ENT(540, 12, 0),
149 };
150 
151 struct p2p_mgmt_data {
152 	int size;
153 	u8 *buff;
154 };
155 
156 static u8 wlan_channel = INVALID_CHANNEL;
157 static u8 curr_channel;
158 static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
159 static u8 p2p_local_random = 0x01;
160 static u8 p2p_recv_random;
161 static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
162 static bool wilc_ie;
163 
164 static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
165 	.channels = ieee80211_2ghz_channels,
166 	.n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
167 	.bitrates = ieee80211_bitrates,
168 	.n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
169 };
170 
171 
172 struct add_key_params {
173 	u8 key_idx;
174 	bool pairwise;
175 	u8 *mac_addr;
176 };
177 static struct add_key_params g_add_gtk_key_params;
178 static struct wilc_wfi_key g_key_gtk_params;
179 static struct add_key_params g_add_ptk_key_params;
180 static struct wilc_wfi_key g_key_ptk_params;
181 static struct wilc_wfi_wep_key g_key_wep_params;
182 static bool g_ptk_keys_saved;
183 static bool g_gtk_keys_saved;
184 static bool g_wep_keys_saved;
185 
186 #define AGING_TIME	(9 * 1000)
187 #define during_ip_time	15000
188 
clear_shadow_scan(void)189 static void clear_shadow_scan(void)
190 {
191 	int i;
192 
193 	if (op_ifcs == 0) {
194 		del_timer_sync(&hAgingTimer);
195 
196 		for (i = 0; i < last_scanned_cnt; i++) {
197 			if (last_scanned_shadow[last_scanned_cnt].ies) {
198 				kfree(last_scanned_shadow[i].ies);
199 				last_scanned_shadow[last_scanned_cnt].ies = NULL;
200 			}
201 
202 			kfree(last_scanned_shadow[i].join_params);
203 			last_scanned_shadow[i].join_params = NULL;
204 		}
205 		last_scanned_cnt = 0;
206 	}
207 }
208 
get_rssi_avg(struct network_info * network_info)209 static u32 get_rssi_avg(struct network_info *network_info)
210 {
211 	u8 i;
212 	int rssi_v = 0;
213 	u8 num_rssi = (network_info->str_rssi.u8Full) ?
214 		       NUM_RSSI : (network_info->str_rssi.u8Index);
215 
216 	for (i = 0; i < num_rssi; i++)
217 		rssi_v += network_info->str_rssi.as8RSSI[i];
218 
219 	rssi_v /= num_rssi;
220 	return rssi_v;
221 }
222 
refresh_scan(void * user_void,u8 all,bool direct_scan)223 static void refresh_scan(void *user_void, u8 all, bool direct_scan)
224 {
225 	struct wilc_priv *priv;
226 	struct wiphy *wiphy;
227 	struct cfg80211_bss *bss = NULL;
228 	int i;
229 	int rssi = 0;
230 
231 	priv = user_void;
232 	wiphy = priv->dev->ieee80211_ptr->wiphy;
233 
234 	for (i = 0; i < last_scanned_cnt; i++) {
235 		struct network_info *network_info;
236 
237 		network_info = &last_scanned_shadow[i];
238 
239 		if (!network_info->found || all) {
240 			s32 freq;
241 			struct ieee80211_channel *channel;
242 
243 			if (network_info) {
244 				freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ);
245 				channel = ieee80211_get_channel(wiphy, freq);
246 
247 				rssi = get_rssi_avg(network_info);
248 				if (memcmp("DIRECT-", network_info->ssid, 7) ||
249 				    direct_scan) {
250 					bss = cfg80211_inform_bss(wiphy,
251 								  channel,
252 								  CFG80211_BSS_FTYPE_UNKNOWN,
253 								  network_info->bssid,
254 								  network_info->tsf_hi,
255 								  network_info->cap_info,
256 								  network_info->beacon_period,
257 								  (const u8 *)network_info->ies,
258 								  (size_t)network_info->ies_len,
259 								  (s32)rssi * 100,
260 								  GFP_KERNEL);
261 					cfg80211_put_bss(wiphy, bss);
262 				}
263 			}
264 		}
265 	}
266 }
267 
reset_shadow_found(void)268 static void reset_shadow_found(void)
269 {
270 	int i;
271 
272 	for (i = 0; i < last_scanned_cnt; i++)
273 		last_scanned_shadow[i].found = 0;
274 }
275 
update_scan_time(void)276 static void update_scan_time(void)
277 {
278 	int i;
279 
280 	for (i = 0; i < last_scanned_cnt; i++)
281 		last_scanned_shadow[i].time_scan = jiffies;
282 }
283 
remove_network_from_shadow(unsigned long arg)284 static void remove_network_from_shadow(unsigned long arg)
285 {
286 	unsigned long now = jiffies;
287 	int i, j;
288 
289 
290 	for (i = 0; i < last_scanned_cnt; i++) {
291 		if (time_after(now, last_scanned_shadow[i].time_scan +
292 			       (unsigned long)(SCAN_RESULT_EXPIRE))) {
293 			kfree(last_scanned_shadow[i].ies);
294 			last_scanned_shadow[i].ies = NULL;
295 
296 			kfree(last_scanned_shadow[i].join_params);
297 
298 			for (j = i; (j < last_scanned_cnt - 1); j++)
299 				last_scanned_shadow[j] = last_scanned_shadow[j + 1];
300 
301 			last_scanned_cnt--;
302 		}
303 	}
304 
305 	if (last_scanned_cnt != 0) {
306 		hAgingTimer.data = arg;
307 		mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
308 	}
309 }
310 
clear_duringIP(unsigned long arg)311 static void clear_duringIP(unsigned long arg)
312 {
313 	wilc_optaining_ip = false;
314 }
315 
is_network_in_shadow(struct network_info * pstrNetworkInfo,void * user_void)316 static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
317 				void *user_void)
318 {
319 	int state = -1;
320 	int i;
321 
322 	if (last_scanned_cnt == 0) {
323 		hAgingTimer.data = (unsigned long)user_void;
324 		mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
325 		state = -1;
326 	} else {
327 		for (i = 0; i < last_scanned_cnt; i++) {
328 			if (memcmp(last_scanned_shadow[i].bssid,
329 				   pstrNetworkInfo->bssid, 6) == 0) {
330 				state = i;
331 				break;
332 			}
333 		}
334 	}
335 	return state;
336 }
337 
add_network_to_shadow(struct network_info * pstrNetworkInfo,void * user_void,void * pJoinParams)338 static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
339 				  void *user_void, void *pJoinParams)
340 {
341 	int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
342 	u32 ap_index = 0;
343 	u8 rssi_index = 0;
344 
345 	if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
346 		return;
347 
348 	if (ap_found == -1) {
349 		ap_index = last_scanned_cnt;
350 		last_scanned_cnt++;
351 	} else {
352 		ap_index = ap_found;
353 	}
354 	rssi_index = last_scanned_shadow[ap_index].str_rssi.u8Index;
355 	last_scanned_shadow[ap_index].str_rssi.as8RSSI[rssi_index++] = pstrNetworkInfo->rssi;
356 	if (rssi_index == NUM_RSSI) {
357 		rssi_index = 0;
358 		last_scanned_shadow[ap_index].str_rssi.u8Full = 1;
359 	}
360 	last_scanned_shadow[ap_index].str_rssi.u8Index = rssi_index;
361 	last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
362 	last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
363 	last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
364 	memcpy(last_scanned_shadow[ap_index].ssid,
365 	       pstrNetworkInfo->ssid, pstrNetworkInfo->ssid_len);
366 	memcpy(last_scanned_shadow[ap_index].bssid,
367 	       pstrNetworkInfo->bssid, ETH_ALEN);
368 	last_scanned_shadow[ap_index].beacon_period = pstrNetworkInfo->beacon_period;
369 	last_scanned_shadow[ap_index].dtim_period = pstrNetworkInfo->dtim_period;
370 	last_scanned_shadow[ap_index].ch = pstrNetworkInfo->ch;
371 	last_scanned_shadow[ap_index].ies_len = pstrNetworkInfo->ies_len;
372 	last_scanned_shadow[ap_index].tsf_hi = pstrNetworkInfo->tsf_hi;
373 	if (ap_found != -1)
374 		kfree(last_scanned_shadow[ap_index].ies);
375 	last_scanned_shadow[ap_index].ies = kmalloc(pstrNetworkInfo->ies_len,
376 						    GFP_KERNEL);
377 	memcpy(last_scanned_shadow[ap_index].ies,
378 	       pstrNetworkInfo->ies, pstrNetworkInfo->ies_len);
379 	last_scanned_shadow[ap_index].time_scan = jiffies;
380 	last_scanned_shadow[ap_index].time_scan_cached = jiffies;
381 	last_scanned_shadow[ap_index].found = 1;
382 	if (ap_found != -1)
383 		kfree(last_scanned_shadow[ap_index].join_params);
384 	last_scanned_shadow[ap_index].join_params = pJoinParams;
385 }
386 
CfgScanResult(enum scan_event scan_event,struct network_info * network_info,void * user_void,void * join_params)387 static void CfgScanResult(enum scan_event scan_event,
388 			  struct network_info *network_info,
389 			  void *user_void,
390 			  void *join_params)
391 {
392 	struct wilc_priv *priv;
393 	struct wiphy *wiphy;
394 	s32 s32Freq;
395 	struct ieee80211_channel *channel;
396 	struct cfg80211_bss *bss = NULL;
397 
398 	priv = user_void;
399 	if (priv->bCfgScanning) {
400 		if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
401 			wiphy = priv->dev->ieee80211_ptr->wiphy;
402 
403 			if (!wiphy)
404 				return;
405 
406 			if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
407 			    (((s32)network_info->rssi * 100) < 0 ||
408 			    ((s32)network_info->rssi * 100) > 100))
409 				return;
410 
411 			if (network_info) {
412 				s32Freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ);
413 				channel = ieee80211_get_channel(wiphy, s32Freq);
414 
415 				if (!channel)
416 					return;
417 
418 				if (network_info->new_network) {
419 					if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
420 						priv->u32RcvdChCount++;
421 
422 						add_network_to_shadow(network_info, priv, join_params);
423 
424 						if (!(memcmp("DIRECT-", network_info->ssid, 7))) {
425 							bss = cfg80211_inform_bss(wiphy,
426 										  channel,
427 										  CFG80211_BSS_FTYPE_UNKNOWN,
428 										  network_info->bssid,
429 										  network_info->tsf_hi,
430 										  network_info->cap_info,
431 										  network_info->beacon_period,
432 										  (const u8 *)network_info->ies,
433 										  (size_t)network_info->ies_len,
434 										  (s32)network_info->rssi * 100,
435 										  GFP_KERNEL);
436 							cfg80211_put_bss(wiphy, bss);
437 						}
438 					}
439 				} else {
440 					u32 i;
441 
442 					for (i = 0; i < priv->u32RcvdChCount; i++) {
443 						if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) {
444 							last_scanned_shadow[i].rssi = network_info->rssi;
445 							last_scanned_shadow[i].time_scan = jiffies;
446 							break;
447 						}
448 					}
449 				}
450 			}
451 		} else if (scan_event == SCAN_EVENT_DONE) {
452 			refresh_scan(priv, 1, false);
453 
454 			mutex_lock(&priv->scan_req_lock);
455 
456 			if (priv->pstrScanReq) {
457 				struct cfg80211_scan_info info = {
458 					.aborted = false,
459 				};
460 
461 				cfg80211_scan_done(priv->pstrScanReq, &info);
462 				priv->u32RcvdChCount = 0;
463 				priv->bCfgScanning = false;
464 				priv->pstrScanReq = NULL;
465 			}
466 			mutex_unlock(&priv->scan_req_lock);
467 		} else if (scan_event == SCAN_EVENT_ABORTED) {
468 			mutex_lock(&priv->scan_req_lock);
469 
470 			if (priv->pstrScanReq) {
471 				struct cfg80211_scan_info info = {
472 					.aborted = false,
473 				};
474 
475 				update_scan_time();
476 				refresh_scan(priv, 1, false);
477 
478 				cfg80211_scan_done(priv->pstrScanReq, &info);
479 				priv->bCfgScanning = false;
480 				priv->pstrScanReq = NULL;
481 			}
482 			mutex_unlock(&priv->scan_req_lock);
483 		}
484 	}
485 }
486 
487 int wilc_connecting;
488 
CfgConnectResult(enum conn_event enuConnDisconnEvent,struct connect_info * pstrConnectInfo,u8 u8MacStatus,struct disconnect_info * pstrDisconnectNotifInfo,void * pUserVoid)489 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
490 			     struct connect_info *pstrConnectInfo,
491 			     u8 u8MacStatus,
492 			     struct disconnect_info *pstrDisconnectNotifInfo,
493 			     void *pUserVoid)
494 {
495 	struct wilc_priv *priv;
496 	struct net_device *dev;
497 	struct host_if_drv *pstrWFIDrv;
498 	u8 NullBssid[ETH_ALEN] = {0};
499 	struct wilc *wl;
500 	struct wilc_vif *vif;
501 
502 	wilc_connecting = 0;
503 
504 	priv = pUserVoid;
505 	dev = priv->dev;
506 	vif = netdev_priv(dev);
507 	wl = vif->wilc;
508 	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
509 
510 	if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
511 		u16 u16ConnectStatus;
512 
513 		u16ConnectStatus = pstrConnectInfo->status;
514 
515 		if ((u8MacStatus == MAC_DISCONNECTED) &&
516 		    (pstrConnectInfo->status == SUCCESSFUL_STATUSCODE)) {
517 			u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
518 			wilc_wlan_set_bssid(priv->dev, NullBssid,
519 					    STATION_MODE);
520 			eth_zero_addr(wilc_connected_ssid);
521 
522 			if (!pstrWFIDrv->p2p_connect)
523 				wlan_channel = INVALID_CHANNEL;
524 
525 			netdev_err(dev, "Unspecified failure\n");
526 		}
527 
528 		if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
529 			bool bNeedScanRefresh = false;
530 			u32 i;
531 
532 			memcpy(priv->au8AssociatedBss, pstrConnectInfo->bssid, ETH_ALEN);
533 
534 
535 			for (i = 0; i < last_scanned_cnt; i++) {
536 				if (memcmp(last_scanned_shadow[i].bssid,
537 					   pstrConnectInfo->bssid,
538 					   ETH_ALEN) == 0) {
539 					unsigned long now = jiffies;
540 
541 					if (time_after(now,
542 						       last_scanned_shadow[i].time_scan_cached +
543 						       (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
544 						bNeedScanRefresh = true;
545 
546 					break;
547 				}
548 			}
549 
550 			if (bNeedScanRefresh)
551 				refresh_scan(priv, 1, true);
552 		}
553 
554 		cfg80211_connect_result(dev, pstrConnectInfo->bssid,
555 					pstrConnectInfo->req_ies, pstrConnectInfo->req_ies_len,
556 					pstrConnectInfo->resp_ies, pstrConnectInfo->resp_ies_len,
557 					u16ConnectStatus, GFP_KERNEL);
558 	} else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF)    {
559 		wilc_optaining_ip = false;
560 		p2p_local_random = 0x01;
561 		p2p_recv_random = 0x00;
562 		wilc_ie = false;
563 		eth_zero_addr(priv->au8AssociatedBss);
564 		wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
565 		eth_zero_addr(wilc_connected_ssid);
566 
567 		if (!pstrWFIDrv->p2p_connect)
568 			wlan_channel = INVALID_CHANNEL;
569 		if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
570 			pstrDisconnectNotifInfo->reason = 3;
571 		else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
572 			pstrDisconnectNotifInfo->reason = 1;
573 
574 		cfg80211_disconnected(dev, pstrDisconnectNotifInfo->reason, pstrDisconnectNotifInfo->ie,
575 				      pstrDisconnectNotifInfo->ie_len, false,
576 				      GFP_KERNEL);
577 	}
578 }
579 
set_channel(struct wiphy * wiphy,struct cfg80211_chan_def * chandef)580 static int set_channel(struct wiphy *wiphy,
581 		       struct cfg80211_chan_def *chandef)
582 {
583 	u32 channelnum = 0;
584 	struct wilc_priv *priv;
585 	int result = 0;
586 	struct wilc_vif *vif;
587 
588 	priv = wiphy_priv(wiphy);
589 	vif = netdev_priv(priv->dev);
590 
591 	channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
592 
593 	curr_channel = channelnum;
594 	result = wilc_set_mac_chnl_num(vif, channelnum);
595 
596 	if (result != 0)
597 		netdev_err(priv->dev, "Error in setting channel\n");
598 
599 	return result;
600 }
601 
scan(struct wiphy * wiphy,struct cfg80211_scan_request * request)602 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
603 {
604 	struct wilc_priv *priv;
605 	u32 i;
606 	s32 s32Error = 0;
607 	u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
608 	struct hidden_network strHiddenNetwork;
609 	struct wilc_vif *vif;
610 
611 	priv = wiphy_priv(wiphy);
612 	vif = netdev_priv(priv->dev);
613 
614 	priv->pstrScanReq = request;
615 
616 	priv->u32RcvdChCount = 0;
617 
618 	reset_shadow_found();
619 
620 	priv->bCfgScanning = true;
621 	if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
622 		for (i = 0; i < request->n_channels; i++)
623 			au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
624 
625 		if (request->n_ssids >= 1) {
626 			strHiddenNetwork.net_info =
627 				kmalloc_array(request->n_ssids,
628 					      sizeof(struct hidden_network),
629 					      GFP_KERNEL);
630 			if (!strHiddenNetwork.net_info)
631 				return -ENOMEM;
632 			strHiddenNetwork.n_ssids = request->n_ssids;
633 
634 
635 			for (i = 0; i < request->n_ssids; i++) {
636 				if (request->ssids[i].ssid_len != 0) {
637 					strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
638 					memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
639 					strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
640 				} else {
641 					strHiddenNetwork.n_ssids -= 1;
642 				}
643 			}
644 			s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
645 					     au8ScanChanList,
646 					     request->n_channels,
647 					     (const u8 *)request->ie,
648 					     request->ie_len, CfgScanResult,
649 					     (void *)priv, &strHiddenNetwork);
650 		} else {
651 			s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
652 					     au8ScanChanList,
653 					     request->n_channels,
654 					     (const u8 *)request->ie,
655 					     request->ie_len, CfgScanResult,
656 					     (void *)priv, NULL);
657 		}
658 	} else {
659 		netdev_err(priv->dev, "Requested scanned channels over\n");
660 	}
661 
662 	if (s32Error != 0)
663 		s32Error = -EBUSY;
664 
665 	return s32Error;
666 }
667 
connect(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_connect_params * sme)668 static int connect(struct wiphy *wiphy, struct net_device *dev,
669 		   struct cfg80211_connect_params *sme)
670 {
671 	s32 s32Error = 0;
672 	u32 i;
673 	u8 u8security = NO_ENCRYPT;
674 	enum AUTHTYPE tenuAuth_type = ANY;
675 
676 	struct wilc_priv *priv;
677 	struct host_if_drv *pstrWFIDrv;
678 	struct network_info *pstrNetworkInfo = NULL;
679 	struct wilc_vif *vif;
680 
681 	wilc_connecting = 1;
682 	priv = wiphy_priv(wiphy);
683 	vif = netdev_priv(priv->dev);
684 	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
685 
686 	if (!(strncmp(sme->ssid, "DIRECT-", 7)))
687 		pstrWFIDrv->p2p_connect = 1;
688 	else
689 		pstrWFIDrv->p2p_connect = 0;
690 
691 	for (i = 0; i < last_scanned_cnt; i++) {
692 		if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
693 		    memcmp(last_scanned_shadow[i].ssid,
694 			   sme->ssid,
695 			   sme->ssid_len) == 0) {
696 			if (!sme->bssid)
697 				break;
698 			else
699 				if (memcmp(last_scanned_shadow[i].bssid,
700 					   sme->bssid,
701 					   ETH_ALEN) == 0)
702 					break;
703 		}
704 	}
705 
706 	if (i < last_scanned_cnt) {
707 		pstrNetworkInfo = &last_scanned_shadow[i];
708 	} else {
709 		s32Error = -ENOENT;
710 		wilc_connecting = 0;
711 		return s32Error;
712 	}
713 
714 	memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
715 	memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
716 
717 	if (sme->crypto.cipher_group != NO_ENCRYPT) {
718 		if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
719 			u8security = ENCRYPT_ENABLED | WEP;
720 
721 			priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
722 			memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
723 
724 			g_key_wep_params.key_len = sme->key_len;
725 			g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
726 			memcpy(g_key_wep_params.key, sme->key, sme->key_len);
727 			g_key_wep_params.key_idx = sme->key_idx;
728 			g_wep_keys_saved = true;
729 
730 			wilc_set_wep_default_keyid(vif, sme->key_idx);
731 			wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
732 						 sme->key_idx);
733 		} else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)   {
734 			u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
735 
736 			priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
737 			memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
738 
739 			g_key_wep_params.key_len = sme->key_len;
740 			g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
741 			memcpy(g_key_wep_params.key, sme->key, sme->key_len);
742 			g_key_wep_params.key_idx = sme->key_idx;
743 			g_wep_keys_saved = true;
744 
745 			wilc_set_wep_default_keyid(vif, sme->key_idx);
746 			wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
747 						 sme->key_idx);
748 		} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)   {
749 			if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
750 				u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
751 			else
752 				u8security = ENCRYPT_ENABLED | WPA2 | AES;
753 		} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)   {
754 			if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
755 				u8security = ENCRYPT_ENABLED | WPA | TKIP;
756 			else
757 				u8security = ENCRYPT_ENABLED | WPA | AES;
758 		} else {
759 			s32Error = -ENOTSUPP;
760 			netdev_err(dev, "Not supported cipher\n");
761 			wilc_connecting = 0;
762 			return s32Error;
763 		}
764 	}
765 
766 	if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
767 	    || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
768 		for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
769 			if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP)
770 				u8security = u8security | TKIP;
771 			else
772 				u8security = u8security | AES;
773 		}
774 	}
775 
776 	switch (sme->auth_type)	{
777 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
778 		tenuAuth_type = OPEN_SYSTEM;
779 		break;
780 
781 	case NL80211_AUTHTYPE_SHARED_KEY:
782 		tenuAuth_type = SHARED_KEY;
783 		break;
784 
785 	default:
786 		break;
787 	}
788 
789 	if (sme->crypto.n_akm_suites) {
790 		switch (sme->crypto.akm_suites[0]) {
791 		case WLAN_AKM_SUITE_8021X:
792 			tenuAuth_type = IEEE8021;
793 			break;
794 
795 		default:
796 			break;
797 		}
798 	}
799 
800 	curr_channel = pstrNetworkInfo->ch;
801 
802 	if (!pstrWFIDrv->p2p_connect)
803 		wlan_channel = pstrNetworkInfo->ch;
804 
805 	wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
806 
807 	s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
808 				     sme->ssid_len, sme->ie, sme->ie_len,
809 				     CfgConnectResult, (void *)priv,
810 				     u8security, tenuAuth_type,
811 				     pstrNetworkInfo->ch,
812 				     pstrNetworkInfo->join_params);
813 	if (s32Error != 0) {
814 		netdev_err(dev, "wilc_set_join_req(): Error\n");
815 		s32Error = -ENOENT;
816 		wilc_connecting = 0;
817 		return s32Error;
818 	}
819 
820 	return s32Error;
821 }
822 
disconnect(struct wiphy * wiphy,struct net_device * dev,u16 reason_code)823 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
824 {
825 	s32 s32Error = 0;
826 	struct wilc_priv *priv;
827 	struct host_if_drv *pstrWFIDrv;
828 	struct wilc_vif *vif;
829 	struct wilc *wilc;
830 	u8 NullBssid[ETH_ALEN] = {0};
831 
832 	wilc_connecting = 0;
833 	priv = wiphy_priv(wiphy);
834 	vif = netdev_priv(priv->dev);
835 	wilc = vif->wilc;
836 
837 	if (!wilc)
838 		return -EIO;
839 
840 	if (wilc->close) {
841 		/* already disconnected done */
842 		cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
843 		return 0;
844 	}
845 
846 	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
847 	if (!pstrWFIDrv->p2p_connect)
848 		wlan_channel = INVALID_CHANNEL;
849 	wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
850 
851 	p2p_local_random = 0x01;
852 	p2p_recv_random = 0x00;
853 	wilc_ie = false;
854 	pstrWFIDrv->p2p_timeout = 0;
855 
856 	s32Error = wilc_disconnect(vif, reason_code);
857 	if (s32Error != 0) {
858 		netdev_err(priv->dev, "Error in disconnecting\n");
859 		s32Error = -EINVAL;
860 	}
861 
862 	return s32Error;
863 }
864 
add_key(struct wiphy * wiphy,struct net_device * netdev,u8 key_index,bool pairwise,const u8 * mac_addr,struct key_params * params)865 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
866 		   bool pairwise,
867 		   const u8 *mac_addr, struct key_params *params)
868 
869 {
870 	s32 s32Error = 0, KeyLen = params->key_len;
871 	struct wilc_priv *priv;
872 	const u8 *pu8RxMic = NULL;
873 	const u8 *pu8TxMic = NULL;
874 	u8 u8mode = NO_ENCRYPT;
875 	u8 u8gmode = NO_ENCRYPT;
876 	u8 u8pmode = NO_ENCRYPT;
877 	enum AUTHTYPE tenuAuth_type = ANY;
878 	struct wilc *wl;
879 	struct wilc_vif *vif;
880 
881 	priv = wiphy_priv(wiphy);
882 	vif = netdev_priv(netdev);
883 	wl = vif->wilc;
884 
885 	switch (params->cipher)	{
886 	case WLAN_CIPHER_SUITE_WEP40:
887 	case WLAN_CIPHER_SUITE_WEP104:
888 		if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
889 			priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
890 			memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
891 
892 			tenuAuth_type = OPEN_SYSTEM;
893 
894 			if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
895 				u8mode = ENCRYPT_ENABLED | WEP;
896 			else
897 				u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
898 
899 			wilc_add_wep_key_bss_ap(vif, params->key,
900 						params->key_len, key_index,
901 						u8mode, tenuAuth_type);
902 			break;
903 		}
904 		if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
905 			priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
906 			memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
907 
908 			wilc_add_wep_key_bss_sta(vif, params->key,
909 						 params->key_len, key_index);
910 		}
911 
912 		break;
913 
914 	case WLAN_CIPHER_SUITE_TKIP:
915 	case WLAN_CIPHER_SUITE_CCMP:
916 		if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
917 			if (!priv->wilc_gtk[key_index]) {
918 				priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
919 				priv->wilc_gtk[key_index]->key = NULL;
920 				priv->wilc_gtk[key_index]->seq = NULL;
921 			}
922 			if (!priv->wilc_ptk[key_index]) {
923 				priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
924 				priv->wilc_ptk[key_index]->key = NULL;
925 				priv->wilc_ptk[key_index]->seq = NULL;
926 			}
927 
928 
929 
930 			if (!pairwise) {
931 				if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
932 					u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
933 				else
934 					u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
935 
936 				priv->wilc_groupkey = u8gmode;
937 
938 				if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
939 					pu8TxMic = params->key + 24;
940 					pu8RxMic = params->key + 16;
941 					KeyLen = params->key_len - 16;
942 				}
943 				kfree(priv->wilc_gtk[key_index]->key);
944 
945 				priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
946 				memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
947 				kfree(priv->wilc_gtk[key_index]->seq);
948 
949 				if ((params->seq_len) > 0) {
950 					priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
951 					memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
952 				}
953 
954 				priv->wilc_gtk[key_index]->cipher = params->cipher;
955 				priv->wilc_gtk[key_index]->key_len = params->key_len;
956 				priv->wilc_gtk[key_index]->seq_len = params->seq_len;
957 
958 				wilc_add_rx_gtk(vif, params->key, KeyLen,
959 						key_index, params->seq_len,
960 						params->seq, pu8RxMic,
961 						pu8TxMic, AP_MODE, u8gmode);
962 
963 			} else {
964 				if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
965 					u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
966 				else
967 					u8pmode = priv->wilc_groupkey | AES;
968 
969 
970 				if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
971 					pu8TxMic = params->key + 24;
972 					pu8RxMic = params->key + 16;
973 					KeyLen = params->key_len - 16;
974 				}
975 
976 				kfree(priv->wilc_ptk[key_index]->key);
977 
978 				priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
979 
980 				kfree(priv->wilc_ptk[key_index]->seq);
981 
982 				if ((params->seq_len) > 0)
983 					priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
984 
985 				memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
986 
987 				if ((params->seq_len) > 0)
988 					memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
989 
990 				priv->wilc_ptk[key_index]->cipher = params->cipher;
991 				priv->wilc_ptk[key_index]->key_len = params->key_len;
992 				priv->wilc_ptk[key_index]->seq_len = params->seq_len;
993 
994 				wilc_add_ptk(vif, params->key, KeyLen,
995 					     mac_addr, pu8RxMic, pu8TxMic,
996 					     AP_MODE, u8pmode, key_index);
997 			}
998 			break;
999 		}
1000 
1001 		{
1002 			u8mode = 0;
1003 			if (!pairwise) {
1004 				if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1005 					pu8RxMic = params->key + 24;
1006 					pu8TxMic = params->key + 16;
1007 					KeyLen = params->key_len - 16;
1008 				}
1009 
1010 				if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
1011 					g_add_gtk_key_params.key_idx = key_index;
1012 					g_add_gtk_key_params.pairwise = pairwise;
1013 					if (!mac_addr) {
1014 						g_add_gtk_key_params.mac_addr = NULL;
1015 					} else {
1016 						g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1017 						memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1018 					}
1019 					g_key_gtk_params.key_len = params->key_len;
1020 					g_key_gtk_params.seq_len = params->seq_len;
1021 					g_key_gtk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
1022 					memcpy(g_key_gtk_params.key, params->key, params->key_len);
1023 					if (params->seq_len > 0) {
1024 						g_key_gtk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
1025 						memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1026 					}
1027 					g_key_gtk_params.cipher = params->cipher;
1028 					g_gtk_keys_saved = true;
1029 				}
1030 
1031 				wilc_add_rx_gtk(vif, params->key, KeyLen,
1032 						key_index, params->seq_len,
1033 						params->seq, pu8RxMic,
1034 						pu8TxMic, STATION_MODE,
1035 						u8mode);
1036 			} else {
1037 				if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1038 					pu8RxMic = params->key + 24;
1039 					pu8TxMic = params->key + 16;
1040 					KeyLen = params->key_len - 16;
1041 				}
1042 
1043 				if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1044 					g_add_ptk_key_params.key_idx = key_index;
1045 					g_add_ptk_key_params.pairwise = pairwise;
1046 					if (!mac_addr) {
1047 						g_add_ptk_key_params.mac_addr = NULL;
1048 					} else {
1049 						g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1050 						memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1051 					}
1052 					g_key_ptk_params.key_len = params->key_len;
1053 					g_key_ptk_params.seq_len = params->seq_len;
1054 					g_key_ptk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
1055 					memcpy(g_key_ptk_params.key, params->key, params->key_len);
1056 					if (params->seq_len > 0) {
1057 						g_key_ptk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
1058 						memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1059 					}
1060 					g_key_ptk_params.cipher = params->cipher;
1061 					g_ptk_keys_saved = true;
1062 				}
1063 
1064 				wilc_add_ptk(vif, params->key, KeyLen,
1065 					     mac_addr, pu8RxMic, pu8TxMic,
1066 					     STATION_MODE, u8mode, key_index);
1067 			}
1068 		}
1069 		break;
1070 
1071 	default:
1072 		netdev_err(netdev, "Not supported cipher\n");
1073 		s32Error = -ENOTSUPP;
1074 	}
1075 
1076 	return s32Error;
1077 }
1078 
del_key(struct wiphy * wiphy,struct net_device * netdev,u8 key_index,bool pairwise,const u8 * mac_addr)1079 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1080 		   u8 key_index,
1081 		   bool pairwise,
1082 		   const u8 *mac_addr)
1083 {
1084 	struct wilc_priv *priv;
1085 	struct wilc *wl;
1086 	struct wilc_vif *vif;
1087 
1088 	priv = wiphy_priv(wiphy);
1089 	vif = netdev_priv(netdev);
1090 	wl = vif->wilc;
1091 
1092 	if (netdev == wl->vif[0]->ndev) {
1093 		g_ptk_keys_saved = false;
1094 		g_gtk_keys_saved = false;
1095 		g_wep_keys_saved = false;
1096 
1097 		kfree(g_key_wep_params.key);
1098 		g_key_wep_params.key = NULL;
1099 
1100 		if ((priv->wilc_gtk[key_index]) != NULL) {
1101 			kfree(priv->wilc_gtk[key_index]->key);
1102 			priv->wilc_gtk[key_index]->key = NULL;
1103 			kfree(priv->wilc_gtk[key_index]->seq);
1104 			priv->wilc_gtk[key_index]->seq = NULL;
1105 
1106 			kfree(priv->wilc_gtk[key_index]);
1107 			priv->wilc_gtk[key_index] = NULL;
1108 		}
1109 
1110 		if ((priv->wilc_ptk[key_index]) != NULL) {
1111 			kfree(priv->wilc_ptk[key_index]->key);
1112 			priv->wilc_ptk[key_index]->key = NULL;
1113 			kfree(priv->wilc_ptk[key_index]->seq);
1114 			priv->wilc_ptk[key_index]->seq = NULL;
1115 			kfree(priv->wilc_ptk[key_index]);
1116 			priv->wilc_ptk[key_index] = NULL;
1117 		}
1118 
1119 		kfree(g_key_ptk_params.key);
1120 		g_key_ptk_params.key = NULL;
1121 		kfree(g_key_ptk_params.seq);
1122 		g_key_ptk_params.seq = NULL;
1123 
1124 		kfree(g_key_gtk_params.key);
1125 		g_key_gtk_params.key = NULL;
1126 		kfree(g_key_gtk_params.seq);
1127 		g_key_gtk_params.seq = NULL;
1128 
1129 	}
1130 
1131 	if (key_index >= 0 && key_index <= 3) {
1132 		if (priv->WILC_WFI_wep_key_len[key_index]) {
1133 			memset(priv->WILC_WFI_wep_key[key_index], 0,
1134 			       priv->WILC_WFI_wep_key_len[key_index]);
1135 			priv->WILC_WFI_wep_key_len[key_index] = 0;
1136 			wilc_remove_wep_key(vif, key_index);
1137 		}
1138 	} else {
1139 		wilc_remove_key(priv->hif_drv, mac_addr);
1140 	}
1141 
1142 	return 0;
1143 }
1144 
get_key(struct wiphy * wiphy,struct net_device * netdev,u8 key_index,bool pairwise,const u8 * mac_addr,void * cookie,void (* callback)(void * cookie,struct key_params *))1145 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1146 		   bool pairwise,
1147 		   const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1148 {
1149 	struct wilc_priv *priv;
1150 	struct  key_params key_params;
1151 
1152 	priv = wiphy_priv(wiphy);
1153 
1154 
1155 	if (!pairwise) {
1156 		key_params.key = priv->wilc_gtk[key_index]->key;
1157 		key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1158 		key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1159 		key_params.seq = priv->wilc_gtk[key_index]->seq;
1160 		key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1161 	} else {
1162 		key_params.key = priv->wilc_ptk[key_index]->key;
1163 		key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1164 		key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1165 		key_params.seq = priv->wilc_ptk[key_index]->seq;
1166 		key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1167 	}
1168 
1169 	callback(cookie, &key_params);
1170 
1171 	return 0;
1172 }
1173 
set_default_key(struct wiphy * wiphy,struct net_device * netdev,u8 key_index,bool unicast,bool multicast)1174 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1175 			   bool unicast, bool multicast)
1176 {
1177 	struct wilc_priv *priv;
1178 	struct wilc_vif *vif;
1179 
1180 	priv = wiphy_priv(wiphy);
1181 	vif = netdev_priv(priv->dev);
1182 
1183 	wilc_set_wep_default_keyid(vif, key_index);
1184 
1185 	return 0;
1186 }
1187 
get_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_info * sinfo)1188 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1189 		       const u8 *mac, struct station_info *sinfo)
1190 {
1191 	struct wilc_priv *priv;
1192 	struct wilc_vif *vif;
1193 	u32 i = 0;
1194 	u32 associatedsta = ~0;
1195 	u32 inactive_time = 0;
1196 	priv = wiphy_priv(wiphy);
1197 	vif = netdev_priv(dev);
1198 
1199 	if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1200 		for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1201 			if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1202 				associatedsta = i;
1203 				break;
1204 			}
1205 		}
1206 
1207 		if (associatedsta == ~0) {
1208 			netdev_err(dev, "sta required is not associated\n");
1209 			return -ENOENT;
1210 		}
1211 
1212 		sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1213 
1214 		wilc_get_inactive_time(vif, mac, &inactive_time);
1215 		sinfo->inactive_time = 1000 * inactive_time;
1216 	}
1217 
1218 	if (vif->iftype == STATION_MODE) {
1219 		struct rf_info strStatistics;
1220 
1221 		wilc_get_statistics(vif, &strStatistics);
1222 
1223 		sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1224 						BIT(NL80211_STA_INFO_RX_PACKETS) |
1225 						BIT(NL80211_STA_INFO_TX_PACKETS) |
1226 						BIT(NL80211_STA_INFO_TX_FAILED) |
1227 						BIT(NL80211_STA_INFO_TX_BITRATE);
1228 
1229 		sinfo->signal = strStatistics.rssi;
1230 		sinfo->rx_packets = strStatistics.rx_cnt;
1231 		sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1232 		sinfo->tx_failed = strStatistics.tx_fail_cnt;
1233 		sinfo->txrate.legacy = strStatistics.link_speed * 10;
1234 
1235 		if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1236 		    (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1237 			wilc_enable_tcp_ack_filter(true);
1238 		else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1239 			wilc_enable_tcp_ack_filter(false);
1240 	}
1241 	return 0;
1242 }
1243 
change_bss(struct wiphy * wiphy,struct net_device * dev,struct bss_parameters * params)1244 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1245 		      struct bss_parameters *params)
1246 {
1247 	return 0;
1248 }
1249 
set_wiphy_params(struct wiphy * wiphy,u32 changed)1250 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1251 {
1252 	s32 s32Error = 0;
1253 	struct cfg_param_attr pstrCfgParamVal;
1254 	struct wilc_priv *priv;
1255 	struct wilc_vif *vif;
1256 
1257 	priv = wiphy_priv(wiphy);
1258 	vif = netdev_priv(priv->dev);
1259 
1260 	pstrCfgParamVal.flag = 0;
1261 
1262 	if (changed & WIPHY_PARAM_RETRY_SHORT) {
1263 		pstrCfgParamVal.flag  |= RETRY_SHORT;
1264 		pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1265 	}
1266 	if (changed & WIPHY_PARAM_RETRY_LONG) {
1267 		pstrCfgParamVal.flag |= RETRY_LONG;
1268 		pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1269 	}
1270 	if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1271 		pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1272 		pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1273 	}
1274 
1275 	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1276 		pstrCfgParamVal.flag |= RTS_THRESHOLD;
1277 		pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1278 	}
1279 
1280 	s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1281 	if (s32Error)
1282 		netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1283 
1284 	return s32Error;
1285 }
1286 
set_pmksa(struct wiphy * wiphy,struct net_device * netdev,struct cfg80211_pmksa * pmksa)1287 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1288 		     struct cfg80211_pmksa *pmksa)
1289 {
1290 	u32 i;
1291 	s32 s32Error = 0;
1292 	u8 flag = 0;
1293 	struct wilc_vif *vif;
1294 	struct wilc_priv *priv = wiphy_priv(wiphy);
1295 
1296 	vif = netdev_priv(priv->dev);
1297 
1298 
1299 	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
1300 		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1301 				 ETH_ALEN)) {
1302 			flag = PMKID_FOUND;
1303 			break;
1304 		}
1305 	}
1306 	if (i < WILC_MAX_NUM_PMKIDS) {
1307 		memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1308 			    ETH_ALEN);
1309 		memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1310 			    PMKID_LEN);
1311 		if (!(flag == PMKID_FOUND))
1312 			priv->pmkid_list.numpmkid++;
1313 	} else {
1314 		netdev_err(netdev, "Invalid PMKID index\n");
1315 		s32Error = -EINVAL;
1316 	}
1317 
1318 	if (!s32Error)
1319 		s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1320 
1321 	return s32Error;
1322 }
1323 
del_pmksa(struct wiphy * wiphy,struct net_device * netdev,struct cfg80211_pmksa * pmksa)1324 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1325 		     struct cfg80211_pmksa *pmksa)
1326 {
1327 	u32 i;
1328 	s32 s32Error = 0;
1329 
1330 	struct wilc_priv *priv = wiphy_priv(wiphy);
1331 
1332 	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
1333 		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1334 				 ETH_ALEN)) {
1335 			memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1336 			break;
1337 		}
1338 	}
1339 
1340 	if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1341 		for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1342 			memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1343 				    priv->pmkid_list.pmkidlist[i + 1].bssid,
1344 				    ETH_ALEN);
1345 			memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1346 				    priv->pmkid_list.pmkidlist[i].pmkid,
1347 				    PMKID_LEN);
1348 		}
1349 		priv->pmkid_list.numpmkid--;
1350 	} else {
1351 		s32Error = -EINVAL;
1352 	}
1353 
1354 	return s32Error;
1355 }
1356 
flush_pmksa(struct wiphy * wiphy,struct net_device * netdev)1357 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1358 {
1359 	struct wilc_priv *priv = wiphy_priv(wiphy);
1360 
1361 	memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1362 
1363 	return 0;
1364 }
1365 
WILC_WFI_CfgParseRxAction(u8 * buf,u32 len)1366 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1367 {
1368 	u32 index = 0;
1369 	u32 i = 0, j = 0;
1370 
1371 	u8 op_channel_attr_index = 0;
1372 	u8 channel_list_attr_index = 0;
1373 
1374 	while (index < len) {
1375 		if (buf[index] == GO_INTENT_ATTR_ID)
1376 			buf[index + 3] = (buf[index + 3]  & 0x01) | (0x00 << 1);
1377 
1378 		if (buf[index] ==  CHANLIST_ATTR_ID)
1379 			channel_list_attr_index = index;
1380 		else if (buf[index] ==  OPERCHAN_ATTR_ID)
1381 			op_channel_attr_index = index;
1382 		index += buf[index + 1] + 3;
1383 	}
1384 	if (wlan_channel != INVALID_CHANNEL) {
1385 		if (channel_list_attr_index) {
1386 			for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1387 				if (buf[i] == 0x51) {
1388 					for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1389 						buf[j] = wlan_channel;
1390 					break;
1391 				}
1392 			}
1393 		}
1394 
1395 		if (op_channel_attr_index) {
1396 			buf[op_channel_attr_index + 6] = 0x51;
1397 			buf[op_channel_attr_index + 7] = wlan_channel;
1398 		}
1399 	}
1400 }
1401 
WILC_WFI_CfgParseTxAction(u8 * buf,u32 len,bool bOperChan,u8 iftype)1402 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1403 {
1404 	u32 index = 0;
1405 	u32 i = 0, j = 0;
1406 
1407 	u8 op_channel_attr_index = 0;
1408 	u8 channel_list_attr_index = 0;
1409 
1410 	while (index < len) {
1411 		if (buf[index] == GO_INTENT_ATTR_ID) {
1412 			buf[index + 3] = (buf[index + 3]  & 0x01) | (0x0f << 1);
1413 
1414 			break;
1415 		}
1416 
1417 		if (buf[index] ==  CHANLIST_ATTR_ID)
1418 			channel_list_attr_index = index;
1419 		else if (buf[index] ==  OPERCHAN_ATTR_ID)
1420 			op_channel_attr_index = index;
1421 		index += buf[index + 1] + 3;
1422 	}
1423 	if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1424 		if (channel_list_attr_index) {
1425 			for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1426 				if (buf[i] == 0x51) {
1427 					for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1428 						buf[j] = wlan_channel;
1429 					break;
1430 				}
1431 			}
1432 		}
1433 
1434 		if (op_channel_attr_index) {
1435 			buf[op_channel_attr_index + 6] = 0x51;
1436 			buf[op_channel_attr_index + 7] = wlan_channel;
1437 		}
1438 	}
1439 }
1440 
WILC_WFI_p2p_rx(struct net_device * dev,u8 * buff,u32 size)1441 void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
1442 {
1443 	struct wilc_priv *priv;
1444 	u32 header, pkt_offset;
1445 	struct host_if_drv *pstrWFIDrv;
1446 	u32 i = 0;
1447 	s32 s32Freq;
1448 
1449 	priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1450 	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1451 
1452 	memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1453 
1454 	pkt_offset = GET_PKT_OFFSET(header);
1455 
1456 	if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1457 		if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1458 			cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1459 			return;
1460 		} else {
1461 			if (pkt_offset & IS_MGMT_STATUS_SUCCES)
1462 				cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1463 			else
1464 				cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1465 			return;
1466 		}
1467 	} else {
1468 		s32Freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ);
1469 
1470 		if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1471 			if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1472 				netdev_dbg(dev, "Receiving action wrong ch\n");
1473 				return;
1474 			}
1475 			if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1476 				switch (buff[ACTION_SUBTYPE_ID]) {
1477 				case GAS_INTIAL_REQ:
1478 					break;
1479 
1480 				case GAS_INTIAL_RSP:
1481 					break;
1482 
1483 				case PUBLIC_ACT_VENDORSPEC:
1484 					if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1485 						if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP))	{
1486 							if (!wilc_ie) {
1487 								for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++)	{
1488 									if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1489 										p2p_recv_random = buff[i + 6];
1490 										wilc_ie = true;
1491 										break;
1492 									}
1493 								}
1494 							}
1495 						}
1496 						if (p2p_local_random > p2p_recv_random)	{
1497 							if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1498 							      || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1499 								for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1500 									if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1501 										WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1502 										break;
1503 									}
1504 								}
1505 							}
1506 						} else {
1507 							netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1508 						}
1509 					}
1510 
1511 
1512 					if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie))	{
1513 						cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1514 						return;
1515 					}
1516 					break;
1517 
1518 				default:
1519 					netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1520 					break;
1521 				}
1522 			}
1523 		}
1524 
1525 		cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1526 	}
1527 }
1528 
WILC_WFI_mgmt_tx_complete(void * priv,int status)1529 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1530 {
1531 	struct p2p_mgmt_data *pv_data = priv;
1532 
1533 
1534 	kfree(pv_data->buff);
1535 	kfree(pv_data);
1536 }
1537 
WILC_WFI_RemainOnChannelReady(void * pUserVoid)1538 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1539 {
1540 	struct wilc_priv *priv;
1541 
1542 	priv = pUserVoid;
1543 
1544 	priv->bInP2PlistenState = true;
1545 
1546 	cfg80211_ready_on_channel(priv->wdev,
1547 				  priv->strRemainOnChanParams.u64ListenCookie,
1548 				  priv->strRemainOnChanParams.pstrListenChan,
1549 				  priv->strRemainOnChanParams.u32ListenDuration,
1550 				  GFP_KERNEL);
1551 }
1552 
WILC_WFI_RemainOnChannelExpired(void * pUserVoid,u32 u32SessionID)1553 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1554 {
1555 	struct wilc_priv *priv;
1556 
1557 	priv = pUserVoid;
1558 
1559 	if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1560 		priv->bInP2PlistenState = false;
1561 
1562 		cfg80211_remain_on_channel_expired(priv->wdev,
1563 						   priv->strRemainOnChanParams.u64ListenCookie,
1564 						   priv->strRemainOnChanParams.pstrListenChan,
1565 						   GFP_KERNEL);
1566 	}
1567 }
1568 
remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,struct ieee80211_channel * chan,unsigned int duration,u64 * cookie)1569 static int remain_on_channel(struct wiphy *wiphy,
1570 			     struct wireless_dev *wdev,
1571 			     struct ieee80211_channel *chan,
1572 			     unsigned int duration, u64 *cookie)
1573 {
1574 	s32 s32Error = 0;
1575 	struct wilc_priv *priv;
1576 	struct wilc_vif *vif;
1577 
1578 	priv = wiphy_priv(wiphy);
1579 	vif = netdev_priv(priv->dev);
1580 
1581 	if (wdev->iftype == NL80211_IFTYPE_AP) {
1582 		netdev_dbg(vif->ndev, "Required while in AP mode\n");
1583 		return s32Error;
1584 	}
1585 
1586 	curr_channel = chan->hw_value;
1587 
1588 	priv->strRemainOnChanParams.pstrListenChan = chan;
1589 	priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1590 	priv->strRemainOnChanParams.u32ListenDuration = duration;
1591 	priv->strRemainOnChanParams.u32ListenSessionID++;
1592 
1593 	s32Error = wilc_remain_on_channel(vif,
1594 				priv->strRemainOnChanParams.u32ListenSessionID,
1595 				duration, chan->hw_value,
1596 				WILC_WFI_RemainOnChannelExpired,
1597 				WILC_WFI_RemainOnChannelReady, (void *)priv);
1598 
1599 	return s32Error;
1600 }
1601 
cancel_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)1602 static int cancel_remain_on_channel(struct wiphy *wiphy,
1603 				    struct wireless_dev *wdev,
1604 				    u64 cookie)
1605 {
1606 	s32 s32Error = 0;
1607 	struct wilc_priv *priv;
1608 	struct wilc_vif *vif;
1609 
1610 	priv = wiphy_priv(wiphy);
1611 	vif = netdev_priv(priv->dev);
1612 
1613 	s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
1614 	return s32Error;
1615 }
1616 
mgmt_tx(struct wiphy * wiphy,struct wireless_dev * wdev,struct cfg80211_mgmt_tx_params * params,u64 * cookie)1617 static int mgmt_tx(struct wiphy *wiphy,
1618 		   struct wireless_dev *wdev,
1619 		   struct cfg80211_mgmt_tx_params *params,
1620 		   u64 *cookie)
1621 {
1622 	struct ieee80211_channel *chan = params->chan;
1623 	unsigned int wait = params->wait;
1624 	const u8 *buf = params->buf;
1625 	size_t len = params->len;
1626 	const struct ieee80211_mgmt *mgmt;
1627 	struct p2p_mgmt_data *mgmt_tx;
1628 	struct wilc_priv *priv;
1629 	struct host_if_drv *pstrWFIDrv;
1630 	u32 i;
1631 	struct wilc_vif *vif;
1632 	u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1633 
1634 	vif = netdev_priv(wdev->netdev);
1635 	priv = wiphy_priv(wiphy);
1636 	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1637 
1638 	*cookie = (unsigned long)buf;
1639 	priv->u64tx_cookie = *cookie;
1640 	mgmt = (const struct ieee80211_mgmt *) buf;
1641 
1642 	if (ieee80211_is_mgmt(mgmt->frame_control)) {
1643 		mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1644 		if (!mgmt_tx)
1645 			return -EFAULT;
1646 
1647 		mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1648 		if (!mgmt_tx->buff) {
1649 			kfree(mgmt_tx);
1650 			return -ENOMEM;
1651 		}
1652 
1653 		memcpy(mgmt_tx->buff, buf, len);
1654 		mgmt_tx->size = len;
1655 
1656 
1657 		if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1658 			wilc_set_mac_chnl_num(vif, chan->hw_value);
1659 			curr_channel = chan->hw_value;
1660 		} else if (ieee80211_is_action(mgmt->frame_control))   {
1661 			if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1662 				if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1663 				    buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF)	{
1664 					wilc_set_mac_chnl_num(vif,
1665 							      chan->hw_value);
1666 					curr_channel = chan->hw_value;
1667 				}
1668 				switch (buf[ACTION_SUBTYPE_ID])	{
1669 				case GAS_INTIAL_REQ:
1670 					break;
1671 
1672 				case GAS_INTIAL_RSP:
1673 					break;
1674 
1675 				case PUBLIC_ACT_VENDORSPEC:
1676 				{
1677 					if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1678 						if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1679 							if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1680 								get_random_bytes(&p2p_local_random, 1);
1681 								p2p_local_random++;
1682 							}
1683 						}
1684 
1685 						if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1686 						      || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1687 							if (p2p_local_random > p2p_recv_random)	{
1688 								for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1689 									if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1690 										if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1691 											WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1692 										else
1693 											WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1694 										break;
1695 									}
1696 								}
1697 
1698 								if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1699 									memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1700 									mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1701 									mgmt_tx->size = buf_len;
1702 								}
1703 							}
1704 						}
1705 
1706 					} else {
1707 						netdev_dbg(vif->ndev, "Not a P2P public action frame\n");
1708 					}
1709 
1710 					break;
1711 				}
1712 
1713 				default:
1714 				{
1715 					netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1716 					break;
1717 				}
1718 				}
1719 			}
1720 
1721 			pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1722 		}
1723 
1724 		wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1725 					   mgmt_tx->buff, mgmt_tx->size,
1726 					   WILC_WFI_mgmt_tx_complete);
1727 	}
1728 	return 0;
1729 }
1730 
mgmt_tx_cancel_wait(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)1731 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1732 			       struct wireless_dev *wdev,
1733 			       u64 cookie)
1734 {
1735 	struct wilc_priv *priv;
1736 	struct host_if_drv *pstrWFIDrv;
1737 
1738 	priv = wiphy_priv(wiphy);
1739 	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1740 	pstrWFIDrv->p2p_timeout = jiffies;
1741 
1742 	if (!priv->bInP2PlistenState) {
1743 		cfg80211_remain_on_channel_expired(priv->wdev,
1744 						   priv->strRemainOnChanParams.u64ListenCookie,
1745 						   priv->strRemainOnChanParams.pstrListenChan,
1746 						   GFP_KERNEL);
1747 	}
1748 
1749 	return 0;
1750 }
1751 
wilc_mgmt_frame_register(struct wiphy * wiphy,struct wireless_dev * wdev,u16 frame_type,bool reg)1752 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1753 			      u16 frame_type, bool reg)
1754 {
1755 	struct wilc_priv *priv;
1756 	struct wilc_vif *vif;
1757 	struct wilc *wl;
1758 
1759 	priv = wiphy_priv(wiphy);
1760 	vif = netdev_priv(priv->wdev->netdev);
1761 	wl = vif->wilc;
1762 
1763 	if (!frame_type)
1764 		return;
1765 
1766 	switch (frame_type) {
1767 	case PROBE_REQ:
1768 	{
1769 		vif->frame_reg[0].type = frame_type;
1770 		vif->frame_reg[0].reg = reg;
1771 	}
1772 	break;
1773 
1774 	case ACTION:
1775 	{
1776 		vif->frame_reg[1].type = frame_type;
1777 		vif->frame_reg[1].reg = reg;
1778 	}
1779 	break;
1780 
1781 	default:
1782 	{
1783 		break;
1784 	}
1785 	}
1786 
1787 	if (!wl->initialized)
1788 		return;
1789 	wilc_frame_register(vif, frame_type, reg);
1790 }
1791 
set_cqm_rssi_config(struct wiphy * wiphy,struct net_device * dev,s32 rssi_thold,u32 rssi_hyst)1792 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1793 			       s32 rssi_thold, u32 rssi_hyst)
1794 {
1795 	return 0;
1796 }
1797 
dump_station(struct wiphy * wiphy,struct net_device * dev,int idx,u8 * mac,struct station_info * sinfo)1798 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1799 			int idx, u8 *mac, struct station_info *sinfo)
1800 {
1801 	struct wilc_priv *priv;
1802 	struct wilc_vif *vif;
1803 
1804 	if (idx != 0)
1805 		return -ENOENT;
1806 
1807 	priv = wiphy_priv(wiphy);
1808 	vif = netdev_priv(priv->dev);
1809 
1810 	sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1811 
1812 	wilc_get_rssi(vif, &sinfo->signal);
1813 
1814 	memcpy(mac, priv->au8AssociatedBss, ETH_ALEN);
1815 	return 0;
1816 }
1817 
set_power_mgmt(struct wiphy * wiphy,struct net_device * dev,bool enabled,int timeout)1818 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1819 			  bool enabled, int timeout)
1820 {
1821 	struct wilc_priv *priv;
1822 	struct wilc_vif *vif;
1823 
1824 	if (!wiphy)
1825 		return -ENOENT;
1826 
1827 	priv = wiphy_priv(wiphy);
1828 	vif = netdev_priv(priv->dev);
1829 	if (!priv->hif_drv)
1830 		return -EIO;
1831 
1832 	if (wilc_enable_ps)
1833 		wilc_set_power_mgmt(vif, enabled, timeout);
1834 
1835 
1836 	return 0;
1837 }
1838 
change_virtual_intf(struct wiphy * wiphy,struct net_device * dev,enum nl80211_iftype type,u32 * flags,struct vif_params * params)1839 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1840 			       enum nl80211_iftype type, u32 *flags, struct vif_params *params)
1841 {
1842 	struct wilc_priv *priv;
1843 	struct wilc_vif *vif;
1844 	struct wilc *wl;
1845 
1846 	vif = netdev_priv(dev);
1847 	priv = wiphy_priv(wiphy);
1848 	wl = vif->wilc;
1849 	p2p_local_random = 0x01;
1850 	p2p_recv_random = 0x00;
1851 	wilc_ie = false;
1852 	wilc_optaining_ip = false;
1853 	del_timer(&wilc_during_ip_timer);
1854 
1855 	switch (type) {
1856 	case NL80211_IFTYPE_STATION:
1857 		wilc_connecting = 0;
1858 		dev->ieee80211_ptr->iftype = type;
1859 		priv->wdev->iftype = type;
1860 		vif->monitor_flag = 0;
1861 		vif->iftype = STATION_MODE;
1862 		wilc_set_operation_mode(vif, STATION_MODE);
1863 
1864 		memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
1865 
1866 		wilc_enable_ps = true;
1867 		wilc_set_power_mgmt(vif, 1, 0);
1868 		break;
1869 
1870 	case NL80211_IFTYPE_P2P_CLIENT:
1871 		wilc_connecting = 0;
1872 		dev->ieee80211_ptr->iftype = type;
1873 		priv->wdev->iftype = type;
1874 		vif->monitor_flag = 0;
1875 		vif->iftype = CLIENT_MODE;
1876 		wilc_set_operation_mode(vif, STATION_MODE);
1877 
1878 		wilc_enable_ps = false;
1879 		wilc_set_power_mgmt(vif, 0, 0);
1880 		break;
1881 
1882 	case NL80211_IFTYPE_AP:
1883 		wilc_enable_ps = false;
1884 		dev->ieee80211_ptr->iftype = type;
1885 		priv->wdev->iftype = type;
1886 		vif->iftype = AP_MODE;
1887 
1888 		if (wl->initialized) {
1889 			wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
1890 						 0);
1891 			wilc_set_operation_mode(vif, AP_MODE);
1892 			wilc_set_power_mgmt(vif, 0, 0);
1893 		}
1894 		break;
1895 
1896 	case NL80211_IFTYPE_P2P_GO:
1897 		wilc_optaining_ip = true;
1898 		mod_timer(&wilc_during_ip_timer,
1899 			  jiffies + msecs_to_jiffies(during_ip_time));
1900 		wilc_set_operation_mode(vif, AP_MODE);
1901 		dev->ieee80211_ptr->iftype = type;
1902 		priv->wdev->iftype = type;
1903 		vif->iftype = GO_MODE;
1904 
1905 		wilc_enable_ps = false;
1906 		wilc_set_power_mgmt(vif, 0, 0);
1907 		break;
1908 
1909 	default:
1910 		netdev_err(dev, "Unknown interface type= %d\n", type);
1911 		return -EINVAL;
1912 	}
1913 
1914 	return 0;
1915 }
1916 
start_ap(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_ap_settings * settings)1917 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1918 		    struct cfg80211_ap_settings *settings)
1919 {
1920 	struct cfg80211_beacon_data *beacon = &(settings->beacon);
1921 	struct wilc_priv *priv;
1922 	s32 s32Error = 0;
1923 	struct wilc *wl;
1924 	struct wilc_vif *vif;
1925 
1926 	priv = wiphy_priv(wiphy);
1927 	vif = netdev_priv(dev);
1928 	wl = vif->wilc;
1929 
1930 	s32Error = set_channel(wiphy, &settings->chandef);
1931 
1932 	if (s32Error != 0)
1933 		netdev_err(dev, "Error in setting channel\n");
1934 
1935 	wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
1936 	wilc_set_power_mgmt(vif, 0, 0);
1937 
1938 	s32Error = wilc_add_beacon(vif, settings->beacon_interval,
1939 				   settings->dtim_period, beacon->head_len,
1940 				   (u8 *)beacon->head, beacon->tail_len,
1941 				   (u8 *)beacon->tail);
1942 
1943 	return s32Error;
1944 }
1945 
change_beacon(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_beacon_data * beacon)1946 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1947 			 struct cfg80211_beacon_data *beacon)
1948 {
1949 	struct wilc_priv *priv;
1950 	struct wilc_vif *vif;
1951 	s32 s32Error = 0;
1952 
1953 	priv = wiphy_priv(wiphy);
1954 	vif = netdev_priv(priv->dev);
1955 
1956 	s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
1957 				   (u8 *)beacon->head, beacon->tail_len,
1958 				   (u8 *)beacon->tail);
1959 
1960 	return s32Error;
1961 }
1962 
stop_ap(struct wiphy * wiphy,struct net_device * dev)1963 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1964 {
1965 	s32 s32Error = 0;
1966 	struct wilc_priv *priv;
1967 	struct wilc_vif *vif;
1968 	u8 NullBssid[ETH_ALEN] = {0};
1969 
1970 	if (!wiphy)
1971 		return -EFAULT;
1972 
1973 	priv = wiphy_priv(wiphy);
1974 	vif = netdev_priv(priv->dev);
1975 
1976 	wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
1977 
1978 	s32Error = wilc_del_beacon(vif);
1979 
1980 	if (s32Error)
1981 		netdev_err(dev, "Host delete beacon fail\n");
1982 
1983 	return s32Error;
1984 }
1985 
add_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_parameters * params)1986 static int add_station(struct wiphy *wiphy, struct net_device *dev,
1987 		       const u8 *mac, struct station_parameters *params)
1988 {
1989 	s32 s32Error = 0;
1990 	struct wilc_priv *priv;
1991 	struct add_sta_param strStaParams = { {0} };
1992 	struct wilc_vif *vif;
1993 
1994 	if (!wiphy)
1995 		return -EFAULT;
1996 
1997 	priv = wiphy_priv(wiphy);
1998 	vif = netdev_priv(dev);
1999 
2000 	if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2001 		memcpy(strStaParams.bssid, mac, ETH_ALEN);
2002 		memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
2003 		strStaParams.aid = params->aid;
2004 		strStaParams.rates_len = params->supported_rates_len;
2005 		strStaParams.rates = params->supported_rates;
2006 
2007 		if (!params->ht_capa) {
2008 			strStaParams.ht_supported = false;
2009 		} else {
2010 			strStaParams.ht_supported = true;
2011 			strStaParams.ht_capa_info = params->ht_capa->cap_info;
2012 			strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2013 			memcpy(strStaParams.ht_supp_mcs_set,
2014 			       &params->ht_capa->mcs,
2015 			       WILC_SUPP_MCS_SET_SIZE);
2016 			strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2017 			strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2018 			strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2019 		}
2020 
2021 		strStaParams.flags_mask = params->sta_flags_mask;
2022 		strStaParams.flags_set = params->sta_flags_set;
2023 
2024 		s32Error = wilc_add_station(vif, &strStaParams);
2025 		if (s32Error)
2026 			netdev_err(dev, "Host add station fail\n");
2027 	}
2028 
2029 	return s32Error;
2030 }
2031 
del_station(struct wiphy * wiphy,struct net_device * dev,struct station_del_parameters * params)2032 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2033 		       struct station_del_parameters *params)
2034 {
2035 	const u8 *mac = params->mac;
2036 	s32 s32Error = 0;
2037 	struct wilc_priv *priv;
2038 	struct wilc_vif *vif;
2039 
2040 	if (!wiphy)
2041 		return -EFAULT;
2042 
2043 	priv = wiphy_priv(wiphy);
2044 	vif = netdev_priv(dev);
2045 
2046 	if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2047 		if (!mac)
2048 			s32Error = wilc_del_allstation(vif,
2049 				     priv->assoc_stainfo.au8Sta_AssociatedBss);
2050 
2051 		s32Error = wilc_del_station(vif, mac);
2052 
2053 		if (s32Error)
2054 			netdev_err(dev, "Host delete station fail\n");
2055 	}
2056 	return s32Error;
2057 }
2058 
change_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_parameters * params)2059 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2060 			  const u8 *mac, struct station_parameters *params)
2061 {
2062 	s32 s32Error = 0;
2063 	struct wilc_priv *priv;
2064 	struct add_sta_param strStaParams = { {0} };
2065 	struct wilc_vif *vif;
2066 
2067 	if (!wiphy)
2068 		return -EFAULT;
2069 
2070 	priv = wiphy_priv(wiphy);
2071 	vif = netdev_priv(dev);
2072 
2073 	if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2074 		memcpy(strStaParams.bssid, mac, ETH_ALEN);
2075 		strStaParams.aid = params->aid;
2076 		strStaParams.rates_len = params->supported_rates_len;
2077 		strStaParams.rates = params->supported_rates;
2078 
2079 		if (!params->ht_capa) {
2080 			strStaParams.ht_supported = false;
2081 		} else {
2082 			strStaParams.ht_supported = true;
2083 			strStaParams.ht_capa_info = params->ht_capa->cap_info;
2084 			strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2085 			memcpy(strStaParams.ht_supp_mcs_set,
2086 			       &params->ht_capa->mcs,
2087 			       WILC_SUPP_MCS_SET_SIZE);
2088 			strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2089 			strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2090 			strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2091 		}
2092 
2093 		strStaParams.flags_mask = params->sta_flags_mask;
2094 		strStaParams.flags_set = params->sta_flags_set;
2095 
2096 		s32Error = wilc_edit_station(vif, &strStaParams);
2097 		if (s32Error)
2098 			netdev_err(dev, "Host edit station fail\n");
2099 	}
2100 	return s32Error;
2101 }
2102 
add_virtual_intf(struct wiphy * wiphy,const char * name,unsigned char name_assign_type,enum nl80211_iftype type,u32 * flags,struct vif_params * params)2103 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2104 					     const char *name,
2105 					     unsigned char name_assign_type,
2106 					     enum nl80211_iftype type,
2107 					     u32 *flags,
2108 					     struct vif_params *params)
2109 {
2110 	struct wilc_vif *vif;
2111 	struct wilc_priv *priv;
2112 	struct net_device *new_ifc = NULL;
2113 
2114 	priv = wiphy_priv(wiphy);
2115 	vif = netdev_priv(priv->wdev->netdev);
2116 
2117 
2118 	if (type == NL80211_IFTYPE_MONITOR) {
2119 		new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2120 		if (new_ifc) {
2121 			vif = netdev_priv(priv->wdev->netdev);
2122 			vif->monitor_flag = 1;
2123 		}
2124 	}
2125 	return priv->wdev;
2126 }
2127 
del_virtual_intf(struct wiphy * wiphy,struct wireless_dev * wdev)2128 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2129 {
2130 	return 0;
2131 }
2132 
wilc_suspend(struct wiphy * wiphy,struct cfg80211_wowlan * wow)2133 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2134 {
2135 	struct wilc_priv *priv = wiphy_priv(wiphy);
2136 	struct wilc_vif *vif = netdev_priv(priv->dev);
2137 
2138 	if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2139 		vif->wilc->suspend_event = true;
2140 	else
2141 		vif->wilc->suspend_event = false;
2142 
2143 	return 0;
2144 }
2145 
wilc_resume(struct wiphy * wiphy)2146 static int wilc_resume(struct wiphy *wiphy)
2147 {
2148 	struct wilc_priv *priv = wiphy_priv(wiphy);
2149 	struct wilc_vif *vif = netdev_priv(priv->dev);
2150 
2151 	netdev_info(vif->ndev, "cfg resume\n");
2152 	return 0;
2153 }
2154 
wilc_set_wakeup(struct wiphy * wiphy,bool enabled)2155 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2156 {
2157 	struct wilc_priv *priv = wiphy_priv(wiphy);
2158 	struct wilc_vif *vif = netdev_priv(priv->dev);
2159 
2160 	netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2161 }
2162 
set_tx_power(struct wiphy * wiphy,struct wireless_dev * wdev,enum nl80211_tx_power_setting type,int mbm)2163 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2164 			enum nl80211_tx_power_setting type, int mbm)
2165 {
2166 	int ret;
2167 	s32 tx_power = MBM_TO_DBM(mbm);
2168 	struct wilc_priv *priv = wiphy_priv(wiphy);
2169 	struct wilc_vif *vif = netdev_priv(priv->dev);
2170 
2171 	if (tx_power < 0)
2172 		tx_power = 0;
2173 	else if (tx_power > 18)
2174 		tx_power = 18;
2175 	ret = wilc_set_tx_power(vif, tx_power);
2176 	if (ret)
2177 		netdev_err(vif->ndev, "Failed to set tx power\n");
2178 
2179 	return ret;
2180 }
2181 
get_tx_power(struct wiphy * wiphy,struct wireless_dev * wdev,int * dbm)2182 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2183 			int *dbm)
2184 {
2185 	int ret;
2186 	struct wilc_priv *priv = wiphy_priv(wiphy);
2187 	struct wilc_vif *vif = netdev_priv(priv->dev);
2188 	struct wilc *wl;
2189 
2190 	wl = vif->wilc;
2191 
2192 	/* If firmware is not started, return. */
2193 	if (!wl->initialized)
2194 		return -EIO;
2195 
2196 	ret = wilc_get_tx_power(vif, (u8 *)dbm);
2197 	if (ret)
2198 		netdev_err(vif->ndev, "Failed to get tx power\n");
2199 
2200 	return ret;
2201 }
2202 
2203 static const struct cfg80211_ops wilc_cfg80211_ops = {
2204 	.set_monitor_channel = set_channel,
2205 	.scan = scan,
2206 	.connect = connect,
2207 	.disconnect = disconnect,
2208 	.add_key = add_key,
2209 	.del_key = del_key,
2210 	.get_key = get_key,
2211 	.set_default_key = set_default_key,
2212 	.add_virtual_intf = add_virtual_intf,
2213 	.del_virtual_intf = del_virtual_intf,
2214 	.change_virtual_intf = change_virtual_intf,
2215 
2216 	.start_ap = start_ap,
2217 	.change_beacon = change_beacon,
2218 	.stop_ap = stop_ap,
2219 	.add_station = add_station,
2220 	.del_station = del_station,
2221 	.change_station = change_station,
2222 	.get_station = get_station,
2223 	.dump_station = dump_station,
2224 	.change_bss = change_bss,
2225 	.set_wiphy_params = set_wiphy_params,
2226 
2227 	.set_pmksa = set_pmksa,
2228 	.del_pmksa = del_pmksa,
2229 	.flush_pmksa = flush_pmksa,
2230 	.remain_on_channel = remain_on_channel,
2231 	.cancel_remain_on_channel = cancel_remain_on_channel,
2232 	.mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2233 	.mgmt_tx = mgmt_tx,
2234 	.mgmt_frame_register = wilc_mgmt_frame_register,
2235 	.set_power_mgmt = set_power_mgmt,
2236 	.set_cqm_rssi_config = set_cqm_rssi_config,
2237 
2238 	.suspend = wilc_suspend,
2239 	.resume = wilc_resume,
2240 	.set_wakeup = wilc_set_wakeup,
2241 	.set_tx_power = set_tx_power,
2242 	.get_tx_power = get_tx_power,
2243 
2244 };
2245 
WILC_WFI_CfgAlloc(void)2246 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2247 {
2248 	struct wireless_dev *wdev;
2249 
2250 	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2251 	if (!wdev)
2252 		goto _fail_;
2253 
2254 	wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2255 	if (!wdev->wiphy)
2256 		goto _fail_mem_;
2257 
2258 	WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2259 	WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2260 	WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2261 	WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2262 	WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2263 
2264 	wdev->wiphy->bands[NL80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2265 
2266 	return wdev;
2267 
2268 _fail_mem_:
2269 	kfree(wdev);
2270 _fail_:
2271 	return NULL;
2272 }
2273 
wilc_create_wiphy(struct net_device * net,struct device * dev)2274 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2275 {
2276 	struct wilc_priv *priv;
2277 	struct wireless_dev *wdev;
2278 	s32 s32Error = 0;
2279 
2280 	wdev = WILC_WFI_CfgAlloc();
2281 	if (!wdev) {
2282 		netdev_err(net, "wiphy new allocate failed\n");
2283 		return NULL;
2284 	}
2285 
2286 	priv = wdev_priv(wdev);
2287 	priv->wdev = wdev;
2288 	wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2289 #ifdef CONFIG_PM
2290 	wdev->wiphy->wowlan = &wowlan_support;
2291 #endif
2292 	wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2293 	wdev->wiphy->max_scan_ie_len = 1000;
2294 	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2295 	wdev->wiphy->cipher_suites = cipher_suites;
2296 	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2297 	wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2298 
2299 	wdev->wiphy->max_remain_on_channel_duration = 500;
2300 	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2301 		BIT(NL80211_IFTYPE_P2P_CLIENT);
2302 	wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2303 	wdev->iftype = NL80211_IFTYPE_STATION;
2304 
2305 	set_wiphy_dev(wdev->wiphy, dev);
2306 
2307 	s32Error = wiphy_register(wdev->wiphy);
2308 	if (s32Error)
2309 		netdev_err(net, "Cannot register wiphy device\n");
2310 
2311 	priv->dev = net;
2312 	return wdev;
2313 }
2314 
wilc_init_host_int(struct net_device * net)2315 int wilc_init_host_int(struct net_device *net)
2316 {
2317 	int s32Error = 0;
2318 
2319 	struct wilc_priv *priv;
2320 
2321 	priv = wdev_priv(net->ieee80211_ptr);
2322 	if (op_ifcs == 0) {
2323 		setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2324 		setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2325 	}
2326 	op_ifcs++;
2327 
2328 	priv->gbAutoRateAdjusted = false;
2329 
2330 	priv->bInP2PlistenState = false;
2331 
2332 	mutex_init(&priv->scan_req_lock);
2333 	s32Error = wilc_init(net, &priv->hif_drv);
2334 	if (s32Error)
2335 		netdev_err(net, "Error while initializing hostinterface\n");
2336 
2337 	return s32Error;
2338 }
2339 
wilc_deinit_host_int(struct net_device * net)2340 int wilc_deinit_host_int(struct net_device *net)
2341 {
2342 	int s32Error = 0;
2343 	struct wilc_vif *vif;
2344 	struct wilc_priv *priv;
2345 
2346 	priv = wdev_priv(net->ieee80211_ptr);
2347 	vif = netdev_priv(priv->dev);
2348 
2349 	priv->gbAutoRateAdjusted = false;
2350 
2351 	priv->bInP2PlistenState = false;
2352 
2353 	op_ifcs--;
2354 
2355 	s32Error = wilc_deinit(vif);
2356 
2357 	clear_shadow_scan();
2358 	if (op_ifcs == 0)
2359 		del_timer_sync(&wilc_during_ip_timer);
2360 
2361 	if (s32Error)
2362 		netdev_err(net, "Error while deintializing host interface\n");
2363 
2364 	return s32Error;
2365 }
2366 
wilc_free_wiphy(struct net_device * net)2367 void wilc_free_wiphy(struct net_device *net)
2368 {
2369 	if (!net)
2370 		return;
2371 
2372 	if (!net->ieee80211_ptr)
2373 		return;
2374 
2375 	if (!net->ieee80211_ptr->wiphy)
2376 		return;
2377 
2378 	wiphy_unregister(net->ieee80211_ptr->wiphy);
2379 
2380 	wiphy_free(net->ieee80211_ptr->wiphy);
2381 	kfree(net->ieee80211_ptr);
2382 }
2383