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