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