1
2#include "wilc_wfi_cfgoperations.h"
3
4#define NO_ENCRYPT 0
5#define ENCRYPT_ENABLED BIT(0)
6#define WEP BIT(1)
7#define WEP_EXTENDED BIT(2)
8#define WPA BIT(3)
9#define WPA2 BIT(4)
10#define AES BIT(5)
11#define TKIP BIT(6)
12
13#define FRAME_TYPE_ID 0
14#define ACTION_CAT_ID 24
15#define ACTION_SUBTYPE_ID 25
16#define P2P_PUB_ACTION_SUBTYPE 30
17
18#define ACTION_FRAME 0xd0
19#define GO_INTENT_ATTR_ID 0x04
20#define CHANLIST_ATTR_ID 0x0b
21#define OPERCHAN_ATTR_ID 0x11
22#define PUB_ACTION_ATTR_ID 0x04
23#define P2PELEM_ATTR_ID 0xdd
24
25#define GO_NEG_REQ 0x00
26#define GO_NEG_RSP 0x01
27#define GO_NEG_CONF 0x02
28#define P2P_INV_REQ 0x03
29#define P2P_INV_RSP 0x04
30#define PUBLIC_ACT_VENDORSPEC 0x09
31#define GAS_INITIAL_REQ 0x0a
32#define GAS_INITIAL_RSP 0x0b
33
34#define INVALID_CHANNEL 0
35
36#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
37#define SCAN_RESULT_EXPIRE (40 * HZ)
38
39static const u32 cipher_suites[] = {
40 WLAN_CIPHER_SUITE_WEP40,
41 WLAN_CIPHER_SUITE_WEP104,
42 WLAN_CIPHER_SUITE_TKIP,
43 WLAN_CIPHER_SUITE_CCMP,
44 WLAN_CIPHER_SUITE_AES_CMAC,
45};
46
47static const struct ieee80211_txrx_stypes
48 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
49 [NL80211_IFTYPE_STATION] = {
50 .tx = 0xffff,
51 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
52 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
53 },
54 [NL80211_IFTYPE_AP] = {
55 .tx = 0xffff,
56 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
57 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
58 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
59 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
60 BIT(IEEE80211_STYPE_AUTH >> 4) |
61 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
62 BIT(IEEE80211_STYPE_ACTION >> 4)
63 },
64 [NL80211_IFTYPE_P2P_CLIENT] = {
65 .tx = 0xffff,
66 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
67 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
68 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
69 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
70 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
71 BIT(IEEE80211_STYPE_AUTH >> 4) |
72 BIT(IEEE80211_STYPE_DEAUTH >> 4)
73 }
74};
75
76static const struct wiphy_wowlan_support wowlan_support = {
77 .flags = WIPHY_WOWLAN_ANY
78};
79
80#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
81#define DEFAULT_LINK_SPEED 72
82
83#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
84
85static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
86static u32 last_scanned_cnt;
87struct timer_list wilc_during_ip_timer;
88static struct timer_list aging_timer;
89static u8 op_ifcs;
90
91#define CHAN2G(_channel, _freq, _flags) { \
92 .band = NL80211_BAND_2GHZ, \
93 .center_freq = (_freq), \
94 .hw_value = (_channel), \
95 .flags = (_flags), \
96 .max_antenna_gain = 0, \
97 .max_power = 30, \
98}
99
100static struct ieee80211_channel ieee80211_2ghz_channels[] = {
101 CHAN2G(1, 2412, 0),
102 CHAN2G(2, 2417, 0),
103 CHAN2G(3, 2422, 0),
104 CHAN2G(4, 2427, 0),
105 CHAN2G(5, 2432, 0),
106 CHAN2G(6, 2437, 0),
107 CHAN2G(7, 2442, 0),
108 CHAN2G(8, 2447, 0),
109 CHAN2G(9, 2452, 0),
110 CHAN2G(10, 2457, 0),
111 CHAN2G(11, 2462, 0),
112 CHAN2G(12, 2467, 0),
113 CHAN2G(13, 2472, 0),
114 CHAN2G(14, 2484, 0),
115};
116
117#define RATETAB_ENT(_rate, _hw_value, _flags) { \
118 .bitrate = (_rate), \
119 .hw_value = (_hw_value), \
120 .flags = (_flags), \
121}
122
123static struct ieee80211_rate ieee80211_bitrates[] = {
124 RATETAB_ENT(10, 0, 0),
125 RATETAB_ENT(20, 1, 0),
126 RATETAB_ENT(55, 2, 0),
127 RATETAB_ENT(110, 3, 0),
128 RATETAB_ENT(60, 9, 0),
129 RATETAB_ENT(90, 6, 0),
130 RATETAB_ENT(120, 7, 0),
131 RATETAB_ENT(180, 8, 0),
132 RATETAB_ENT(240, 9, 0),
133 RATETAB_ENT(360, 10, 0),
134 RATETAB_ENT(480, 11, 0),
135 RATETAB_ENT(540, 12, 0),
136};
137
138struct p2p_mgmt_data {
139 int size;
140 u8 *buff;
141};
142
143static u8 wlan_channel = INVALID_CHANNEL;
144static u8 curr_channel;
145static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
146static u8 p2p_local_random = 0x01;
147static u8 p2p_recv_random;
148static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
149static bool wilc_ie;
150
151static struct ieee80211_supported_band wilc_band_2ghz = {
152 .channels = ieee80211_2ghz_channels,
153 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
154 .bitrates = ieee80211_bitrates,
155 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
156};
157
158#define AGING_TIME (9 * 1000)
159#define DURING_IP_TIME_OUT 15000
160
161static void clear_shadow_scan(void)
162{
163 int i;
164
165 if (op_ifcs != 0)
166 return;
167
168 del_timer_sync(&aging_timer);
169
170 for (i = 0; i < last_scanned_cnt; i++) {
171 if (last_scanned_shadow[last_scanned_cnt].ies) {
172 kfree(last_scanned_shadow[i].ies);
173 last_scanned_shadow[last_scanned_cnt].ies = NULL;
174 }
175
176 kfree(last_scanned_shadow[i].join_params);
177 last_scanned_shadow[i].join_params = NULL;
178 }
179 last_scanned_cnt = 0;
180}
181
182static u32 get_rssi_avg(struct network_info *network_info)
183{
184 u8 i;
185 int rssi_v = 0;
186 u8 num_rssi = (network_info->rssi_history.full) ?
187 NUM_RSSI : (network_info->rssi_history.index);
188
189 for (i = 0; i < num_rssi; i++)
190 rssi_v += network_info->rssi_history.samples[i];
191
192 rssi_v /= num_rssi;
193 return rssi_v;
194}
195
196static void refresh_scan(struct wilc_priv *priv, bool direct_scan)
197{
198 struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
199 int i;
200
201 for (i = 0; i < last_scanned_cnt; i++) {
202 struct network_info *network_info;
203 s32 freq;
204 struct ieee80211_channel *channel;
205 int rssi;
206 struct cfg80211_bss *bss;
207
208 network_info = &last_scanned_shadow[i];
209
210 if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan)
211 continue;
212
213 freq = ieee80211_channel_to_frequency((s32)network_info->ch,
214 NL80211_BAND_2GHZ);
215 channel = ieee80211_get_channel(wiphy, freq);
216 rssi = get_rssi_avg(network_info);
217 bss = cfg80211_inform_bss(wiphy,
218 channel,
219 CFG80211_BSS_FTYPE_UNKNOWN,
220 network_info->bssid,
221 network_info->tsf_hi,
222 network_info->cap_info,
223 network_info->beacon_period,
224 (const u8 *)network_info->ies,
225 (size_t)network_info->ies_len,
226 (s32)rssi * 100,
227 GFP_KERNEL);
228 cfg80211_put_bss(wiphy, bss);
229 }
230}
231
232static void reset_shadow_found(void)
233{
234 int i;
235
236 for (i = 0; i < last_scanned_cnt; i++)
237 last_scanned_shadow[i].found = 0;
238}
239
240static void update_scan_time(void)
241{
242 int i;
243
244 for (i = 0; i < last_scanned_cnt; i++)
245 last_scanned_shadow[i].time_scan = jiffies;
246}
247
248static void remove_network_from_shadow(struct timer_list *unused)
249{
250 unsigned long now = jiffies;
251 int i, j;
252
253 for (i = 0; i < last_scanned_cnt; i++) {
254 if (!time_after(now, last_scanned_shadow[i].time_scan +
255 (unsigned long)(SCAN_RESULT_EXPIRE)))
256 continue;
257 kfree(last_scanned_shadow[i].ies);
258 last_scanned_shadow[i].ies = NULL;
259
260 kfree(last_scanned_shadow[i].join_params);
261
262 for (j = i; (j < last_scanned_cnt - 1); j++)
263 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
264
265 last_scanned_cnt--;
266 }
267
268 if (last_scanned_cnt != 0)
269 mod_timer(&aging_timer, jiffies + msecs_to_jiffies(AGING_TIME));
270}
271
272static void clear_during_ip(struct timer_list *unused)
273{
274 wilc_optaining_ip = false;
275}
276
277static int is_network_in_shadow(struct network_info *nw_info, void *user_void)
278{
279 int state = -1;
280 int i;
281
282 if (last_scanned_cnt == 0) {
283 mod_timer(&aging_timer, jiffies + msecs_to_jiffies(AGING_TIME));
284 state = -1;
285 } else {
286 for (i = 0; i < last_scanned_cnt; i++) {
287 if (memcmp(last_scanned_shadow[i].bssid,
288 nw_info->bssid, 6) == 0) {
289 state = i;
290 break;
291 }
292 }
293 }
294 return state;
295}
296
297static void add_network_to_shadow(struct network_info *nw_info,
298 void *user_void, void *join_params)
299{
300 int ap_found = is_network_in_shadow(nw_info, user_void);
301 u32 ap_index = 0;
302 u8 rssi_index = 0;
303 struct network_info *shadow_nw_info;
304
305 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
306 return;
307
308 if (ap_found == -1) {
309 ap_index = last_scanned_cnt;
310 last_scanned_cnt++;
311 } else {
312 ap_index = ap_found;
313 }
314 shadow_nw_info = &last_scanned_shadow[ap_index];
315 rssi_index = shadow_nw_info->rssi_history.index;
316 shadow_nw_info->rssi_history.samples[rssi_index++] = nw_info->rssi;
317 if (rssi_index == NUM_RSSI) {
318 rssi_index = 0;
319 shadow_nw_info->rssi_history.full = true;
320 }
321 shadow_nw_info->rssi_history.index = rssi_index;
322 shadow_nw_info->rssi = nw_info->rssi;
323 shadow_nw_info->cap_info = nw_info->cap_info;
324 shadow_nw_info->ssid_len = nw_info->ssid_len;
325 memcpy(shadow_nw_info->ssid, nw_info->ssid, nw_info->ssid_len);
326 memcpy(shadow_nw_info->bssid, nw_info->bssid, ETH_ALEN);
327 shadow_nw_info->beacon_period = nw_info->beacon_period;
328 shadow_nw_info->dtim_period = nw_info->dtim_period;
329 shadow_nw_info->ch = nw_info->ch;
330 shadow_nw_info->tsf_hi = nw_info->tsf_hi;
331 if (ap_found != -1)
332 kfree(shadow_nw_info->ies);
333 shadow_nw_info->ies = kmemdup(nw_info->ies, nw_info->ies_len,
334 GFP_KERNEL);
335 if (shadow_nw_info->ies)
336 shadow_nw_info->ies_len = nw_info->ies_len;
337 else
338 shadow_nw_info->ies_len = 0;
339 shadow_nw_info->time_scan = jiffies;
340 shadow_nw_info->time_scan_cached = jiffies;
341 shadow_nw_info->found = 1;
342 if (ap_found != -1)
343 kfree(shadow_nw_info->join_params);
344 shadow_nw_info->join_params = join_params;
345}
346
347static void cfg_scan_result(enum scan_event scan_event,
348 struct network_info *network_info,
349 void *user_void, void *join_params)
350{
351 struct wilc_priv *priv;
352 struct wiphy *wiphy;
353 s32 freq;
354 struct ieee80211_channel *channel;
355 struct cfg80211_bss *bss = NULL;
356
357 priv = user_void;
358 if (!priv->cfg_scanning)
359 return;
360
361 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
362 wiphy = priv->dev->ieee80211_ptr->wiphy;
363
364 if (!wiphy || !network_info)
365 return;
366
367 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
368 (((s32)network_info->rssi * 100) < 0 ||
369 ((s32)network_info->rssi * 100) > 100))
370 return;
371
372 freq = ieee80211_channel_to_frequency((s32)network_info->ch,
373 NL80211_BAND_2GHZ);
374 channel = ieee80211_get_channel(wiphy, freq);
375
376 if (!channel)
377 return;
378
379 if (network_info->new_network) {
380 if (priv->rcvd_ch_cnt >= MAX_NUM_SCANNED_NETWORKS)
381 return;
382
383 priv->rcvd_ch_cnt++;
384
385 add_network_to_shadow(network_info, priv, join_params);
386
387 if (memcmp("DIRECT-", network_info->ssid, 7))
388 return;
389
390 bss = cfg80211_inform_bss(wiphy,
391 channel,
392 CFG80211_BSS_FTYPE_UNKNOWN,
393 network_info->bssid,
394 network_info->tsf_hi,
395 network_info->cap_info,
396 network_info->beacon_period,
397 (const u8 *)network_info->ies,
398 (size_t)network_info->ies_len,
399 (s32)network_info->rssi * 100,
400 GFP_KERNEL);
401 cfg80211_put_bss(wiphy, bss);
402 } else {
403 u32 i;
404
405 for (i = 0; i < priv->rcvd_ch_cnt; i++) {
406 if (memcmp(last_scanned_shadow[i].bssid,
407 network_info->bssid, 6) == 0)
408 break;
409 }
410
411 if (i >= priv->rcvd_ch_cnt)
412 return;
413
414 last_scanned_shadow[i].rssi = network_info->rssi;
415 last_scanned_shadow[i].time_scan = jiffies;
416 }
417 } else if (scan_event == SCAN_EVENT_DONE) {
418 refresh_scan(priv, false);
419
420 mutex_lock(&priv->scan_req_lock);
421
422 if (priv->scan_req) {
423 struct cfg80211_scan_info info = {
424 .aborted = false,
425 };
426
427 cfg80211_scan_done(priv->scan_req, &info);
428 priv->rcvd_ch_cnt = 0;
429 priv->cfg_scanning = false;
430 priv->scan_req = NULL;
431 }
432 mutex_unlock(&priv->scan_req_lock);
433 } else if (scan_event == SCAN_EVENT_ABORTED) {
434 mutex_lock(&priv->scan_req_lock);
435
436 if (priv->scan_req) {
437 struct cfg80211_scan_info info = {
438 .aborted = false,
439 };
440
441 update_scan_time();
442 refresh_scan(priv, false);
443
444 cfg80211_scan_done(priv->scan_req, &info);
445 priv->cfg_scanning = false;
446 priv->scan_req = NULL;
447 }
448 mutex_unlock(&priv->scan_req_lock);
449 }
450}
451
452static inline bool wilc_wfi_cfg_scan_time_expired(int i)
453{
454 unsigned long now = jiffies;
455
456 if (time_after(now, last_scanned_shadow[i].time_scan_cached +
457 (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
458 return true;
459 else
460 return false;
461}
462
463int wilc_connecting;
464
465static void cfg_connect_result(enum conn_event conn_disconn_evt,
466 struct connect_info *conn_info,
467 u8 mac_status,
468 struct disconnect_info *disconn_info,
469 void *priv_data)
470{
471 struct wilc_priv *priv;
472 struct net_device *dev;
473 struct host_if_drv *wfi_drv;
474 u8 null_bssid[ETH_ALEN] = {0};
475 struct wilc *wl;
476 struct wilc_vif *vif;
477
478 wilc_connecting = 0;
479
480 priv = priv_data;
481 dev = priv->dev;
482 vif = netdev_priv(dev);
483 wl = vif->wilc;
484 wfi_drv = (struct host_if_drv *)priv->hif_drv;
485
486 if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
487 u16 connect_status;
488
489 connect_status = conn_info->status;
490
491 if (mac_status == MAC_STATUS_DISCONNECTED &&
492 conn_info->status == SUCCESSFUL_STATUSCODE) {
493 connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
494 wilc_wlan_set_bssid(priv->dev, null_bssid,
495 STATION_MODE);
496 eth_zero_addr(wilc_connected_ssid);
497
498 if (!wfi_drv->p2p_connect)
499 wlan_channel = INVALID_CHANNEL;
500
501 netdev_err(dev, "Unspecified failure\n");
502 }
503
504 if (connect_status == WLAN_STATUS_SUCCESS) {
505 bool scan_refresh = false;
506 u32 i;
507
508 memcpy(priv->associated_bss, conn_info->bssid,
509 ETH_ALEN);
510
511 for (i = 0; i < last_scanned_cnt; i++) {
512 if (memcmp(last_scanned_shadow[i].bssid,
513 conn_info->bssid,
514 ETH_ALEN) == 0) {
515 if (wilc_wfi_cfg_scan_time_expired(i))
516 scan_refresh = true;
517
518 break;
519 }
520 }
521
522 if (scan_refresh)
523 refresh_scan(priv, true);
524 }
525
526 cfg80211_connect_result(dev, conn_info->bssid,
527 conn_info->req_ies,
528 conn_info->req_ies_len,
529 conn_info->resp_ies,
530 conn_info->resp_ies_len, connect_status,
531 GFP_KERNEL);
532 } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
533 wilc_optaining_ip = false;
534 p2p_local_random = 0x01;
535 p2p_recv_random = 0x00;
536 wilc_ie = false;
537 eth_zero_addr(priv->associated_bss);
538 wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE);
539 eth_zero_addr(wilc_connected_ssid);
540
541 if (!wfi_drv->p2p_connect)
542 wlan_channel = INVALID_CHANNEL;
543 if (wfi_drv->IFC_UP && dev == wl->vif[1]->ndev)
544 disconn_info->reason = 3;
545 else if (!wfi_drv->IFC_UP && dev == wl->vif[1]->ndev)
546 disconn_info->reason = 1;
547
548 cfg80211_disconnected(dev, disconn_info->reason,
549 disconn_info->ie, disconn_info->ie_len,
550 false, GFP_KERNEL);
551 }
552}
553
554static int set_channel(struct wiphy *wiphy,
555 struct cfg80211_chan_def *chandef)
556{
557 u32 channelnum = 0;
558 struct wilc_priv *priv;
559 int result = 0;
560 struct wilc_vif *vif;
561
562 priv = wiphy_priv(wiphy);
563 vif = netdev_priv(priv->dev);
564
565 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
566
567 curr_channel = channelnum;
568 result = wilc_set_mac_chnl_num(vif, channelnum);
569
570 if (result != 0)
571 netdev_err(priv->dev, "Error in setting channel\n");
572
573 return result;
574}
575
576static inline int
577wilc_wfi_cfg_alloc_fill_ssid(struct cfg80211_scan_request *request,
578 struct hidden_network *ntwk)
579{
580 int i;
581 int slot_id = 0;
582
583 ntwk->net_info = kcalloc(request->n_ssids, sizeof(*ntwk->net_info),
584 GFP_KERNEL);
585 if (!ntwk->net_info)
586 goto out;
587
588 ntwk->n_ssids = request->n_ssids;
589
590 for (i = 0; i < request->n_ssids; i++) {
591 if (request->ssids[i].ssid_len > 0) {
592 struct hidden_net_info *info = &ntwk->net_info[slot_id];
593
594 info->ssid = kmemdup(request->ssids[i].ssid,
595 request->ssids[i].ssid_len,
596 GFP_KERNEL);
597 if (!info->ssid)
598 goto out_free;
599
600 info->ssid_len = request->ssids[i].ssid_len;
601 slot_id++;
602 } else {
603 ntwk->n_ssids -= 1;
604 }
605 }
606 return 0;
607
608out_free:
609
610 for (i = 0; i < slot_id; i++)
611 kfree(ntwk->net_info[i].ssid);
612
613 kfree(ntwk->net_info);
614out:
615
616 return -ENOMEM;
617}
618
619static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
620{
621 struct wilc_priv *priv;
622 u32 i;
623 s32 ret = 0;
624 u8 scan_ch_list[MAX_NUM_SCANNED_NETWORKS];
625 struct hidden_network hidden_ntwk;
626 struct wilc_vif *vif;
627
628 priv = wiphy_priv(wiphy);
629 vif = netdev_priv(priv->dev);
630
631 priv->scan_req = request;
632
633 priv->rcvd_ch_cnt = 0;
634
635 reset_shadow_found();
636
637 priv->cfg_scanning = true;
638 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
639 for (i = 0; i < request->n_channels; i++) {
640 u16 freq = request->channels[i]->center_freq;
641
642 scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
643 }
644
645 if (request->n_ssids >= 1) {
646 if (wilc_wfi_cfg_alloc_fill_ssid(request,
647 &hidden_ntwk))
648 return -ENOMEM;
649
650 ret = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
651 scan_ch_list,
652 request->n_channels,
653 (const u8 *)request->ie,
654 request->ie_len, cfg_scan_result,
655 (void *)priv, &hidden_ntwk);
656 } else {
657 ret = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
658 scan_ch_list,
659 request->n_channels,
660 (const u8 *)request->ie,
661 request->ie_len, cfg_scan_result,
662 (void *)priv, NULL);
663 }
664 } else {
665 netdev_err(priv->dev, "Requested scanned channels over\n");
666 }
667
668 if (ret != 0)
669 ret = -EBUSY;
670
671 return ret;
672}
673
674static int connect(struct wiphy *wiphy, struct net_device *dev,
675 struct cfg80211_connect_params *sme)
676{
677 s32 ret = 0;
678 u32 i;
679 u32 sel_bssi_idx = UINT_MAX;
680 u8 security = NO_ENCRYPT;
681 enum AUTHTYPE auth_type = ANY;
682 u32 cipher_group;
683 struct wilc_priv *priv;
684 struct host_if_drv *wfi_drv;
685 struct network_info *nw_info = NULL;
686 struct wilc_vif *vif;
687
688 wilc_connecting = 1;
689 priv = wiphy_priv(wiphy);
690 vif = netdev_priv(priv->dev);
691 wfi_drv = (struct host_if_drv *)priv->hif_drv;
692
693 if (!(strncmp(sme->ssid, "DIRECT-", 7)))
694 wfi_drv->p2p_connect = 1;
695 else
696 wfi_drv->p2p_connect = 0;
697
698 for (i = 0; i < last_scanned_cnt; i++) {
699 if (sme->ssid_len == last_scanned_shadow[i].ssid_len &&
700 memcmp(last_scanned_shadow[i].ssid,
701 sme->ssid,
702 sme->ssid_len) == 0) {
703 if (!sme->bssid) {
704 if (sel_bssi_idx == UINT_MAX ||
705 last_scanned_shadow[i].rssi >
706 last_scanned_shadow[sel_bssi_idx].rssi)
707 sel_bssi_idx = i;
708 } else {
709 if (memcmp(last_scanned_shadow[i].bssid,
710 sme->bssid,
711 ETH_ALEN) == 0) {
712 sel_bssi_idx = i;
713 break;
714 }
715 }
716 }
717 }
718
719 if (sel_bssi_idx < last_scanned_cnt) {
720 nw_info = &last_scanned_shadow[sel_bssi_idx];
721 } else {
722 ret = -ENOENT;
723 wilc_connecting = 0;
724 return ret;
725 }
726
727 memset(priv->wep_key, 0, sizeof(priv->wep_key));
728 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
729
730 cipher_group = sme->crypto.cipher_group;
731 if (cipher_group != NO_ENCRYPT) {
732 if (cipher_group == WLAN_CIPHER_SUITE_WEP40) {
733 security = ENCRYPT_ENABLED | WEP;
734
735 priv->wep_key_len[sme->key_idx] = sme->key_len;
736 memcpy(priv->wep_key[sme->key_idx], sme->key,
737 sme->key_len);
738
739 wilc_set_wep_default_keyid(vif, sme->key_idx);
740 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
741 sme->key_idx);
742 } else if (cipher_group == WLAN_CIPHER_SUITE_WEP104) {
743 security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
744
745 priv->wep_key_len[sme->key_idx] = sme->key_len;
746 memcpy(priv->wep_key[sme->key_idx], sme->key,
747 sme->key_len);
748
749 wilc_set_wep_default_keyid(vif, sme->key_idx);
750 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
751 sme->key_idx);
752 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
753 if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
754 security = ENCRYPT_ENABLED | WPA2 | TKIP;
755 else
756 security = ENCRYPT_ENABLED | WPA2 | AES;
757 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
758 if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
759 security = ENCRYPT_ENABLED | WPA | TKIP;
760 else
761 security = ENCRYPT_ENABLED | WPA | AES;
762 } else {
763 ret = -ENOTSUPP;
764 netdev_err(dev, "Not supported cipher\n");
765 wilc_connecting = 0;
766 return ret;
767 }
768 }
769
770 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
771 (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
772 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
773 u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];
774
775 if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
776 security = security | TKIP;
777 else
778 security = security | AES;
779 }
780 }
781
782 switch (sme->auth_type) {
783 case NL80211_AUTHTYPE_OPEN_SYSTEM:
784 auth_type = OPEN_SYSTEM;
785 break;
786
787 case NL80211_AUTHTYPE_SHARED_KEY:
788 auth_type = SHARED_KEY;
789 break;
790
791 default:
792 break;
793 }
794
795 if (sme->crypto.n_akm_suites) {
796 if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
797 auth_type = IEEE8021;
798 }
799
800 curr_channel = nw_info->ch;
801
802 if (!wfi_drv->p2p_connect)
803 wlan_channel = nw_info->ch;
804
805 wilc_wlan_set_bssid(dev, nw_info->bssid, STATION_MODE);
806
807 ret = wilc_set_join_req(vif, nw_info->bssid, sme->ssid,
808 sme->ssid_len, sme->ie, sme->ie_len,
809 cfg_connect_result, (void *)priv,
810 security, auth_type,
811 nw_info->ch,
812 nw_info->join_params);
813 if (ret != 0) {
814 netdev_err(dev, "wilc_set_join_req(): Error\n");
815 ret = -ENOENT;
816 wilc_connecting = 0;
817 return ret;
818 }
819
820 return ret;
821}
822
823static int disconnect(struct wiphy *wiphy, struct net_device *dev,
824 u16 reason_code)
825{
826 s32 ret = 0;
827 struct wilc_priv *priv;
828 struct host_if_drv *wfi_drv;
829 struct wilc_vif *vif;
830 struct wilc *wilc;
831 u8 null_bssid[ETH_ALEN] = {0};
832
833 wilc_connecting = 0;
834 priv = wiphy_priv(wiphy);
835 vif = netdev_priv(priv->dev);
836 wilc = vif->wilc;
837
838 if (!wilc)
839 return -EIO;
840
841 if (wilc->close) {
842
843 cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
844 return 0;
845 }
846
847 wfi_drv = (struct host_if_drv *)priv->hif_drv;
848 if (!wfi_drv->p2p_connect)
849 wlan_channel = INVALID_CHANNEL;
850 wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE);
851
852 p2p_local_random = 0x01;
853 p2p_recv_random = 0x00;
854 wilc_ie = false;
855 wfi_drv->p2p_timeout = 0;
856
857 ret = wilc_disconnect(vif, reason_code);
858 if (ret != 0) {
859 netdev_err(priv->dev, "Error in disconnecting\n");
860 ret = -EINVAL;
861 }
862
863 return ret;
864}
865
866static inline void wilc_wfi_cfg_copy_wep_info(struct wilc_priv *priv,
867 u8 key_index,
868 struct key_params *params)
869{
870 priv->wep_key_len[key_index] = params->key_len;
871 memcpy(priv->wep_key[key_index], params->key, params->key_len);
872}
873
874static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
875{
876 if (!priv->wilc_gtk[idx]) {
877 priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
878 GFP_KERNEL);
879 if (!priv->wilc_gtk[idx])
880 return -ENOMEM;
881 }
882
883 if (!priv->wilc_ptk[idx]) {
884 priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
885 GFP_KERNEL);
886 if (!priv->wilc_ptk[idx])
887 return -ENOMEM;
888 }
889
890 return 0;
891}
892
893static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
894 struct key_params *params)
895{
896 kfree(key_info->key);
897
898 key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
899 if (!key_info->key)
900 return -ENOMEM;
901
902 kfree(key_info->seq);
903
904 if (params->seq_len > 0) {
905 key_info->seq = kmemdup(params->seq, params->seq_len,
906 GFP_KERNEL);
907 if (!key_info->seq)
908 return -ENOMEM;
909 }
910
911 key_info->cipher = params->cipher;
912 key_info->key_len = params->key_len;
913 key_info->seq_len = params->seq_len;
914
915 return 0;
916}
917
918static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
919 bool pairwise, const u8 *mac_addr, struct key_params *params)
920
921{
922 s32 ret = 0, keylen = params->key_len;
923 struct wilc_priv *priv;
924 const u8 *rx_mic = NULL;
925 const u8 *tx_mic = NULL;
926 u8 mode = NO_ENCRYPT;
927 u8 op_mode;
928 struct wilc_vif *vif;
929
930 priv = wiphy_priv(wiphy);
931 vif = netdev_priv(netdev);
932
933 switch (params->cipher) {
934 case WLAN_CIPHER_SUITE_WEP40:
935 case WLAN_CIPHER_SUITE_WEP104:
936 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
937 wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
938
939 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
940 mode = ENCRYPT_ENABLED | WEP;
941 else
942 mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
943
944 ret = wilc_add_wep_key_bss_ap(vif, params->key,
945 params->key_len,
946 key_index, mode,
947 OPEN_SYSTEM);
948 break;
949 }
950 if (memcmp(params->key, priv->wep_key[key_index],
951 params->key_len)) {
952 wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
953
954 ret = wilc_add_wep_key_bss_sta(vif, params->key,
955 params->key_len,
956 key_index);
957 }
958
959 break;
960
961 case WLAN_CIPHER_SUITE_TKIP:
962 case WLAN_CIPHER_SUITE_CCMP:
963 if (priv->wdev->iftype == NL80211_IFTYPE_AP ||
964 priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
965 struct wilc_wfi_key *key;
966
967 ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
968 if (ret)
969 return -ENOMEM;
970
971 if (params->key_len > 16 &&
972 params->cipher == WLAN_CIPHER_SUITE_TKIP) {
973 tx_mic = params->key + 24;
974 rx_mic = params->key + 16;
975 keylen = params->key_len - 16;
976 }
977
978 if (!pairwise) {
979 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
980 mode = ENCRYPT_ENABLED | WPA | TKIP;
981 else
982 mode = ENCRYPT_ENABLED | WPA2 | AES;
983
984 priv->wilc_groupkey = mode;
985
986 key = priv->wilc_gtk[key_index];
987 } else {
988 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
989 mode = ENCRYPT_ENABLED | WPA | TKIP;
990 else
991 mode = priv->wilc_groupkey | AES;
992
993 key = priv->wilc_ptk[key_index];
994 }
995 ret = wilc_wfi_cfg_copy_wpa_info(key, params);
996 if (ret)
997 return -ENOMEM;
998
999 op_mode = AP_MODE;
1000 } else {
1001 if (params->key_len > 16 &&
1002 params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1003 rx_mic = params->key + 24;
1004 tx_mic = params->key + 16;
1005 keylen = params->key_len - 16;
1006 }
1007
1008 op_mode = STATION_MODE;
1009 }
1010
1011 if (!pairwise)
1012 ret = wilc_add_rx_gtk(vif, params->key, keylen,
1013 key_index, params->seq_len,
1014 params->seq, rx_mic, tx_mic,
1015 op_mode, mode);
1016 else
1017 ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
1018 rx_mic, tx_mic, op_mode, mode,
1019 key_index);
1020
1021 break;
1022
1023 default:
1024 netdev_err(netdev, "Not supported cipher\n");
1025 ret = -ENOTSUPP;
1026 }
1027
1028 return ret;
1029}
1030
1031static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1032 u8 key_index,
1033 bool pairwise,
1034 const u8 *mac_addr)
1035{
1036 struct wilc_priv *priv;
1037 struct wilc *wl;
1038 struct wilc_vif *vif;
1039
1040 priv = wiphy_priv(wiphy);
1041 vif = netdev_priv(netdev);
1042 wl = vif->wilc;
1043
1044 if (netdev == wl->vif[0]->ndev) {
1045 if (priv->wilc_gtk[key_index]) {
1046 kfree(priv->wilc_gtk[key_index]->key);
1047 priv->wilc_gtk[key_index]->key = NULL;
1048 kfree(priv->wilc_gtk[key_index]->seq);
1049 priv->wilc_gtk[key_index]->seq = NULL;
1050
1051 kfree(priv->wilc_gtk[key_index]);
1052 priv->wilc_gtk[key_index] = NULL;
1053 }
1054
1055 if (priv->wilc_ptk[key_index]) {
1056 kfree(priv->wilc_ptk[key_index]->key);
1057 priv->wilc_ptk[key_index]->key = NULL;
1058 kfree(priv->wilc_ptk[key_index]->seq);
1059 priv->wilc_ptk[key_index]->seq = NULL;
1060 kfree(priv->wilc_ptk[key_index]);
1061 priv->wilc_ptk[key_index] = NULL;
1062 }
1063 }
1064
1065 if (key_index <= 3 && priv->wep_key_len[key_index]) {
1066 memset(priv->wep_key[key_index], 0,
1067 priv->wep_key_len[key_index]);
1068 priv->wep_key_len[key_index] = 0;
1069 wilc_remove_wep_key(vif, key_index);
1070 }
1071
1072 return 0;
1073}
1074
1075static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1076 bool pairwise, const u8 *mac_addr, void *cookie,
1077 void (*callback)(void *cookie, struct key_params *))
1078{
1079 struct wilc_priv *priv;
1080 struct key_params key_params;
1081
1082 priv = wiphy_priv(wiphy);
1083
1084 if (!pairwise) {
1085 key_params.key = priv->wilc_gtk[key_index]->key;
1086 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1087 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1088 key_params.seq = priv->wilc_gtk[key_index]->seq;
1089 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1090 } else {
1091 key_params.key = priv->wilc_ptk[key_index]->key;
1092 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1093 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1094 key_params.seq = priv->wilc_ptk[key_index]->seq;
1095 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1096 }
1097
1098 callback(cookie, &key_params);
1099
1100 return 0;
1101}
1102
1103static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
1104 u8 key_index, bool unicast, bool multicast)
1105{
1106 struct wilc_priv *priv;
1107 struct wilc_vif *vif;
1108
1109 priv = wiphy_priv(wiphy);
1110 vif = netdev_priv(priv->dev);
1111
1112 wilc_set_wep_default_keyid(vif, key_index);
1113
1114 return 0;
1115}
1116
1117static int get_station(struct wiphy *wiphy, struct net_device *dev,
1118 const u8 *mac, struct station_info *sinfo)
1119{
1120 struct wilc_priv *priv;
1121 struct wilc_vif *vif;
1122 u32 i = 0;
1123 u32 associatedsta = ~0;
1124 u32 inactive_time = 0;
1125
1126 priv = wiphy_priv(wiphy);
1127 vif = netdev_priv(dev);
1128
1129 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1130 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1131 if (!(memcmp(mac,
1132 priv->assoc_stainfo.sta_associated_bss[i],
1133 ETH_ALEN))) {
1134 associatedsta = i;
1135 break;
1136 }
1137 }
1138
1139 if (associatedsta == ~0) {
1140 netdev_err(dev, "sta required is not associated\n");
1141 return -ENOENT;
1142 }
1143
1144 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1145
1146 wilc_get_inactive_time(vif, mac, &inactive_time);
1147 sinfo->inactive_time = 1000 * inactive_time;
1148 } else if (vif->iftype == STATION_MODE) {
1149 struct rf_info stats;
1150
1151 wilc_get_statistics(vif, &stats);
1152
1153 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1154 BIT(NL80211_STA_INFO_RX_PACKETS) |
1155 BIT(NL80211_STA_INFO_TX_PACKETS) |
1156 BIT(NL80211_STA_INFO_TX_FAILED) |
1157 BIT(NL80211_STA_INFO_TX_BITRATE);
1158
1159 sinfo->signal = stats.rssi;
1160 sinfo->rx_packets = stats.rx_cnt;
1161 sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
1162 sinfo->tx_failed = stats.tx_fail_cnt;
1163 sinfo->txrate.legacy = stats.link_speed * 10;
1164
1165 if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
1166 stats.link_speed != DEFAULT_LINK_SPEED)
1167 wilc_enable_tcp_ack_filter(true);
1168 else if (stats.link_speed != DEFAULT_LINK_SPEED)
1169 wilc_enable_tcp_ack_filter(false);
1170 }
1171 return 0;
1172}
1173
1174static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1175 struct bss_parameters *params)
1176{
1177 return 0;
1178}
1179
1180static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1181{
1182 s32 ret = 0;
1183 struct cfg_param_attr cfg_param_val;
1184 struct wilc_priv *priv;
1185 struct wilc_vif *vif;
1186
1187 priv = wiphy_priv(wiphy);
1188 vif = netdev_priv(priv->dev);
1189
1190 cfg_param_val.flag = 0;
1191
1192 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1193 cfg_param_val.flag |= RETRY_SHORT;
1194 cfg_param_val.short_retry_limit = wiphy->retry_short;
1195 }
1196 if (changed & WIPHY_PARAM_RETRY_LONG) {
1197 cfg_param_val.flag |= RETRY_LONG;
1198 cfg_param_val.long_retry_limit = wiphy->retry_long;
1199 }
1200 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1201 cfg_param_val.flag |= FRAG_THRESHOLD;
1202 cfg_param_val.frag_threshold = wiphy->frag_threshold;
1203 }
1204
1205 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1206 cfg_param_val.flag |= RTS_THRESHOLD;
1207 cfg_param_val.rts_threshold = wiphy->rts_threshold;
1208 }
1209
1210 ret = wilc_hif_set_cfg(vif, &cfg_param_val);
1211 if (ret)
1212 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1213
1214 return ret;
1215}
1216
1217static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1218 struct cfg80211_pmksa *pmksa)
1219{
1220 u32 i;
1221 s32 ret = 0;
1222 u8 flag = 0;
1223 struct wilc_vif *vif;
1224 struct wilc_priv *priv = wiphy_priv(wiphy);
1225
1226 vif = netdev_priv(priv->dev);
1227
1228 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1229 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1230 ETH_ALEN)) {
1231 flag = PMKID_FOUND;
1232 break;
1233 }
1234 }
1235 if (i < WILC_MAX_NUM_PMKIDS) {
1236 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1237 ETH_ALEN);
1238 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1239 PMKID_LEN);
1240 if (!(flag == PMKID_FOUND))
1241 priv->pmkid_list.numpmkid++;
1242 } else {
1243 netdev_err(netdev, "Invalid PMKID index\n");
1244 ret = -EINVAL;
1245 }
1246
1247 if (!ret)
1248 ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1249
1250 return ret;
1251}
1252
1253static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1254 struct cfg80211_pmksa *pmksa)
1255{
1256 u32 i;
1257 s32 ret = 0;
1258
1259 struct wilc_priv *priv = wiphy_priv(wiphy);
1260
1261 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1262 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1263 ETH_ALEN)) {
1264 memset(&priv->pmkid_list.pmkidlist[i], 0,
1265 sizeof(struct host_if_pmkid));
1266 break;
1267 }
1268 }
1269
1270 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1271 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1272 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1273 priv->pmkid_list.pmkidlist[i + 1].bssid,
1274 ETH_ALEN);
1275 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1276 priv->pmkid_list.pmkidlist[i + 1].pmkid,
1277 PMKID_LEN);
1278 }
1279 priv->pmkid_list.numpmkid--;
1280 } else {
1281 ret = -EINVAL;
1282 }
1283
1284 return ret;
1285}
1286
1287static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1288{
1289 struct wilc_priv *priv = wiphy_priv(wiphy);
1290
1291 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1292
1293 return 0;
1294}
1295
1296static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx,
1297 u8 op_ch_attr_idx)
1298{
1299 int i = 0;
1300 int j = 0;
1301
1302 if (ch_list_attr_idx) {
1303 u8 limit = ch_list_attr_idx + 3 + buf[ch_list_attr_idx + 1];
1304
1305 for (i = ch_list_attr_idx + 3; i < limit; i++) {
1306 if (buf[i] == 0x51) {
1307 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1308 buf[j] = wlan_channel;
1309 break;
1310 }
1311 }
1312 }
1313
1314 if (op_ch_attr_idx) {
1315 buf[op_ch_attr_idx + 6] = 0x51;
1316 buf[op_ch_attr_idx + 7] = wlan_channel;
1317 }
1318}
1319
1320static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len)
1321{
1322 u32 index = 0;
1323
1324 u8 op_channel_attr_index = 0;
1325 u8 channel_list_attr_index = 0;
1326
1327 while (index < len) {
1328 if (buf[index] == GO_INTENT_ATTR_ID)
1329 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
1330
1331 if (buf[index] == CHANLIST_ATTR_ID)
1332 channel_list_attr_index = index;
1333 else if (buf[index] == OPERCHAN_ATTR_ID)
1334 op_channel_attr_index = index;
1335 index += buf[index + 1] + 3;
1336 }
1337 if (wlan_channel != INVALID_CHANNEL)
1338 wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index,
1339 op_channel_attr_index);
1340}
1341
1342static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch,
1343 u8 iftype)
1344{
1345 u32 index = 0;
1346
1347 u8 op_channel_attr_index = 0;
1348 u8 channel_list_attr_index = 0;
1349
1350 while (index < len) {
1351 if (buf[index] == GO_INTENT_ATTR_ID) {
1352 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
1353
1354 break;
1355 }
1356
1357 if (buf[index] == CHANLIST_ATTR_ID)
1358 channel_list_attr_index = index;
1359 else if (buf[index] == OPERCHAN_ATTR_ID)
1360 op_channel_attr_index = index;
1361 index += buf[index + 1] + 3;
1362 }
1363 if (wlan_channel != INVALID_CHANNEL && oper_ch)
1364 wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index,
1365 op_channel_attr_index);
1366}
1367
1368static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff,
1369 u32 size)
1370{
1371 int i;
1372 u8 subtype;
1373 struct wilc_vif *vif = netdev_priv(priv->dev);
1374
1375 subtype = buff[P2P_PUB_ACTION_SUBTYPE];
1376 if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) && !wilc_ie) {
1377 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1378 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1379 p2p_recv_random = buff[i + 6];
1380 wilc_ie = true;
1381 break;
1382 }
1383 }
1384 }
1385
1386 if (p2p_local_random <= p2p_recv_random) {
1387 netdev_dbg(vif->ndev,
1388 "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n",
1389 p2p_local_random, p2p_recv_random);
1390 return;
1391 }
1392
1393 if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP ||
1394 subtype == P2P_INV_REQ || subtype == P2P_INV_RSP) {
1395 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1396 if (buff[i] == P2PELEM_ATTR_ID &&
1397 !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1398 wilc_wfi_cfg_parse_rx_action(&buff[i + 6],
1399 size - (i + 6));
1400 break;
1401 }
1402 }
1403 }
1404}
1405
1406void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
1407{
1408 struct wilc_priv *priv;
1409 u32 header, pkt_offset;
1410 struct host_if_drv *wfi_drv;
1411 s32 freq;
1412
1413 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1414 wfi_drv = (struct host_if_drv *)priv->hif_drv;
1415
1416 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1417
1418 pkt_offset = GET_PKT_OFFSET(header);
1419
1420 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1421 bool ack = false;
1422
1423 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP ||
1424 pkt_offset & IS_MGMT_STATUS_SUCCES)
1425 ack = true;
1426
1427 cfg80211_mgmt_tx_status(priv->wdev, priv->tx_cookie, buff, size,
1428 ack, GFP_KERNEL);
1429 return;
1430 }
1431
1432 freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ);
1433
1434 if (!ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1435 cfg80211_rx_mgmt(priv->wdev, freq, 0, buff, size, 0);
1436 return;
1437 }
1438
1439 if (priv->cfg_scanning &&
1440 time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
1441 netdev_dbg(dev, "Receiving action wrong ch\n");
1442 return;
1443 }
1444 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1445 u8 subtype = buff[P2P_PUB_ACTION_SUBTYPE];
1446
1447 switch (buff[ACTION_SUBTYPE_ID]) {
1448 case GAS_INITIAL_REQ:
1449 case GAS_INITIAL_RSP:
1450 break;
1451
1452 case PUBLIC_ACT_VENDORSPEC:
1453 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4))
1454 wilc_wfi_cfg_parse_rx_vendor_spec(priv, buff,
1455 size);
1456
1457 if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
1458 wilc_ie)
1459 size -= 7;
1460
1461 break;
1462
1463 default:
1464 netdev_dbg(dev,
1465 "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n",
1466 buff[ACTION_SUBTYPE_ID]);
1467 break;
1468 }
1469 }
1470
1471 cfg80211_rx_mgmt(priv->wdev, freq, 0, buff, size, 0);
1472}
1473
1474static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
1475{
1476 struct p2p_mgmt_data *pv_data = priv;
1477
1478 kfree(pv_data->buff);
1479 kfree(pv_data);
1480}
1481
1482static void wilc_wfi_remain_on_channel_ready(void *priv_data)
1483{
1484 struct wilc_priv *priv;
1485
1486 priv = priv_data;
1487
1488 priv->p2p_listen_state = true;
1489
1490 cfg80211_ready_on_channel(priv->wdev,
1491 priv->remain_on_ch_params.listen_cookie,
1492 priv->remain_on_ch_params.listen_ch,
1493 priv->remain_on_ch_params.listen_duration,
1494 GFP_KERNEL);
1495}
1496
1497static void wilc_wfi_remain_on_channel_expired(void *data, u32 session_id)
1498{
1499 struct wilc_priv *priv = data;
1500 struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
1501
1502 if (session_id != params->listen_session_id)
1503 return;
1504
1505 priv->p2p_listen_state = false;
1506
1507 cfg80211_remain_on_channel_expired(priv->wdev, params->listen_cookie,
1508 params->listen_ch, GFP_KERNEL);
1509}
1510
1511static int remain_on_channel(struct wiphy *wiphy,
1512 struct wireless_dev *wdev,
1513 struct ieee80211_channel *chan,
1514 unsigned int duration, u64 *cookie)
1515{
1516 s32 ret = 0;
1517 struct wilc_priv *priv;
1518 struct wilc_vif *vif;
1519
1520 priv = wiphy_priv(wiphy);
1521 vif = netdev_priv(priv->dev);
1522
1523 if (wdev->iftype == NL80211_IFTYPE_AP) {
1524 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1525 return ret;
1526 }
1527
1528 curr_channel = chan->hw_value;
1529
1530 priv->remain_on_ch_params.listen_ch = chan;
1531 priv->remain_on_ch_params.listen_cookie = *cookie;
1532 priv->remain_on_ch_params.listen_duration = duration;
1533 priv->remain_on_ch_params.listen_session_id++;
1534
1535 return wilc_remain_on_channel(vif,
1536 priv->remain_on_ch_params.listen_session_id,
1537 duration, chan->hw_value,
1538 wilc_wfi_remain_on_channel_expired,
1539 wilc_wfi_remain_on_channel_ready, (void *)priv);
1540}
1541
1542static int cancel_remain_on_channel(struct wiphy *wiphy,
1543 struct wireless_dev *wdev,
1544 u64 cookie)
1545{
1546 struct wilc_priv *priv;
1547 struct wilc_vif *vif;
1548
1549 priv = wiphy_priv(wiphy);
1550 vif = netdev_priv(priv->dev);
1551
1552 return wilc_listen_state_expired(vif,
1553 priv->remain_on_ch_params.listen_session_id);
1554}
1555
1556static void wilc_wfi_cfg_tx_vendor_spec(struct p2p_mgmt_data *mgmt_tx,
1557 struct cfg80211_mgmt_tx_params *params,
1558 u8 iftype, u32 buf_len)
1559{
1560 const u8 *buf = params->buf;
1561 size_t len = params->len;
1562 u32 i;
1563 u8 subtype = buf[P2P_PUB_ACTION_SUBTYPE];
1564
1565 if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) {
1566 if (p2p_local_random == 1 &&
1567 p2p_recv_random < p2p_local_random) {
1568 get_random_bytes(&p2p_local_random, 1);
1569 p2p_local_random++;
1570 }
1571 }
1572
1573 if (p2p_local_random <= p2p_recv_random || !(subtype == GO_NEG_REQ ||
1574 subtype == GO_NEG_RSP ||
1575 subtype == P2P_INV_REQ ||
1576 subtype == P2P_INV_RSP))
1577 return;
1578
1579 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1580 if (buf[i] == P2PELEM_ATTR_ID &&
1581 !memcmp(p2p_oui, &buf[i + 2], 4)) {
1582 bool oper_ch = false;
1583 u8 *tx_buff = &mgmt_tx->buff[i + 6];
1584
1585 if (subtype == P2P_INV_REQ || subtype == P2P_INV_RSP)
1586 oper_ch = true;
1587
1588 wilc_wfi_cfg_parse_tx_action(tx_buff, len - (i + 6),
1589 oper_ch, iftype);
1590
1591 break;
1592 }
1593 }
1594
1595 if (subtype != P2P_INV_REQ && subtype != P2P_INV_RSP) {
1596 int vendor_spec_len = sizeof(p2p_vendor_spec);
1597
1598 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec,
1599 vendor_spec_len);
1600 mgmt_tx->buff[len + vendor_spec_len] = p2p_local_random;
1601 mgmt_tx->size = buf_len;
1602 }
1603}
1604
1605static int mgmt_tx(struct wiphy *wiphy,
1606 struct wireless_dev *wdev,
1607 struct cfg80211_mgmt_tx_params *params,
1608 u64 *cookie)
1609{
1610 struct ieee80211_channel *chan = params->chan;
1611 unsigned int wait = params->wait;
1612 const u8 *buf = params->buf;
1613 size_t len = params->len;
1614 const struct ieee80211_mgmt *mgmt;
1615 struct p2p_mgmt_data *mgmt_tx;
1616 struct wilc_priv *priv;
1617 struct host_if_drv *wfi_drv;
1618 struct wilc_vif *vif;
1619 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1620 int ret = 0;
1621
1622 vif = netdev_priv(wdev->netdev);
1623 priv = wiphy_priv(wiphy);
1624 wfi_drv = (struct host_if_drv *)priv->hif_drv;
1625
1626 *cookie = (unsigned long)buf;
1627 priv->tx_cookie = *cookie;
1628 mgmt = (const struct ieee80211_mgmt *)buf;
1629
1630 if (!ieee80211_is_mgmt(mgmt->frame_control))
1631 goto out;
1632
1633 mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
1634 if (!mgmt_tx) {
1635 ret = -ENOMEM;
1636 goto out;
1637 }
1638
1639 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1640 if (!mgmt_tx->buff) {
1641 ret = -ENOMEM;
1642 kfree(mgmt_tx);
1643 goto out;
1644 }
1645
1646 memcpy(mgmt_tx->buff, buf, len);
1647 mgmt_tx->size = len;
1648
1649 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1650 wilc_set_mac_chnl_num(vif, chan->hw_value);
1651 curr_channel = chan->hw_value;
1652 goto out_txq_add_pkt;
1653 }
1654
1655 if (!ieee80211_is_action(mgmt->frame_control))
1656 goto out_txq_add_pkt;
1657
1658 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1659 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1660 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1661 wilc_set_mac_chnl_num(vif, chan->hw_value);
1662 curr_channel = chan->hw_value;
1663 }
1664 switch (buf[ACTION_SUBTYPE_ID]) {
1665 case GAS_INITIAL_REQ:
1666 case GAS_INITIAL_RSP:
1667 break;
1668
1669 case PUBLIC_ACT_VENDORSPEC:
1670 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4))
1671 wilc_wfi_cfg_tx_vendor_spec(mgmt_tx, params,
1672 vif->iftype,
1673 buf_len);
1674 else
1675 netdev_dbg(vif->ndev,
1676 "Not a P2P public action frame\n");
1677
1678 break;
1679
1680 default:
1681 netdev_dbg(vif->ndev,
1682 "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n",
1683 buf[ACTION_SUBTYPE_ID]);
1684 break;
1685 }
1686 }
1687
1688 wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1689
1690out_txq_add_pkt:
1691
1692 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1693 mgmt_tx->buff, mgmt_tx->size,
1694 wilc_wfi_mgmt_tx_complete);
1695
1696out:
1697
1698 return ret;
1699}
1700
1701static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1702 struct wireless_dev *wdev,
1703 u64 cookie)
1704{
1705 struct wilc_priv *priv;
1706 struct host_if_drv *wfi_drv;
1707
1708 priv = wiphy_priv(wiphy);
1709 wfi_drv = (struct host_if_drv *)priv->hif_drv;
1710 wfi_drv->p2p_timeout = jiffies;
1711
1712 if (!priv->p2p_listen_state) {
1713 struct wilc_wfi_p2p_listen_params *params;
1714
1715 params = &priv->remain_on_ch_params;
1716
1717 cfg80211_remain_on_channel_expired(priv->wdev,
1718 params->listen_cookie,
1719 params->listen_ch,
1720 GFP_KERNEL);
1721 }
1722
1723 return 0;
1724}
1725
1726void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1727 u16 frame_type, bool reg)
1728{
1729 struct wilc_priv *priv;
1730 struct wilc_vif *vif;
1731 struct wilc *wl;
1732
1733 priv = wiphy_priv(wiphy);
1734 vif = netdev_priv(priv->wdev->netdev);
1735 wl = vif->wilc;
1736
1737 if (!frame_type)
1738 return;
1739
1740 switch (frame_type) {
1741 case PROBE_REQ:
1742 vif->frame_reg[0].type = frame_type;
1743 vif->frame_reg[0].reg = reg;
1744 break;
1745
1746 case ACTION:
1747 vif->frame_reg[1].type = frame_type;
1748 vif->frame_reg[1].reg = reg;
1749 break;
1750
1751 default:
1752 break;
1753 }
1754
1755 if (!wl->initialized)
1756 return;
1757 wilc_frame_register(vif, frame_type, reg);
1758}
1759
1760static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1761 s32 rssi_thold, u32 rssi_hyst)
1762{
1763 return 0;
1764}
1765
1766static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1767 int idx, u8 *mac, struct station_info *sinfo)
1768{
1769 struct wilc_priv *priv;
1770 struct wilc_vif *vif;
1771
1772 if (idx != 0)
1773 return -ENOENT;
1774
1775 priv = wiphy_priv(wiphy);
1776 vif = netdev_priv(priv->dev);
1777
1778 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1779
1780 wilc_get_rssi(vif, &sinfo->signal);
1781
1782 memcpy(mac, priv->associated_bss, ETH_ALEN);
1783 return 0;
1784}
1785
1786static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1787 bool enabled, int timeout)
1788{
1789 struct wilc_priv *priv;
1790 struct wilc_vif *vif;
1791
1792 if (!wiphy)
1793 return -ENOENT;
1794
1795 priv = wiphy_priv(wiphy);
1796 vif = netdev_priv(priv->dev);
1797 if (!priv->hif_drv)
1798 return -EIO;
1799
1800 if (wilc_enable_ps)
1801 wilc_set_power_mgmt(vif, enabled, timeout);
1802
1803 return 0;
1804}
1805
1806static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1807 enum nl80211_iftype type,
1808 struct vif_params *params)
1809{
1810 struct wilc_priv *priv;
1811 struct wilc_vif *vif;
1812 struct wilc *wl;
1813
1814 vif = netdev_priv(dev);
1815 priv = wiphy_priv(wiphy);
1816 wl = vif->wilc;
1817 p2p_local_random = 0x01;
1818 p2p_recv_random = 0x00;
1819 wilc_ie = false;
1820 wilc_optaining_ip = false;
1821 del_timer(&wilc_during_ip_timer);
1822
1823 switch (type) {
1824 case NL80211_IFTYPE_STATION:
1825 wilc_connecting = 0;
1826 dev->ieee80211_ptr->iftype = type;
1827 priv->wdev->iftype = type;
1828 vif->monitor_flag = 0;
1829 vif->iftype = STATION_MODE;
1830 wilc_set_operation_mode(vif, STATION_MODE);
1831
1832 memset(priv->assoc_stainfo.sta_associated_bss, 0,
1833 MAX_NUM_STA * ETH_ALEN);
1834
1835 wilc_enable_ps = true;
1836 wilc_set_power_mgmt(vif, 1, 0);
1837 break;
1838
1839 case NL80211_IFTYPE_P2P_CLIENT:
1840 wilc_connecting = 0;
1841 dev->ieee80211_ptr->iftype = type;
1842 priv->wdev->iftype = type;
1843 vif->monitor_flag = 0;
1844 vif->iftype = CLIENT_MODE;
1845 wilc_set_operation_mode(vif, STATION_MODE);
1846
1847 wilc_enable_ps = false;
1848 wilc_set_power_mgmt(vif, 0, 0);
1849 break;
1850
1851 case NL80211_IFTYPE_AP:
1852 wilc_enable_ps = false;
1853 dev->ieee80211_ptr->iftype = type;
1854 priv->wdev->iftype = type;
1855 vif->iftype = AP_MODE;
1856
1857 if (wl->initialized) {
1858 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
1859 0, vif->ifc_id);
1860 wilc_set_operation_mode(vif, AP_MODE);
1861 wilc_set_power_mgmt(vif, 0, 0);
1862 }
1863 break;
1864
1865 case NL80211_IFTYPE_P2P_GO:
1866 wilc_optaining_ip = true;
1867 mod_timer(&wilc_during_ip_timer,
1868 jiffies + msecs_to_jiffies(DURING_IP_TIME_OUT));
1869 wilc_set_operation_mode(vif, AP_MODE);
1870 dev->ieee80211_ptr->iftype = type;
1871 priv->wdev->iftype = type;
1872 vif->iftype = GO_MODE;
1873
1874 wilc_enable_ps = false;
1875 wilc_set_power_mgmt(vif, 0, 0);
1876 break;
1877
1878 default:
1879 netdev_err(dev, "Unknown interface type= %d\n", type);
1880 return -EINVAL;
1881 }
1882
1883 return 0;
1884}
1885
1886static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1887 struct cfg80211_ap_settings *settings)
1888{
1889 struct cfg80211_beacon_data *beacon = &settings->beacon;
1890 s32 ret = 0;
1891 struct wilc *wl;
1892 struct wilc_vif *vif;
1893
1894 vif = netdev_priv(dev);
1895 wl = vif->wilc;
1896
1897 ret = set_channel(wiphy, &settings->chandef);
1898
1899 if (ret != 0)
1900 netdev_err(dev, "Error in setting channel\n");
1901
1902 wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
1903 wilc_set_power_mgmt(vif, 0, 0);
1904
1905 return wilc_add_beacon(vif, settings->beacon_interval,
1906 settings->dtim_period, beacon->head_len,
1907 (u8 *)beacon->head, beacon->tail_len,
1908 (u8 *)beacon->tail);
1909}
1910
1911static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1912 struct cfg80211_beacon_data *beacon)
1913{
1914 struct wilc_priv *priv;
1915 struct wilc_vif *vif;
1916
1917 priv = wiphy_priv(wiphy);
1918 vif = netdev_priv(priv->dev);
1919
1920 return wilc_add_beacon(vif, 0, 0, beacon->head_len,
1921 (u8 *)beacon->head, beacon->tail_len,
1922 (u8 *)beacon->tail);
1923}
1924
1925static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1926{
1927 s32 ret = 0;
1928 struct wilc_priv *priv;
1929 struct wilc_vif *vif;
1930 u8 null_bssid[ETH_ALEN] = {0};
1931
1932 if (!wiphy)
1933 return -EFAULT;
1934
1935 priv = wiphy_priv(wiphy);
1936 vif = netdev_priv(priv->dev);
1937
1938 wilc_wlan_set_bssid(dev, null_bssid, AP_MODE);
1939
1940 ret = wilc_del_beacon(vif);
1941
1942 if (ret)
1943 netdev_err(dev, "Host delete beacon fail\n");
1944
1945 return ret;
1946}
1947
1948static int add_station(struct wiphy *wiphy, struct net_device *dev,
1949 const u8 *mac, struct station_parameters *params)
1950{
1951 s32 ret = 0;
1952 struct wilc_priv *priv;
1953 struct add_sta_param sta_params = { {0} };
1954 struct wilc_vif *vif;
1955
1956 if (!wiphy)
1957 return -EFAULT;
1958
1959 priv = wiphy_priv(wiphy);
1960 vif = netdev_priv(dev);
1961
1962 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1963 memcpy(sta_params.bssid, mac, ETH_ALEN);
1964 memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
1965 ETH_ALEN);
1966 sta_params.aid = params->aid;
1967 sta_params.rates_len = params->supported_rates_len;
1968 sta_params.rates = params->supported_rates;
1969
1970 if (!params->ht_capa) {
1971 sta_params.ht_supported = false;
1972 } else {
1973 sta_params.ht_supported = true;
1974 sta_params.ht_capa = *params->ht_capa;
1975 }
1976
1977 sta_params.flags_mask = params->sta_flags_mask;
1978 sta_params.flags_set = params->sta_flags_set;
1979
1980 ret = wilc_add_station(vif, &sta_params);
1981 if (ret)
1982 netdev_err(dev, "Host add station fail\n");
1983 }
1984
1985 return ret;
1986}
1987
1988static int del_station(struct wiphy *wiphy, struct net_device *dev,
1989 struct station_del_parameters *params)
1990{
1991 const u8 *mac = params->mac;
1992 s32 ret = 0;
1993 struct wilc_priv *priv;
1994 struct wilc_vif *vif;
1995 struct sta_info *info;
1996
1997 if (!wiphy)
1998 return -EFAULT;
1999
2000 priv = wiphy_priv(wiphy);
2001 vif = netdev_priv(dev);
2002
2003 if (!(vif->iftype == AP_MODE || vif->iftype == GO_MODE))
2004 return ret;
2005
2006 info = &priv->assoc_stainfo;
2007
2008 if (!mac)
2009 ret = wilc_del_allstation(vif, info->sta_associated_bss);
2010
2011 ret = wilc_del_station(vif, mac);
2012 if (ret)
2013 netdev_err(dev, "Host delete station fail\n");
2014 return ret;
2015}
2016
2017static int change_station(struct wiphy *wiphy, struct net_device *dev,
2018 const u8 *mac, struct station_parameters *params)
2019{
2020 s32 ret = 0;
2021 struct add_sta_param sta_params = { {0} };
2022 struct wilc_vif *vif;
2023
2024 if (!wiphy)
2025 return -EFAULT;
2026
2027 vif = netdev_priv(dev);
2028
2029 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2030 memcpy(sta_params.bssid, mac, ETH_ALEN);
2031 sta_params.aid = params->aid;
2032 sta_params.rates_len = params->supported_rates_len;
2033 sta_params.rates = params->supported_rates;
2034
2035 if (!params->ht_capa) {
2036 sta_params.ht_supported = false;
2037 } else {
2038 sta_params.ht_supported = true;
2039 sta_params.ht_capa = *params->ht_capa;
2040 }
2041
2042 sta_params.flags_mask = params->sta_flags_mask;
2043 sta_params.flags_set = params->sta_flags_set;
2044
2045 ret = wilc_edit_station(vif, &sta_params);
2046 if (ret)
2047 netdev_err(dev, "Host edit station fail\n");
2048 }
2049 return ret;
2050}
2051
2052static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2053 const char *name,
2054 unsigned char name_assign_type,
2055 enum nl80211_iftype type,
2056 struct vif_params *params)
2057{
2058 struct wilc_vif *vif;
2059 struct wilc_priv *priv;
2060 struct net_device *new_ifc = NULL;
2061
2062 priv = wiphy_priv(wiphy);
2063 vif = netdev_priv(priv->wdev->netdev);
2064
2065 if (type == NL80211_IFTYPE_MONITOR) {
2066 new_ifc = wilc_wfi_init_mon_interface(name, vif->ndev);
2067 if (new_ifc) {
2068 vif = netdev_priv(priv->wdev->netdev);
2069 vif->monitor_flag = 1;
2070 }
2071 }
2072 return priv->wdev;
2073}
2074
2075static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2076{
2077 return 0;
2078}
2079
2080static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2081{
2082 struct wilc_priv *priv = wiphy_priv(wiphy);
2083 struct wilc_vif *vif = netdev_priv(priv->dev);
2084
2085 if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2086 vif->wilc->suspend_event = true;
2087 else
2088 vif->wilc->suspend_event = false;
2089
2090 return 0;
2091}
2092
2093static int wilc_resume(struct wiphy *wiphy)
2094{
2095 struct wilc_priv *priv = wiphy_priv(wiphy);
2096 struct wilc_vif *vif = netdev_priv(priv->dev);
2097
2098 netdev_info(vif->ndev, "cfg resume\n");
2099 return 0;
2100}
2101
2102static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2103{
2104 struct wilc_priv *priv = wiphy_priv(wiphy);
2105 struct wilc_vif *vif = netdev_priv(priv->dev);
2106
2107 netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2108}
2109
2110static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2111 enum nl80211_tx_power_setting type, int mbm)
2112{
2113 int ret;
2114 s32 tx_power = MBM_TO_DBM(mbm);
2115 struct wilc_priv *priv = wiphy_priv(wiphy);
2116 struct wilc_vif *vif = netdev_priv(priv->dev);
2117
2118 if (tx_power < 0)
2119 tx_power = 0;
2120 else if (tx_power > 18)
2121 tx_power = 18;
2122 ret = wilc_set_tx_power(vif, tx_power);
2123 if (ret)
2124 netdev_err(vif->ndev, "Failed to set tx power\n");
2125
2126 return ret;
2127}
2128
2129static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2130 int *dbm)
2131{
2132 int ret;
2133 struct wilc_priv *priv = wiphy_priv(wiphy);
2134 struct wilc_vif *vif = netdev_priv(priv->dev);
2135 struct wilc *wl;
2136
2137 wl = vif->wilc;
2138
2139
2140 if (!wl->initialized)
2141 return -EIO;
2142
2143 ret = wilc_get_tx_power(vif, (u8 *)dbm);
2144 if (ret)
2145 netdev_err(vif->ndev, "Failed to get tx power\n");
2146
2147 return ret;
2148}
2149
2150static const struct cfg80211_ops wilc_cfg80211_ops = {
2151 .set_monitor_channel = set_channel,
2152 .scan = scan,
2153 .connect = connect,
2154 .disconnect = disconnect,
2155 .add_key = add_key,
2156 .del_key = del_key,
2157 .get_key = get_key,
2158 .set_default_key = set_default_key,
2159 .add_virtual_intf = add_virtual_intf,
2160 .del_virtual_intf = del_virtual_intf,
2161 .change_virtual_intf = change_virtual_intf,
2162
2163 .start_ap = start_ap,
2164 .change_beacon = change_beacon,
2165 .stop_ap = stop_ap,
2166 .add_station = add_station,
2167 .del_station = del_station,
2168 .change_station = change_station,
2169 .get_station = get_station,
2170 .dump_station = dump_station,
2171 .change_bss = change_bss,
2172 .set_wiphy_params = set_wiphy_params,
2173
2174 .set_pmksa = set_pmksa,
2175 .del_pmksa = del_pmksa,
2176 .flush_pmksa = flush_pmksa,
2177 .remain_on_channel = remain_on_channel,
2178 .cancel_remain_on_channel = cancel_remain_on_channel,
2179 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2180 .mgmt_tx = mgmt_tx,
2181 .mgmt_frame_register = wilc_mgmt_frame_register,
2182 .set_power_mgmt = set_power_mgmt,
2183 .set_cqm_rssi_config = set_cqm_rssi_config,
2184
2185 .suspend = wilc_suspend,
2186 .resume = wilc_resume,
2187 .set_wakeup = wilc_set_wakeup,
2188 .set_tx_power = set_tx_power,
2189 .get_tx_power = get_tx_power,
2190
2191};
2192
2193static struct wireless_dev *wilc_wfi_cfg_alloc(void)
2194{
2195 struct wireless_dev *wdev;
2196
2197 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2198 if (!wdev)
2199 goto _fail_;
2200
2201 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2202 if (!wdev->wiphy)
2203 goto _fail_mem_;
2204
2205 wilc_band_2ghz.ht_cap.ht_supported = 1;
2206 wilc_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2207 wilc_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2208 wilc_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2209 wilc_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2210
2211 wdev->wiphy->bands[NL80211_BAND_2GHZ] = &wilc_band_2ghz;
2212
2213 return wdev;
2214
2215_fail_mem_:
2216 kfree(wdev);
2217_fail_:
2218 return NULL;
2219}
2220
2221struct wireless_dev *wilc_create_wiphy(struct net_device *net,
2222 struct device *dev)
2223{
2224 struct wilc_priv *priv;
2225 struct wireless_dev *wdev;
2226 s32 ret = 0;
2227
2228 wdev = wilc_wfi_cfg_alloc();
2229 if (!wdev) {
2230 netdev_err(net, "wiphy new allocate failed\n");
2231 return NULL;
2232 }
2233
2234 priv = wdev_priv(wdev);
2235 priv->wdev = wdev;
2236 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2237#ifdef CONFIG_PM
2238 wdev->wiphy->wowlan = &wowlan_support;
2239#endif
2240 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2241 wdev->wiphy->max_scan_ie_len = 1000;
2242 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2243 wdev->wiphy->cipher_suites = cipher_suites;
2244 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2245 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2246
2247 wdev->wiphy->max_remain_on_channel_duration = 500;
2248 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2249 BIT(NL80211_IFTYPE_AP) |
2250 BIT(NL80211_IFTYPE_MONITOR) |
2251 BIT(NL80211_IFTYPE_P2P_GO) |
2252 BIT(NL80211_IFTYPE_P2P_CLIENT);
2253 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2254 wdev->iftype = NL80211_IFTYPE_STATION;
2255
2256 set_wiphy_dev(wdev->wiphy, dev);
2257
2258 ret = wiphy_register(wdev->wiphy);
2259 if (ret)
2260 netdev_err(net, "Cannot register wiphy device\n");
2261
2262 priv->dev = net;
2263 return wdev;
2264}
2265
2266int wilc_init_host_int(struct net_device *net)
2267{
2268 int ret = 0;
2269
2270 struct wilc_priv *priv;
2271
2272 priv = wdev_priv(net->ieee80211_ptr);
2273 if (op_ifcs == 0) {
2274 timer_setup(&aging_timer, remove_network_from_shadow, 0);
2275 timer_setup(&wilc_during_ip_timer, clear_during_ip, 0);
2276 }
2277 op_ifcs++;
2278
2279 priv->auto_rate_adjusted = false;
2280
2281 priv->p2p_listen_state = false;
2282
2283 mutex_init(&priv->scan_req_lock);
2284 ret = wilc_init(net, &priv->hif_drv);
2285 if (ret)
2286 netdev_err(net, "Error while initializing hostinterface\n");
2287
2288 return ret;
2289}
2290
2291int wilc_deinit_host_int(struct net_device *net)
2292{
2293 int ret = 0;
2294 struct wilc_vif *vif;
2295 struct wilc_priv *priv;
2296
2297 priv = wdev_priv(net->ieee80211_ptr);
2298 vif = netdev_priv(priv->dev);
2299
2300 priv->auto_rate_adjusted = false;
2301
2302 priv->p2p_listen_state = false;
2303
2304 op_ifcs--;
2305
2306 mutex_destroy(&priv->scan_req_lock);
2307 ret = wilc_deinit(vif);
2308
2309 clear_shadow_scan();
2310 if (op_ifcs == 0)
2311 del_timer_sync(&wilc_during_ip_timer);
2312
2313 if (ret)
2314 netdev_err(net, "Error while deinitializing host interface\n");
2315
2316 return ret;
2317}
2318
2319void wilc_free_wiphy(struct net_device *net)
2320{
2321 if (!net)
2322 return;
2323
2324 if (!net->ieee80211_ptr)
2325 return;
2326
2327 if (!net->ieee80211_ptr->wiphy)
2328 return;
2329
2330 wiphy_unregister(net->ieee80211_ptr->wiphy);
2331
2332 wiphy_free(net->ieee80211_ptr->wiphy);
2333 kfree(net->ieee80211_ptr);
2334}
2335