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