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