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