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