]> Git Repo - linux.git/blob - drivers/net/wireless/microchip/wilc1000/cfg80211.c
KVM: x86: fix CPUID entries returned by KVM_GET_CPUID2 ioctl
[linux.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                 if (!bss)
133                         cfg80211_put_bss(wiphy, bss);
134         } else if (scan_event == SCAN_EVENT_DONE) {
135                 mutex_lock(&priv->scan_req_lock);
136
137                 if (priv->scan_req) {
138                         struct cfg80211_scan_info info = {
139                                 .aborted = false,
140                         };
141
142                         cfg80211_scan_done(priv->scan_req, &info);
143                         priv->cfg_scanning = false;
144                         priv->scan_req = NULL;
145                 }
146                 mutex_unlock(&priv->scan_req_lock);
147         } else if (scan_event == SCAN_EVENT_ABORTED) {
148                 mutex_lock(&priv->scan_req_lock);
149
150                 if (priv->scan_req) {
151                         struct cfg80211_scan_info info = {
152                                 .aborted = false,
153                         };
154
155                         cfg80211_scan_done(priv->scan_req, &info);
156                         priv->cfg_scanning = false;
157                         priv->scan_req = NULL;
158                 }
159                 mutex_unlock(&priv->scan_req_lock);
160         }
161 }
162
163 static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
164                                void *priv_data)
165 {
166         struct wilc_priv *priv = priv_data;
167         struct net_device *dev = priv->dev;
168         struct wilc_vif *vif = netdev_priv(dev);
169         struct wilc *wl = vif->wilc;
170         struct host_if_drv *wfi_drv = priv->hif_drv;
171         struct wilc_conn_info *conn_info = &wfi_drv->conn_info;
172         struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
173
174         vif->connecting = false;
175
176         if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
177                 u16 connect_status = conn_info->status;
178
179                 if (mac_status == WILC_MAC_STATUS_DISCONNECTED &&
180                     connect_status == WLAN_STATUS_SUCCESS) {
181                         connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
182                         wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
183
184                         if (vif->iftype != WILC_CLIENT_MODE)
185                                 wl->sta_ch = WILC_INVALID_CHANNEL;
186
187                         netdev_err(dev, "Unspecified failure\n");
188                 }
189
190                 if (connect_status == WLAN_STATUS_SUCCESS)
191                         memcpy(priv->associated_bss, conn_info->bssid,
192                                ETH_ALEN);
193
194                 cfg80211_ref_bss(wiphy, vif->bss);
195                 cfg80211_connect_bss(dev, conn_info->bssid, vif->bss,
196                                      conn_info->req_ies,
197                                      conn_info->req_ies_len,
198                                      conn_info->resp_ies,
199                                      conn_info->resp_ies_len,
200                                      connect_status, GFP_KERNEL,
201                                      NL80211_TIMEOUT_UNSPECIFIED);
202
203                 vif->bss = NULL;
204         } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
205                 u16 reason = 0;
206
207                 eth_zero_addr(priv->associated_bss);
208                 wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
209
210                 if (vif->iftype != WILC_CLIENT_MODE) {
211                         wl->sta_ch = WILC_INVALID_CHANNEL;
212                 } else {
213                         if (wfi_drv->ifc_up)
214                                 reason = 3;
215                         else
216                                 reason = 1;
217                 }
218
219                 cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
220         }
221 }
222
223 struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
224 {
225         struct wilc_vif *vif;
226
227         vif = list_first_or_null_rcu(&wl->vif_list, typeof(*vif), list);
228         if (!vif)
229                 return ERR_PTR(-EINVAL);
230
231         return vif;
232 }
233
234 static int set_channel(struct wiphy *wiphy,
235                        struct cfg80211_chan_def *chandef)
236 {
237         struct wilc *wl = wiphy_priv(wiphy);
238         struct wilc_vif *vif;
239         u32 channelnum;
240         int result;
241         int srcu_idx;
242
243         srcu_idx = srcu_read_lock(&wl->srcu);
244         vif = wilc_get_wl_to_vif(wl);
245         if (IS_ERR(vif)) {
246                 srcu_read_unlock(&wl->srcu, srcu_idx);
247                 return PTR_ERR(vif);
248         }
249
250         channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
251
252         wl->op_ch = channelnum;
253         result = wilc_set_mac_chnl_num(vif, channelnum);
254         if (result)
255                 netdev_err(vif->ndev, "Error in setting channel\n");
256
257         srcu_read_unlock(&wl->srcu, srcu_idx);
258         return result;
259 }
260
261 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
262 {
263         struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
264         struct wilc_priv *priv = &vif->priv;
265         u32 i;
266         int ret = 0;
267         u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
268         u8 scan_type;
269
270         if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
271                 netdev_err(vif->ndev, "Requested scanned channels over\n");
272                 return -EINVAL;
273         }
274
275         priv->scan_req = request;
276         priv->cfg_scanning = true;
277         for (i = 0; i < request->n_channels; i++) {
278                 u16 freq = request->channels[i]->center_freq;
279
280                 scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
281         }
282
283         if (request->n_ssids)
284                 scan_type = WILC_FW_ACTIVE_SCAN;
285         else
286                 scan_type = WILC_FW_PASSIVE_SCAN;
287
288         ret = wilc_scan(vif, WILC_FW_USER_SCAN, scan_type, scan_ch_list,
289                         request->n_channels, cfg_scan_result, (void *)priv,
290                         request);
291
292         if (ret) {
293                 priv->scan_req = NULL;
294                 priv->cfg_scanning = false;
295         }
296
297         return ret;
298 }
299
300 static int connect(struct wiphy *wiphy, struct net_device *dev,
301                    struct cfg80211_connect_params *sme)
302 {
303         struct wilc_vif *vif = netdev_priv(dev);
304         struct wilc_priv *priv = &vif->priv;
305         struct host_if_drv *wfi_drv = priv->hif_drv;
306         int ret;
307         u32 i;
308         u8 security = WILC_FW_SEC_NO;
309         enum authtype auth_type = WILC_FW_AUTH_ANY;
310         u32 cipher_group;
311         struct cfg80211_bss *bss;
312         void *join_params;
313         u8 ch;
314
315         vif->connecting = true;
316
317         memset(priv->wep_key, 0, sizeof(priv->wep_key));
318         memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
319
320         cipher_group = sme->crypto.cipher_group;
321         if (cipher_group != 0) {
322                 if (cipher_group == WLAN_CIPHER_SUITE_WEP40) {
323                         security = WILC_FW_SEC_WEP;
324
325                         priv->wep_key_len[sme->key_idx] = sme->key_len;
326                         memcpy(priv->wep_key[sme->key_idx], sme->key,
327                                sme->key_len);
328
329                         wilc_set_wep_default_keyid(vif, sme->key_idx);
330                         wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
331                                                  sme->key_idx);
332                 } else if (cipher_group == WLAN_CIPHER_SUITE_WEP104) {
333                         security = WILC_FW_SEC_WEP_EXTENDED;
334
335                         priv->wep_key_len[sme->key_idx] = sme->key_len;
336                         memcpy(priv->wep_key[sme->key_idx], sme->key,
337                                sme->key_len);
338
339                         wilc_set_wep_default_keyid(vif, sme->key_idx);
340                         wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
341                                                  sme->key_idx);
342                 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
343                         if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
344                                 security = WILC_FW_SEC_WPA2_TKIP;
345                         else
346                                 security = WILC_FW_SEC_WPA2_AES;
347                 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
348                         if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
349                                 security = WILC_FW_SEC_WPA_TKIP;
350                         else
351                                 security = WILC_FW_SEC_WPA_AES;
352                 } else {
353                         ret = -ENOTSUPP;
354                         netdev_err(dev, "%s: Unsupported cipher\n",
355                                    __func__);
356                         goto out_error;
357                 }
358         }
359
360         if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
361             (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
362                 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
363                         u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];
364
365                         if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
366                                 security |= WILC_FW_TKIP;
367                         else
368                                 security |= WILC_FW_AES;
369                 }
370         }
371
372         switch (sme->auth_type) {
373         case NL80211_AUTHTYPE_OPEN_SYSTEM:
374                 auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
375                 break;
376
377         case NL80211_AUTHTYPE_SHARED_KEY:
378                 auth_type = WILC_FW_AUTH_SHARED_KEY;
379                 break;
380
381         default:
382                 break;
383         }
384
385         if (sme->crypto.n_akm_suites) {
386                 if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
387                         auth_type = WILC_FW_AUTH_IEEE8021;
388         }
389
390         if (wfi_drv->usr_scan_req.scan_result) {
391                 netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
392                 ret = -EBUSY;
393                 goto out_error;
394         }
395
396         bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid,
397                                sme->ssid_len, IEEE80211_BSS_TYPE_ANY,
398                                IEEE80211_PRIVACY(sme->privacy));
399         if (!bss) {
400                 ret = -EINVAL;
401                 goto out_error;
402         }
403
404         if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) {
405                 ret = -EALREADY;
406                 goto out_put_bss;
407         }
408
409         join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
410         if (!join_params) {
411                 netdev_err(dev, "%s: failed to construct join param\n",
412                            __func__);
413                 ret = -EINVAL;
414                 goto out_put_bss;
415         }
416
417         ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
418         vif->wilc->op_ch = ch;
419         if (vif->iftype != WILC_CLIENT_MODE)
420                 vif->wilc->sta_ch = ch;
421
422         wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE);
423
424         wfi_drv->conn_info.security = security;
425         wfi_drv->conn_info.auth_type = auth_type;
426         wfi_drv->conn_info.ch = ch;
427         wfi_drv->conn_info.conn_result = cfg_connect_result;
428         wfi_drv->conn_info.arg = priv;
429         wfi_drv->conn_info.param = join_params;
430
431         ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
432         if (ret) {
433                 netdev_err(dev, "wilc_set_join_req(): Error\n");
434                 ret = -ENOENT;
435                 if (vif->iftype != WILC_CLIENT_MODE)
436                         vif->wilc->sta_ch = WILC_INVALID_CHANNEL;
437                 wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE);
438                 wfi_drv->conn_info.conn_result = NULL;
439                 kfree(join_params);
440                 goto out_put_bss;
441         }
442         kfree(join_params);
443         vif->bss = bss;
444         cfg80211_put_bss(wiphy, bss);
445         return 0;
446
447 out_put_bss:
448         cfg80211_put_bss(wiphy, bss);
449
450 out_error:
451         vif->connecting = false;
452         return ret;
453 }
454
455 static int disconnect(struct wiphy *wiphy, struct net_device *dev,
456                       u16 reason_code)
457 {
458         struct wilc_vif *vif = netdev_priv(dev);
459         struct wilc_priv *priv = &vif->priv;
460         struct wilc *wilc = vif->wilc;
461         int ret;
462
463         vif->connecting = false;
464
465         if (!wilc)
466                 return -EIO;
467
468         if (wilc->close) {
469                 /* already disconnected done */
470                 cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
471                 return 0;
472         }
473
474         if (vif->iftype != WILC_CLIENT_MODE)
475                 wilc->sta_ch = WILC_INVALID_CHANNEL;
476         wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
477
478         priv->hif_drv->p2p_timeout = 0;
479
480         ret = wilc_disconnect(vif);
481         if (ret != 0) {
482                 netdev_err(priv->dev, "Error in disconnecting\n");
483                 ret = -EINVAL;
484         }
485
486         vif->bss = NULL;
487
488         return ret;
489 }
490
491 static inline void wilc_wfi_cfg_copy_wep_info(struct wilc_priv *priv,
492                                               u8 key_index,
493                                               struct key_params *params)
494 {
495         priv->wep_key_len[key_index] = params->key_len;
496         memcpy(priv->wep_key[key_index], params->key, params->key_len);
497 }
498
499 static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
500 {
501         if (!priv->wilc_gtk[idx]) {
502                 priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
503                                               GFP_KERNEL);
504                 if (!priv->wilc_gtk[idx])
505                         return -ENOMEM;
506         }
507
508         if (!priv->wilc_ptk[idx]) {
509                 priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
510                                               GFP_KERNEL);
511                 if (!priv->wilc_ptk[idx])
512                         return -ENOMEM;
513         }
514
515         return 0;
516 }
517
518 static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
519                                       struct key_params *params)
520 {
521         kfree(key_info->key);
522
523         key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
524         if (!key_info->key)
525                 return -ENOMEM;
526
527         kfree(key_info->seq);
528
529         if (params->seq_len > 0) {
530                 key_info->seq = kmemdup(params->seq, params->seq_len,
531                                         GFP_KERNEL);
532                 if (!key_info->seq)
533                         return -ENOMEM;
534         }
535
536         key_info->cipher = params->cipher;
537         key_info->key_len = params->key_len;
538         key_info->seq_len = params->seq_len;
539
540         return 0;
541 }
542
543 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
544                    bool pairwise, const u8 *mac_addr, struct key_params *params)
545
546 {
547         int ret = 0, keylen = params->key_len;
548         const u8 *rx_mic = NULL;
549         const u8 *tx_mic = NULL;
550         u8 mode = WILC_FW_SEC_NO;
551         u8 op_mode;
552         struct wilc_vif *vif = netdev_priv(netdev);
553         struct wilc_priv *priv = &vif->priv;
554
555         switch (params->cipher) {
556         case WLAN_CIPHER_SUITE_WEP40:
557         case WLAN_CIPHER_SUITE_WEP104:
558                 if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
559                         wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
560
561                         if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
562                                 mode = WILC_FW_SEC_WEP;
563                         else
564                                 mode = WILC_FW_SEC_WEP_EXTENDED;
565
566                         ret = wilc_add_wep_key_bss_ap(vif, params->key,
567                                                       params->key_len,
568                                                       key_index, mode,
569                                                       WILC_FW_AUTH_OPEN_SYSTEM);
570                         break;
571                 }
572                 if (memcmp(params->key, priv->wep_key[key_index],
573                            params->key_len)) {
574                         wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
575
576                         ret = wilc_add_wep_key_bss_sta(vif, params->key,
577                                                        params->key_len,
578                                                        key_index);
579                 }
580
581                 break;
582
583         case WLAN_CIPHER_SUITE_TKIP:
584         case WLAN_CIPHER_SUITE_CCMP:
585                 if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
586                     priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
587                         struct wilc_wfi_key *key;
588
589                         ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
590                         if (ret)
591                                 return -ENOMEM;
592
593                         if (params->key_len > 16 &&
594                             params->cipher == WLAN_CIPHER_SUITE_TKIP) {
595                                 tx_mic = params->key + 24;
596                                 rx_mic = params->key + 16;
597                                 keylen = params->key_len - 16;
598                         }
599
600                         if (!pairwise) {
601                                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
602                                         mode = WILC_FW_SEC_WPA_TKIP;
603                                 else
604                                         mode = WILC_FW_SEC_WPA2_AES;
605
606                                 priv->wilc_groupkey = mode;
607
608                                 key = priv->wilc_gtk[key_index];
609                         } else {
610                                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
611                                         mode = WILC_FW_SEC_WPA_TKIP;
612                                 else
613                                         mode = priv->wilc_groupkey | WILC_FW_AES;
614
615                                 key = priv->wilc_ptk[key_index];
616                         }
617                         ret = wilc_wfi_cfg_copy_wpa_info(key, params);
618                         if (ret)
619                                 return -ENOMEM;
620
621                         op_mode = WILC_AP_MODE;
622                 } else {
623                         if (params->key_len > 16 &&
624                             params->cipher == WLAN_CIPHER_SUITE_TKIP) {
625                                 rx_mic = params->key + 24;
626                                 tx_mic = params->key + 16;
627                                 keylen = params->key_len - 16;
628                         }
629
630                         op_mode = WILC_STATION_MODE;
631                 }
632
633                 if (!pairwise)
634                         ret = wilc_add_rx_gtk(vif, params->key, keylen,
635                                               key_index, params->seq_len,
636                                               params->seq, rx_mic, tx_mic,
637                                               op_mode, mode);
638                 else
639                         ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
640                                            rx_mic, tx_mic, op_mode, mode,
641                                            key_index);
642
643                 break;
644
645         default:
646                 netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
647                 ret = -ENOTSUPP;
648         }
649
650         return ret;
651 }
652
653 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
654                    u8 key_index,
655                    bool pairwise,
656                    const u8 *mac_addr)
657 {
658         struct wilc_vif *vif = netdev_priv(netdev);
659         struct wilc_priv *priv = &vif->priv;
660
661         if (priv->wilc_gtk[key_index]) {
662                 kfree(priv->wilc_gtk[key_index]->key);
663                 priv->wilc_gtk[key_index]->key = NULL;
664                 kfree(priv->wilc_gtk[key_index]->seq);
665                 priv->wilc_gtk[key_index]->seq = NULL;
666
667                 kfree(priv->wilc_gtk[key_index]);
668                 priv->wilc_gtk[key_index] = NULL;
669         }
670
671         if (priv->wilc_ptk[key_index]) {
672                 kfree(priv->wilc_ptk[key_index]->key);
673                 priv->wilc_ptk[key_index]->key = NULL;
674                 kfree(priv->wilc_ptk[key_index]->seq);
675                 priv->wilc_ptk[key_index]->seq = NULL;
676                 kfree(priv->wilc_ptk[key_index]);
677                 priv->wilc_ptk[key_index] = NULL;
678         }
679
680         if (key_index <= 3 && priv->wep_key_len[key_index]) {
681                 memset(priv->wep_key[key_index], 0,
682                        priv->wep_key_len[key_index]);
683                 priv->wep_key_len[key_index] = 0;
684                 wilc_remove_wep_key(vif, key_index);
685         }
686
687         return 0;
688 }
689
690 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
691                    bool pairwise, const u8 *mac_addr, void *cookie,
692                    void (*callback)(void *cookie, struct key_params *))
693 {
694         struct wilc_vif *vif = netdev_priv(netdev);
695         struct wilc_priv *priv = &vif->priv;
696         struct  key_params key_params;
697
698         if (!pairwise) {
699                 key_params.key = priv->wilc_gtk[key_index]->key;
700                 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
701                 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
702                 key_params.seq = priv->wilc_gtk[key_index]->seq;
703                 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
704         } else {
705                 key_params.key = priv->wilc_ptk[key_index]->key;
706                 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
707                 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
708                 key_params.seq = priv->wilc_ptk[key_index]->seq;
709                 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
710         }
711
712         callback(cookie, &key_params);
713
714         return 0;
715 }
716
717 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
718                            u8 key_index, bool unicast, bool multicast)
719 {
720         struct wilc_vif *vif = netdev_priv(netdev);
721
722         wilc_set_wep_default_keyid(vif, key_index);
723
724         return 0;
725 }
726
727 static int get_station(struct wiphy *wiphy, struct net_device *dev,
728                        const u8 *mac, struct station_info *sinfo)
729 {
730         struct wilc_vif *vif = netdev_priv(dev);
731         struct wilc_priv *priv = &vif->priv;
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                 wilc_get_statistics(vif, &stats);
759
760                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
761                                  BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
762                                  BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
763                                  BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
764                                  BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
765
766                 sinfo->signal = stats.rssi;
767                 sinfo->rx_packets = stats.rx_cnt;
768                 sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
769                 sinfo->tx_failed = stats.tx_fail_cnt;
770                 sinfo->txrate.legacy = stats.link_speed * 10;
771
772                 if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
773                     stats.link_speed != DEFAULT_LINK_SPEED)
774                         wilc_enable_tcp_ack_filter(vif, true);
775                 else if (stats.link_speed != DEFAULT_LINK_SPEED)
776                         wilc_enable_tcp_ack_filter(vif, false);
777         }
778         return 0;
779 }
780
781 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
782                       struct bss_parameters *params)
783 {
784         return 0;
785 }
786
787 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
788 {
789         int ret = -EINVAL;
790         struct cfg_param_attr cfg_param_val;
791         struct wilc *wl = wiphy_priv(wiphy);
792         struct wilc_vif *vif;
793         struct wilc_priv *priv;
794         int srcu_idx;
795
796         srcu_idx = srcu_read_lock(&wl->srcu);
797         vif = wilc_get_wl_to_vif(wl);
798         if (IS_ERR(vif))
799                 goto out;
800
801         priv = &vif->priv;
802         cfg_param_val.flag = 0;
803
804         if (changed & WIPHY_PARAM_RETRY_SHORT) {
805                 netdev_dbg(vif->ndev,
806                            "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
807                            wiphy->retry_short);
808                 cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
809                 cfg_param_val.short_retry_limit = wiphy->retry_short;
810         }
811         if (changed & WIPHY_PARAM_RETRY_LONG) {
812                 netdev_dbg(vif->ndev,
813                            "Setting WIPHY_PARAM_RETRY_LONG %d\n",
814                            wiphy->retry_long);
815                 cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
816                 cfg_param_val.long_retry_limit = wiphy->retry_long;
817         }
818         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
819                 if (wiphy->frag_threshold > 255 &&
820                     wiphy->frag_threshold < 7937) {
821                         netdev_dbg(vif->ndev,
822                                    "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
823                                    wiphy->frag_threshold);
824                         cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
825                         cfg_param_val.frag_threshold = wiphy->frag_threshold;
826                 } else {
827                         netdev_err(vif->ndev,
828                                    "Fragmentation threshold out of range\n");
829                         goto out;
830                 }
831         }
832
833         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
834                 if (wiphy->rts_threshold > 255) {
835                         netdev_dbg(vif->ndev,
836                                    "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
837                                    wiphy->rts_threshold);
838                         cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
839                         cfg_param_val.rts_threshold = wiphy->rts_threshold;
840                 } else {
841                         netdev_err(vif->ndev, "RTS threshold out of range\n");
842                         goto out;
843                 }
844         }
845
846         ret = wilc_hif_set_cfg(vif, &cfg_param_val);
847         if (ret)
848                 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
849
850 out:
851         srcu_read_unlock(&wl->srcu, srcu_idx);
852         return ret;
853 }
854
855 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
856                      struct cfg80211_pmksa *pmksa)
857 {
858         struct wilc_vif *vif = netdev_priv(netdev);
859         struct wilc_priv *priv = &vif->priv;
860         u32 i;
861         int ret = 0;
862         u8 flag = 0;
863
864         for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
865                 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
866                             ETH_ALEN)) {
867                         flag = PMKID_FOUND;
868                         break;
869                 }
870         }
871         if (i < WILC_MAX_NUM_PMKIDS) {
872                 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
873                        ETH_ALEN);
874                 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
875                        WLAN_PMKID_LEN);
876                 if (!(flag == PMKID_FOUND))
877                         priv->pmkid_list.numpmkid++;
878         } else {
879                 netdev_err(netdev, "Invalid PMKID index\n");
880                 ret = -EINVAL;
881         }
882
883         if (!ret)
884                 ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
885
886         return ret;
887 }
888
889 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
890                      struct cfg80211_pmksa *pmksa)
891 {
892         u32 i;
893         struct wilc_vif *vif = netdev_priv(netdev);
894         struct wilc_priv *priv = &vif->priv;
895
896         for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
897                 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
898                             ETH_ALEN)) {
899                         memset(&priv->pmkid_list.pmkidlist[i], 0,
900                                sizeof(struct wilc_pmkid));
901                         break;
902                 }
903         }
904
905         if (i == priv->pmkid_list.numpmkid)
906                 return -EINVAL;
907
908         for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
909                 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
910                        priv->pmkid_list.pmkidlist[i + 1].bssid,
911                        ETH_ALEN);
912                 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
913                        priv->pmkid_list.pmkidlist[i + 1].pmkid,
914                        WLAN_PMKID_LEN);
915         }
916         priv->pmkid_list.numpmkid--;
917
918         return 0;
919 }
920
921 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
922 {
923         struct wilc_vif *vif = netdev_priv(netdev);
924
925         memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
926
927         return 0;
928 }
929
930 static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
931 {
932         struct wilc_attr_entry *e;
933         struct wilc_attr_ch_list *ch_list;
934         struct wilc_attr_oper_ch *op_ch;
935         u32 index = 0;
936         u8 ch_list_idx = 0;
937         u8 op_ch_idx = 0;
938
939         if (sta_ch == WILC_INVALID_CHANNEL)
940                 return;
941
942         while (index + sizeof(*e) <= len) {
943                 e = (struct wilc_attr_entry *)&buf[index];
944                 if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
945                         ch_list_idx = index;
946                 else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
947                         op_ch_idx = index;
948                 if (ch_list_idx && op_ch_idx)
949                         break;
950                 index += le16_to_cpu(e->attr_len) + sizeof(*e);
951         }
952
953         if (ch_list_idx) {
954                 u16 attr_size;
955                 struct wilc_ch_list_elem *e;
956                 int i;
957
958                 ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
959                 attr_size = le16_to_cpu(ch_list->attr_len);
960                 for (i = 0; i < attr_size;) {
961                         e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
962                         if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
963                                 memset(e->ch_list, sta_ch, e->no_of_channels);
964                                 break;
965                         }
966                         i += e->no_of_channels;
967                 }
968         }
969
970         if (op_ch_idx) {
971                 op_ch = (struct wilc_attr_oper_ch *)&buf[op_ch_idx];
972                 op_ch->op_class = WILC_WLAN_OPERATING_CLASS_2_4GHZ;
973                 op_ch->op_channel = sta_ch;
974         }
975 }
976
977 void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
978 {
979         struct wilc *wl = vif->wilc;
980         struct wilc_priv *priv = &vif->priv;
981         struct host_if_drv *wfi_drv = priv->hif_drv;
982         struct ieee80211_mgmt *mgmt;
983         struct wilc_vendor_specific_ie *p;
984         struct wilc_p2p_pub_act_frame *d;
985         int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
986         const u8 *vendor_ie;
987         u32 header, pkt_offset;
988         s32 freq;
989
990         header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
991         pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
992
993         if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
994                 bool ack = false;
995                 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buff;
996
997                 if (ieee80211_is_probe_resp(hdr->frame_control) ||
998                     pkt_offset & IS_MGMT_STATUS_SUCCES)
999                         ack = true;
1000
1001                 cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
1002                                         size, ack, GFP_KERNEL);
1003                 return;
1004         }
1005
1006         freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
1007
1008         mgmt = (struct ieee80211_mgmt *)buff;
1009         if (!ieee80211_is_action(mgmt->frame_control))
1010                 goto out_rx_mgmt;
1011
1012         if (priv->cfg_scanning &&
1013             time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
1014                 netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
1015                 return;
1016         }
1017
1018         if (!ieee80211_is_public_action((struct ieee80211_hdr *)buff, size))
1019                 goto out_rx_mgmt;
1020
1021         d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
1022         if (d->oui_subtype != GO_NEG_REQ && d->oui_subtype != GO_NEG_RSP &&
1023             d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
1024                 goto out_rx_mgmt;
1025
1026         vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1027                                             buff + ie_offset, size - ie_offset);
1028         if (!vendor_ie)
1029                 goto out_rx_mgmt;
1030
1031         p = (struct wilc_vendor_specific_ie *)vendor_ie;
1032         wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
1033
1034 out_rx_mgmt:
1035         cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1036 }
1037
1038 static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
1039 {
1040         struct wilc_p2p_mgmt_data *pv_data = priv;
1041
1042         kfree(pv_data->buff);
1043         kfree(pv_data);
1044 }
1045
1046 static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
1047 {
1048         struct wilc_vif *vif = data;
1049         struct wilc_priv *priv = &vif->priv;
1050         struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
1051
1052         if (cookie != params->listen_cookie)
1053                 return;
1054
1055         priv->p2p_listen_state = false;
1056
1057         cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
1058                                            params->listen_ch, GFP_KERNEL);
1059 }
1060
1061 static int remain_on_channel(struct wiphy *wiphy,
1062                              struct wireless_dev *wdev,
1063                              struct ieee80211_channel *chan,
1064                              unsigned int duration, u64 *cookie)
1065 {
1066         int ret = 0;
1067         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1068         struct wilc_priv *priv = &vif->priv;
1069         u64 id;
1070
1071         if (wdev->iftype == NL80211_IFTYPE_AP) {
1072                 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1073                 return ret;
1074         }
1075
1076         id = ++priv->inc_roc_cookie;
1077         if (id == 0)
1078                 id = ++priv->inc_roc_cookie;
1079
1080         ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
1081                                      wilc_wfi_remain_on_channel_expired,
1082                                      (void *)vif);
1083         if (ret)
1084                 return ret;
1085
1086         vif->wilc->op_ch = chan->hw_value;
1087
1088         priv->remain_on_ch_params.listen_ch = chan;
1089         priv->remain_on_ch_params.listen_cookie = id;
1090         *cookie = id;
1091         priv->p2p_listen_state = true;
1092         priv->remain_on_ch_params.listen_duration = duration;
1093
1094         cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
1095         mod_timer(&vif->hif_drv->remain_on_ch_timer,
1096                   jiffies + msecs_to_jiffies(duration + 1000));
1097
1098         return ret;
1099 }
1100
1101 static int cancel_remain_on_channel(struct wiphy *wiphy,
1102                                     struct wireless_dev *wdev,
1103                                     u64 cookie)
1104 {
1105         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1106         struct wilc_priv *priv = &vif->priv;
1107
1108         if (cookie != priv->remain_on_ch_params.listen_cookie)
1109                 return -ENOENT;
1110
1111         return wilc_listen_state_expired(vif, cookie);
1112 }
1113
1114 static int mgmt_tx(struct wiphy *wiphy,
1115                    struct wireless_dev *wdev,
1116                    struct cfg80211_mgmt_tx_params *params,
1117                    u64 *cookie)
1118 {
1119         struct ieee80211_channel *chan = params->chan;
1120         unsigned int wait = params->wait;
1121         const u8 *buf = params->buf;
1122         size_t len = params->len;
1123         const struct ieee80211_mgmt *mgmt;
1124         struct wilc_p2p_mgmt_data *mgmt_tx;
1125         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1126         struct wilc_priv *priv = &vif->priv;
1127         struct host_if_drv *wfi_drv = priv->hif_drv;
1128         struct wilc_vendor_specific_ie *p;
1129         struct wilc_p2p_pub_act_frame *d;
1130         int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
1131         const u8 *vendor_ie;
1132         int ret = 0;
1133
1134         *cookie = prandom_u32();
1135         priv->tx_cookie = *cookie;
1136         mgmt = (const struct ieee80211_mgmt *)buf;
1137
1138         if (!ieee80211_is_mgmt(mgmt->frame_control))
1139                 goto out;
1140
1141         mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
1142         if (!mgmt_tx) {
1143                 ret = -ENOMEM;
1144                 goto out;
1145         }
1146
1147         mgmt_tx->buff = kmemdup(buf, len, GFP_KERNEL);
1148         if (!mgmt_tx->buff) {
1149                 ret = -ENOMEM;
1150                 kfree(mgmt_tx);
1151                 goto out;
1152         }
1153
1154         mgmt_tx->size = len;
1155
1156         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1157                 wilc_set_mac_chnl_num(vif, chan->hw_value);
1158                 vif->wilc->op_ch = chan->hw_value;
1159                 goto out_txq_add_pkt;
1160         }
1161
1162         if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len))
1163                 goto out_set_timeout;
1164
1165         d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
1166         if (d->oui_type != WLAN_OUI_TYPE_WFA_P2P ||
1167             d->oui_subtype != GO_NEG_CONF) {
1168                 wilc_set_mac_chnl_num(vif, chan->hw_value);
1169                 vif->wilc->op_ch = chan->hw_value;
1170         }
1171
1172         if (d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
1173                 goto out_set_timeout;
1174
1175         vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1176                                             mgmt_tx->buff + ie_offset,
1177                                             len - ie_offset);
1178         if (!vendor_ie)
1179                 goto out_set_timeout;
1180
1181         p = (struct wilc_vendor_specific_ie *)vendor_ie;
1182         wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
1183
1184 out_set_timeout:
1185         wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1186
1187 out_txq_add_pkt:
1188
1189         wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1190                                    mgmt_tx->buff, mgmt_tx->size,
1191                                    wilc_wfi_mgmt_tx_complete);
1192
1193 out:
1194
1195         return ret;
1196 }
1197
1198 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1199                                struct wireless_dev *wdev,
1200                                u64 cookie)
1201 {
1202         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1203         struct wilc_priv *priv = &vif->priv;
1204         struct host_if_drv *wfi_drv = priv->hif_drv;
1205
1206         wfi_drv->p2p_timeout = jiffies;
1207
1208         if (!priv->p2p_listen_state) {
1209                 struct wilc_wfi_p2p_listen_params *params;
1210
1211                 params = &priv->remain_on_ch_params;
1212
1213                 cfg80211_remain_on_channel_expired(wdev,
1214                                                    params->listen_cookie,
1215                                                    params->listen_ch,
1216                                                    GFP_KERNEL);
1217         }
1218
1219         return 0;
1220 }
1221
1222 void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
1223                                           struct wireless_dev *wdev,
1224                                           struct mgmt_frame_regs *upd)
1225 {
1226         struct wilc *wl = wiphy_priv(wiphy);
1227         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1228         u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
1229         u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4);
1230
1231         if (wl->initialized) {
1232                 bool prev = vif->mgmt_reg_stypes & presp_bit;
1233                 bool now = upd->interface_stypes & presp_bit;
1234
1235                 if (now != prev)
1236                         wilc_frame_register(vif, IEEE80211_STYPE_PROBE_REQ, now);
1237
1238                 prev = vif->mgmt_reg_stypes & action_bit;
1239                 now = upd->interface_stypes & action_bit;
1240
1241                 if (now != prev)
1242                         wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now);
1243         }
1244
1245         vif->mgmt_reg_stypes =
1246                 upd->interface_stypes & (presp_bit | action_bit);
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         .update_mgmt_frame_registrations = wilc_update_mgmt_frame_registrations,
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, i;
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
1729         for (i = 0; i < NQUEUES; i++)
1730                 INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
1731
1732         INIT_LIST_HEAD(&wl->rxq_head.list);
1733         INIT_LIST_HEAD(&wl->vif_list);
1734
1735         wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
1736         if (!wl->hif_workqueue) {
1737                 ret = -ENOMEM;
1738                 goto free_cfg;
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_hq;
1745         }
1746
1747         return 0;
1748
1749 free_hq:
1750         destroy_workqueue(wl->hif_workqueue);
1751
1752 free_cfg:
1753         wilc_wlan_cfg_deinit(wl);
1754
1755 free_wl:
1756         wlan_deinit_locks(wl);
1757         wiphy_unregister(wl->wiphy);
1758         wiphy_free(wl->wiphy);
1759         return ret;
1760 }
1761 EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
1762
1763 struct wilc *wilc_create_wiphy(struct device *dev)
1764 {
1765         struct wiphy *wiphy;
1766         struct wilc *wl;
1767         int ret;
1768
1769         wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
1770         if (!wiphy)
1771                 return NULL;
1772
1773         wl = wiphy_priv(wiphy);
1774
1775         memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
1776         memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
1777         wl->band.bitrates = wl->bitrates;
1778         wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
1779         wl->band.channels = wl->channels;
1780         wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
1781
1782         wl->band.ht_cap.ht_supported = 1;
1783         wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
1784         wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
1785         wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
1786         wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1787
1788         wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
1789
1790         wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
1791 #ifdef CONFIG_PM
1792         wiphy->wowlan = &wowlan_support;
1793 #endif
1794         wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
1795         wiphy->max_scan_ie_len = 1000;
1796         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1797         memcpy(wl->cipher_suites, wilc_cipher_suites,
1798                sizeof(wilc_cipher_suites));
1799         wiphy->cipher_suites = wl->cipher_suites;
1800         wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
1801         wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
1802
1803         wiphy->max_remain_on_channel_duration = 500;
1804         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1805                                 BIT(NL80211_IFTYPE_AP) |
1806                                 BIT(NL80211_IFTYPE_MONITOR) |
1807                                 BIT(NL80211_IFTYPE_P2P_GO) |
1808                                 BIT(NL80211_IFTYPE_P2P_CLIENT);
1809         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
1810
1811         set_wiphy_dev(wiphy, dev);
1812         wl->wiphy = wiphy;
1813         ret = wiphy_register(wiphy);
1814         if (ret) {
1815                 wiphy_free(wiphy);
1816                 return NULL;
1817         }
1818         return wl;
1819 }
1820
1821 int wilc_init_host_int(struct net_device *net)
1822 {
1823         int ret;
1824         struct wilc_vif *vif = netdev_priv(net);
1825         struct wilc_priv *priv = &vif->priv;
1826
1827         priv->p2p_listen_state = false;
1828
1829         mutex_init(&priv->scan_req_lock);
1830         ret = wilc_init(net, &priv->hif_drv);
1831         if (ret)
1832                 netdev_err(net, "Error while initializing hostinterface\n");
1833
1834         return ret;
1835 }
1836
1837 void wilc_deinit_host_int(struct net_device *net)
1838 {
1839         int ret;
1840         struct wilc_vif *vif = netdev_priv(net);
1841         struct wilc_priv *priv = &vif->priv;
1842
1843         priv->p2p_listen_state = false;
1844
1845         flush_workqueue(vif->wilc->hif_workqueue);
1846         mutex_destroy(&priv->scan_req_lock);
1847         ret = wilc_deinit(vif);
1848
1849         if (ret)
1850                 netdev_err(net, "Error while deinitializing host interface\n");
1851 }
1852
This page took 0.149102 seconds and 4 git commands to generate.