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