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