GNU Linux-libre 4.19.314-gnu1
[releases.git] / drivers / staging / wilc1000 / wilc_wfi_cfgoperations.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
4  * All rights reserved.
5  */
6
7 #include "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
44 static 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
52 static 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
81 static const struct wiphy_wowlan_support wowlan_support = {
82         .flags = WIPHY_WOWLAN_ANY
83 };
84
85 static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
86 static u32 last_scanned_cnt;
87 struct timer_list wilc_during_ip_timer;
88 static struct timer_list aging_timer;
89 static 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
100 static 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
123 static 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
138 struct p2p_mgmt_data {
139         int size;
140         u8 *buff;
141 };
142
143 static u8 wlan_channel = INVALID_CHANNEL;
144 static u8 curr_channel;
145 static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
146 static u8 p2p_local_random = 0x01;
147 static u8 p2p_recv_random;
148 static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
149 static bool wilc_ie;
150
151 static 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
161 static 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
182 static 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
196 static 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
232 static 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
240 static 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
248 static 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
272 static void clear_during_ip(struct timer_list *unused)
273 {
274         wilc_optaining_ip = false;
275 }
276
277 static 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
297 static 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
347 static 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
452 static 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
463 int wilc_connecting;
464
465 static 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
548 static 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
567 static inline int
568 wilc_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
599 out_free:
600
601         for (i = 0; i < slot_id; i++)
602                 kfree(ntwk->net_info[i].ssid);
603
604         kfree(ntwk->net_info);
605 out:
606
607         return -ENOMEM;
608 }
609
610 static 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
662 static 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
809 static 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                 /* already disconnected done */
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
849 static 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
857 static 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
876 static 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
901 static 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
1011 static 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
1051 static 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
1077 static 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
1088 static 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
1142 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1143                       struct bss_parameters *params)
1144 {
1145         return 0;
1146 }
1147
1148 static 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
1182 static 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
1216 static 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
1249 static 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
1258 static 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
1282 static 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
1303 static 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
1328 static 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
1366 void 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
1433 static 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
1441 static 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
1456 static 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
1470 static 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
1498 static 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
1509 static 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
1558 static 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
1639 out_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
1645 out:
1646
1647         return ret;
1648 }
1649
1650 static 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
1673 void 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
1703 static 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
1709 static 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
1726 static 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
1741 static 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
1818 static 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
1840 static 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
1851 static 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
1868 static 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
1902 static 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
1925 static 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
1955 static 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
1975 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
1976 {
1977         return 0;
1978 }
1979
1980 static 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
1993 static 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
2002 static 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
2010 static 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
2029 static 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         /* If firmware is not started, return. */
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
2048 static 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
2091 static 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
2113 free_mem:
2114         kfree(wdev);
2115 out:
2116         return NULL;
2117 }
2118
2119 struct 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
2164 int 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
2185 int 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
2208 void 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 }