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