staging: wilc1000: remove typedef from pstrNetworkInfo
[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 = 0x00;
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].pu8IEs) {
198 kfree(last_scanned_shadow[i].pu8IEs);
199 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
200 }
201
202 kfree(last_scanned_shadow[i].pJoinParams);
203 last_scanned_shadow[i].pJoinParams = 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->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index);
214
215 for (i = 0; i < num_rssi; i++)
216 rssi_v += network_info->strRssi.as8RSSI[i];
217
218 rssi_v /= num_rssi;
219 return rssi_v;
220 }
221
222 static void refresh_scan(void *user_void, u8 all, bool direct_scan)
223 {
224 struct wilc_priv *priv;
225 struct wiphy *wiphy;
226 struct cfg80211_bss *bss = NULL;
227 int i;
228 int rssi = 0;
229
230 priv = (struct wilc_priv *)user_void;
231 wiphy = priv->dev->ieee80211_ptr->wiphy;
232
233 for (i = 0; i < last_scanned_cnt; i++) {
234 struct network_info *network_info;
235
236 network_info = &last_scanned_shadow[i];
237
238 if (!network_info->u8Found || all) {
239 s32 freq;
240 struct ieee80211_channel *channel;
241
242 if (network_info) {
243 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
244 channel = ieee80211_get_channel(wiphy, freq);
245
246 rssi = get_rssi_avg(network_info);
247 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
248 direct_scan) {
249 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
250 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
251 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
252 cfg80211_put_bss(wiphy, bss);
253 }
254 }
255 }
256 }
257 }
258
259 static void reset_shadow_found(void)
260 {
261 int i;
262
263 for (i = 0; i < last_scanned_cnt; i++)
264 last_scanned_shadow[i].u8Found = 0;
265 }
266
267 static void update_scan_time(void)
268 {
269 int i;
270
271 for (i = 0; i < last_scanned_cnt; i++)
272 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
273 }
274
275 static void remove_network_from_shadow(unsigned long arg)
276 {
277 unsigned long now = jiffies;
278 int i, j;
279
280
281 for (i = 0; i < last_scanned_cnt; i++) {
282 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
283 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
284
285 kfree(last_scanned_shadow[i].pu8IEs);
286 last_scanned_shadow[i].pu8IEs = NULL;
287
288 kfree(last_scanned_shadow[i].pJoinParams);
289
290 for (j = i; (j < last_scanned_cnt - 1); j++)
291 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
292
293 last_scanned_cnt--;
294 }
295 }
296
297 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
298 last_scanned_cnt);
299 if (last_scanned_cnt != 0) {
300 hAgingTimer.data = arg;
301 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
302 } else {
303 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
304 }
305 }
306
307 static void clear_duringIP(unsigned long arg)
308 {
309 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
310 wilc_optaining_ip = false;
311 }
312
313 static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
314 void *user_void)
315 {
316 int state = -1;
317 int i;
318
319 if (last_scanned_cnt == 0) {
320 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
321 hAgingTimer.data = (unsigned long)user_void;
322 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
323 state = -1;
324 } else {
325 for (i = 0; i < last_scanned_cnt; i++) {
326 if (memcmp(last_scanned_shadow[i].au8bssid,
327 pstrNetworkInfo->au8bssid, 6) == 0) {
328 state = i;
329 break;
330 }
331 }
332 }
333 return state;
334 }
335
336 static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
337 void *user_void, void *pJoinParams)
338 {
339 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
340 u32 ap_index = 0;
341 u8 rssi_index = 0;
342
343 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
344 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
345 return;
346 }
347 if (ap_found == -1) {
348 ap_index = last_scanned_cnt;
349 last_scanned_cnt++;
350 } else {
351 ap_index = ap_found;
352 }
353 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
354 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
355 if (rssi_index == NUM_RSSI) {
356 rssi_index = 0;
357 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
358 }
359 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
360 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
361 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
362 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
363 memcpy(last_scanned_shadow[ap_index].au8ssid,
364 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
365 memcpy(last_scanned_shadow[ap_index].au8bssid,
366 pstrNetworkInfo->au8bssid, ETH_ALEN);
367 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
368 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
369 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
370 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
371 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
372 if (ap_found != -1)
373 kfree(last_scanned_shadow[ap_index].pu8IEs);
374 last_scanned_shadow[ap_index].pu8IEs =
375 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);
376 memcpy(last_scanned_shadow[ap_index].pu8IEs,
377 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
378 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
379 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
380 last_scanned_shadow[ap_index].u8Found = 1;
381 if (ap_found != -1)
382 kfree(last_scanned_shadow[ap_index].pJoinParams);
383 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
384 }
385
386 static void CfgScanResult(enum scan_event scan_event,
387 struct network_info *network_info,
388 void *user_void,
389 void *join_params)
390 {
391 struct wilc_priv *priv;
392 struct wiphy *wiphy;
393 s32 s32Freq;
394 struct ieee80211_channel *channel;
395 struct cfg80211_bss *bss = NULL;
396
397 priv = (struct wilc_priv *)user_void;
398 if (priv->bCfgScanning) {
399 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
400 wiphy = priv->dev->ieee80211_ptr->wiphy;
401
402 if (!wiphy)
403 return;
404
405 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
406 (((s32)network_info->s8rssi * 100) < 0 ||
407 ((s32)network_info->s8rssi * 100) > 100))
408 return;
409
410 if (network_info) {
411 s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
412 channel = ieee80211_get_channel(wiphy, s32Freq);
413
414 if (!channel)
415 return;
416
417 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
418 "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
419 network_info->u16CapInfo, network_info->u16BeaconPeriod);
420
421 if (network_info->bNewNetwork) {
422 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
423 PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
424 priv->u32RcvdChCount++;
425
426 add_network_to_shadow(network_info, priv, join_params);
427
428 if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
429 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
430 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
431 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
432 cfg80211_put_bss(wiphy, bss);
433 }
434 }
435 } else {
436 u32 i;
437
438 for (i = 0; i < priv->u32RcvdChCount; i++) {
439 if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
440 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
441
442 last_scanned_shadow[i].s8rssi = network_info->s8rssi;
443 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
444 break;
445 }
446 }
447 }
448 }
449 } else if (scan_event == SCAN_EVENT_DONE) {
450 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
451 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
452 refresh_scan(priv, 1, false);
453
454 if (priv->u32RcvdChCount > 0)
455 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
456 else
457 PRINT_D(CFG80211_DBG, "No networks found\n");
458
459 down(&(priv->hSemScanReq));
460
461 if (priv->pstrScanReq) {
462 cfg80211_scan_done(priv->pstrScanReq, false);
463 priv->u32RcvdChCount = 0;
464 priv->bCfgScanning = false;
465 priv->pstrScanReq = NULL;
466 }
467 up(&(priv->hSemScanReq));
468 } else if (scan_event == SCAN_EVENT_ABORTED) {
469 down(&(priv->hSemScanReq));
470
471 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
472 if (priv->pstrScanReq) {
473 update_scan_time();
474 refresh_scan(priv, 1, false);
475
476 cfg80211_scan_done(priv->pstrScanReq, false);
477 priv->bCfgScanning = false;
478 priv->pstrScanReq = NULL;
479 }
480 up(&(priv->hSemScanReq));
481 }
482 }
483 }
484
485 int wilc_connecting;
486
487 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
488 tstrConnectInfo *pstrConnectInfo,
489 u8 u8MacStatus,
490 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
491 void *pUserVoid)
492 {
493 struct wilc_priv *priv;
494 struct net_device *dev;
495 struct host_if_drv *pstrWFIDrv;
496 u8 NullBssid[ETH_ALEN] = {0};
497 struct wilc *wl;
498 struct wilc_vif *vif;
499
500 wilc_connecting = 0;
501
502 priv = (struct wilc_priv *)pUserVoid;
503 dev = priv->dev;
504 vif = netdev_priv(dev);
505 wl = vif->wilc;
506 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
507
508 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
509 u16 u16ConnectStatus;
510
511 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
512
513 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
514
515 if ((u8MacStatus == MAC_DISCONNECTED) &&
516 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
517 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
518 wilc_wlan_set_bssid(priv->dev, NullBssid,
519 STATION_MODE);
520 eth_zero_addr(wilc_connected_ssid);
521
522 if (!pstrWFIDrv->p2p_connect)
523 wlan_channel = INVALID_CHANNEL;
524
525 netdev_err(dev, "Unspecified failure\n");
526 }
527
528 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
529 bool bNeedScanRefresh = false;
530 u32 i;
531
532 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
533 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
534 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
535
536
537 for (i = 0; i < last_scanned_cnt; i++) {
538 if (memcmp(last_scanned_shadow[i].au8bssid,
539 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
540 unsigned long now = jiffies;
541
542 if (time_after(now,
543 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
544 bNeedScanRefresh = true;
545 }
546
547 break;
548 }
549 }
550
551 if (bNeedScanRefresh)
552 refresh_scan(priv, 1, true);
553 }
554
555
556 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
557
558 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
559
560 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
561 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
562 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
563 u16ConnectStatus, GFP_KERNEL);
564 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
565 wilc_optaining_ip = false;
566 p2p_local_random = 0x01;
567 p2p_recv_random = 0x00;
568 wilc_ie = false;
569 eth_zero_addr(priv->au8AssociatedBss);
570 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
571 eth_zero_addr(wilc_connected_ssid);
572
573 if (!pstrWFIDrv->p2p_connect)
574 wlan_channel = INVALID_CHANNEL;
575 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
576 pstrDisconnectNotifInfo->u16reason = 3;
577 } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
578 pstrDisconnectNotifInfo->u16reason = 1;
579 }
580 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
581 pstrDisconnectNotifInfo->ie_len, false,
582 GFP_KERNEL);
583 }
584 }
585
586 static int set_channel(struct wiphy *wiphy,
587 struct cfg80211_chan_def *chandef)
588 {
589 u32 channelnum = 0;
590 struct wilc_priv *priv;
591 int result = 0;
592 struct wilc_vif *vif;
593
594 priv = wiphy_priv(wiphy);
595 vif = netdev_priv(priv->dev);
596
597 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
598 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
599
600 curr_channel = channelnum;
601 result = wilc_set_mac_chnl_num(vif, channelnum);
602
603 if (result != 0)
604 netdev_err(priv->dev, "Error in setting channel\n");
605
606 return result;
607 }
608
609 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
610 {
611 struct wilc_priv *priv;
612 u32 i;
613 s32 s32Error = 0;
614 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
615 struct hidden_network strHiddenNetwork;
616 struct wilc_vif *vif;
617
618 priv = wiphy_priv(wiphy);
619 vif = netdev_priv(priv->dev);
620
621 priv->pstrScanReq = request;
622
623 priv->u32RcvdChCount = 0;
624
625 reset_shadow_found();
626
627 priv->bCfgScanning = true;
628 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
629 for (i = 0; i < request->n_channels; i++) {
630 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
631 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
632 }
633
634 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
635 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
636
637 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
638
639 if (request->n_ssids >= 1) {
640 strHiddenNetwork.net_info = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
641 strHiddenNetwork.n_ssids = request->n_ssids;
642
643
644 for (i = 0; i < request->n_ssids; i++) {
645 if (request->ssids[i].ssid &&
646 request->ssids[i].ssid_len != 0) {
647 strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
648 memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
649 strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
650 } else {
651 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
652 strHiddenNetwork.n_ssids -= 1;
653 }
654 }
655 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
656 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
657 au8ScanChanList,
658 request->n_channels,
659 (const u8 *)request->ie,
660 request->ie_len, CfgScanResult,
661 (void *)priv, &strHiddenNetwork);
662 } else {
663 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
664 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
665 au8ScanChanList,
666 request->n_channels,
667 (const u8 *)request->ie,
668 request->ie_len, CfgScanResult,
669 (void *)priv, NULL);
670 }
671 } else {
672 netdev_err(priv->dev, "Requested scanned channels over\n");
673 }
674
675 if (s32Error != 0) {
676 s32Error = -EBUSY;
677 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
678 }
679
680 return s32Error;
681 }
682
683 static int connect(struct wiphy *wiphy, struct net_device *dev,
684 struct cfg80211_connect_params *sme)
685 {
686 s32 s32Error = 0;
687 u32 i;
688 u8 u8security = NO_ENCRYPT;
689 enum AUTHTYPE tenuAuth_type = ANY;
690 char *pcgroup_encrypt_val = NULL;
691 char *pccipher_group = NULL;
692 char *pcwpa_version = NULL;
693
694 struct wilc_priv *priv;
695 struct host_if_drv *pstrWFIDrv;
696 struct network_info *pstrNetworkInfo = NULL;
697 struct wilc_vif *vif;
698
699 wilc_connecting = 1;
700 priv = wiphy_priv(wiphy);
701 vif = netdev_priv(priv->dev);
702 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
703
704 PRINT_D(CFG80211_DBG,
705 "Connecting to SSID [%s] on netdev [%p] host if [%p]\n",
706 sme->ssid, dev, priv->hif_drv);
707 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
708 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
709 pstrWFIDrv->p2p_connect = 1;
710 } else {
711 pstrWFIDrv->p2p_connect = 0;
712 }
713 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
714
715 for (i = 0; i < last_scanned_cnt; i++) {
716 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
717 memcmp(last_scanned_shadow[i].au8ssid,
718 sme->ssid,
719 sme->ssid_len) == 0) {
720 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
721 if (!sme->bssid) {
722 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
723 break;
724 } else {
725 if (memcmp(last_scanned_shadow[i].au8bssid,
726 sme->bssid,
727 ETH_ALEN) == 0) {
728 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
729 break;
730 }
731 }
732 }
733 }
734
735 if (i < last_scanned_cnt) {
736 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
737
738 pstrNetworkInfo = &last_scanned_shadow[i];
739
740 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
741 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
742 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
743 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
744 } else {
745 s32Error = -ENOENT;
746 if (last_scanned_cnt == 0)
747 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
748 else
749 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
750 wilc_connecting = 0;
751 return s32Error;
752 }
753
754 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
755 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
756
757 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
758 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
759
760 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
761
762 if (sme->crypto.cipher_group != NO_ENCRYPT) {
763 pcwpa_version = "Default";
764 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
765 u8security = ENCRYPT_ENABLED | WEP;
766 pcgroup_encrypt_val = "WEP40";
767 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
768 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
769
770 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
771 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
772
773 g_key_wep_params.key_len = sme->key_len;
774 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
775 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
776 g_key_wep_params.key_idx = sme->key_idx;
777 g_wep_keys_saved = true;
778
779 wilc_set_wep_default_keyid(vif, sme->key_idx);
780 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
781 sme->key_idx);
782 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
783 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
784 pcgroup_encrypt_val = "WEP104";
785 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
786
787 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
788 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
789
790 g_key_wep_params.key_len = sme->key_len;
791 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
792 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
793 g_key_wep_params.key_idx = sme->key_idx;
794 g_wep_keys_saved = true;
795
796 wilc_set_wep_default_keyid(vif, sme->key_idx);
797 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
798 sme->key_idx);
799 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
800 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
801 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
802 pcgroup_encrypt_val = "WPA2_TKIP";
803 pccipher_group = "TKIP";
804 } else {
805 u8security = ENCRYPT_ENABLED | WPA2 | AES;
806 pcgroup_encrypt_val = "WPA2_AES";
807 pccipher_group = "AES";
808 }
809 pcwpa_version = "WPA_VERSION_2";
810 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
811 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
812 u8security = ENCRYPT_ENABLED | WPA | TKIP;
813 pcgroup_encrypt_val = "WPA_TKIP";
814 pccipher_group = "TKIP";
815 } else {
816 u8security = ENCRYPT_ENABLED | WPA | AES;
817 pcgroup_encrypt_val = "WPA_AES";
818 pccipher_group = "AES";
819 }
820 pcwpa_version = "WPA_VERSION_1";
821
822 } else {
823 s32Error = -ENOTSUPP;
824 netdev_err(dev, "Not supported cipher\n");
825 wilc_connecting = 0;
826 return s32Error;
827 }
828 }
829
830 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
831 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
832 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
833 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
834 u8security = u8security | TKIP;
835 } else {
836 u8security = u8security | AES;
837 }
838 }
839 }
840
841 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
842
843 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
844 switch (sme->auth_type) {
845 case NL80211_AUTHTYPE_OPEN_SYSTEM:
846 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
847 tenuAuth_type = OPEN_SYSTEM;
848 break;
849
850 case NL80211_AUTHTYPE_SHARED_KEY:
851 tenuAuth_type = SHARED_KEY;
852 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
853 break;
854
855 default:
856 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
857 }
858
859 if (sme->crypto.n_akm_suites) {
860 switch (sme->crypto.akm_suites[0]) {
861 case WLAN_AKM_SUITE_8021X:
862 tenuAuth_type = IEEE8021;
863 break;
864
865 default:
866 break;
867 }
868 }
869
870
871 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
872
873 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
874 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
875
876 curr_channel = pstrNetworkInfo->u8channel;
877
878 if (!pstrWFIDrv->p2p_connect)
879 wlan_channel = pstrNetworkInfo->u8channel;
880
881 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid, STATION_MODE);
882
883 s32Error = wilc_set_join_req(vif, pstrNetworkInfo->au8bssid, sme->ssid,
884 sme->ssid_len, sme->ie, sme->ie_len,
885 CfgConnectResult, (void *)priv,
886 u8security, tenuAuth_type,
887 pstrNetworkInfo->u8channel,
888 pstrNetworkInfo->pJoinParams);
889 if (s32Error != 0) {
890 netdev_err(dev, "wilc_set_join_req(): Error\n");
891 s32Error = -ENOENT;
892 wilc_connecting = 0;
893 return s32Error;
894 }
895
896 return s32Error;
897 }
898
899 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
900 {
901 s32 s32Error = 0;
902 struct wilc_priv *priv;
903 struct host_if_drv *pstrWFIDrv;
904 struct wilc_vif *vif;
905 u8 NullBssid[ETH_ALEN] = {0};
906
907 wilc_connecting = 0;
908 priv = wiphy_priv(wiphy);
909 vif = netdev_priv(priv->dev);
910
911 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
912 if (!pstrWFIDrv->p2p_connect)
913 wlan_channel = INVALID_CHANNEL;
914 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
915
916 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
917
918 p2p_local_random = 0x01;
919 p2p_recv_random = 0x00;
920 wilc_ie = false;
921 pstrWFIDrv->p2p_timeout = 0;
922
923 s32Error = wilc_disconnect(vif, reason_code);
924 if (s32Error != 0) {
925 netdev_err(priv->dev, "Error in disconnecting\n");
926 s32Error = -EINVAL;
927 }
928
929 return s32Error;
930 }
931
932 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
933 bool pairwise,
934 const u8 *mac_addr, struct key_params *params)
935
936 {
937 s32 s32Error = 0, KeyLen = params->key_len;
938 u32 i;
939 struct wilc_priv *priv;
940 const u8 *pu8RxMic = NULL;
941 const u8 *pu8TxMic = NULL;
942 u8 u8mode = NO_ENCRYPT;
943 u8 u8gmode = NO_ENCRYPT;
944 u8 u8pmode = NO_ENCRYPT;
945 enum AUTHTYPE tenuAuth_type = ANY;
946 struct wilc *wl;
947 struct wilc_vif *vif;
948
949 priv = wiphy_priv(wiphy);
950 vif = netdev_priv(netdev);
951 wl = vif->wilc;
952
953 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
954
955 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
956
957 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
958 params->key[1],
959 params->key[2]);
960
961
962 switch (params->cipher) {
963 case WLAN_CIPHER_SUITE_WEP40:
964 case WLAN_CIPHER_SUITE_WEP104:
965 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
966 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
967 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
968
969 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
970 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
971
972 for (i = 0; i < params->key_len; i++)
973 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
974
975 tenuAuth_type = OPEN_SYSTEM;
976
977 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
978 u8mode = ENCRYPT_ENABLED | WEP;
979 else
980 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
981
982 wilc_add_wep_key_bss_ap(vif, params->key,
983 params->key_len, key_index,
984 u8mode, tenuAuth_type);
985 break;
986 }
987 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
988 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
989 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
990
991 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
992 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
993 if (INFO) {
994 for (i = 0; i < params->key_len; i++)
995 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
996 }
997 wilc_add_wep_key_bss_sta(vif, params->key,
998 params->key_len, key_index);
999 }
1000
1001 break;
1002
1003 case WLAN_CIPHER_SUITE_TKIP:
1004 case WLAN_CIPHER_SUITE_CCMP:
1005 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1006 if (!priv->wilc_gtk[key_index]) {
1007 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
1008 priv->wilc_gtk[key_index]->key = NULL;
1009 priv->wilc_gtk[key_index]->seq = NULL;
1010 }
1011 if (!priv->wilc_ptk[key_index]) {
1012 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
1013 priv->wilc_ptk[key_index]->key = NULL;
1014 priv->wilc_ptk[key_index]->seq = NULL;
1015 }
1016
1017
1018
1019 if (!pairwise) {
1020 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1021 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1022 else
1023 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1024
1025 priv->wilc_groupkey = u8gmode;
1026
1027 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1028 pu8TxMic = params->key + 24;
1029 pu8RxMic = params->key + 16;
1030 KeyLen = params->key_len - 16;
1031 }
1032 kfree(priv->wilc_gtk[key_index]->key);
1033
1034 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
1035 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
1036 kfree(priv->wilc_gtk[key_index]->seq);
1037
1038 if ((params->seq_len) > 0) {
1039 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
1040 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
1041 }
1042
1043 priv->wilc_gtk[key_index]->cipher = params->cipher;
1044 priv->wilc_gtk[key_index]->key_len = params->key_len;
1045 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1046
1047 if (INFO) {
1048 for (i = 0; i < params->key_len; i++)
1049 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1050 for (i = 0; i < params->seq_len; i++)
1051 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1052 }
1053
1054
1055 wilc_add_rx_gtk(vif, params->key, KeyLen,
1056 key_index, params->seq_len,
1057 params->seq, pu8RxMic,
1058 pu8TxMic, AP_MODE, u8gmode);
1059
1060 } else {
1061 PRINT_INFO(CFG80211_DBG, "STA Address: %x%x%x%x%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4]);
1062
1063 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1064 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1065 else
1066 u8pmode = priv->wilc_groupkey | AES;
1067
1068
1069 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1070 pu8TxMic = params->key + 24;
1071 pu8RxMic = params->key + 16;
1072 KeyLen = params->key_len - 16;
1073 }
1074
1075 kfree(priv->wilc_ptk[key_index]->key);
1076
1077 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
1078
1079 kfree(priv->wilc_ptk[key_index]->seq);
1080
1081 if ((params->seq_len) > 0)
1082 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
1083
1084 if (INFO) {
1085 for (i = 0; i < params->key_len; i++)
1086 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1087
1088 for (i = 0; i < params->seq_len; i++)
1089 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1090 }
1091
1092 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
1093
1094 if ((params->seq_len) > 0)
1095 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
1096
1097 priv->wilc_ptk[key_index]->cipher = params->cipher;
1098 priv->wilc_ptk[key_index]->key_len = params->key_len;
1099 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1100
1101 wilc_add_ptk(vif, params->key, KeyLen,
1102 mac_addr, pu8RxMic, pu8TxMic,
1103 AP_MODE, u8pmode, key_index);
1104 }
1105 break;
1106 }
1107
1108 {
1109 u8mode = 0;
1110 if (!pairwise) {
1111 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1112 pu8RxMic = params->key + 24;
1113 pu8TxMic = params->key + 16;
1114 KeyLen = params->key_len - 16;
1115 }
1116
1117 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
1118 g_add_gtk_key_params.key_idx = key_index;
1119 g_add_gtk_key_params.pairwise = pairwise;
1120 if (!mac_addr) {
1121 g_add_gtk_key_params.mac_addr = NULL;
1122 } else {
1123 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1124 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1125 }
1126 g_key_gtk_params.key_len = params->key_len;
1127 g_key_gtk_params.seq_len = params->seq_len;
1128 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1129 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1130 if (params->seq_len > 0) {
1131 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1132 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1133 }
1134 g_key_gtk_params.cipher = params->cipher;
1135
1136 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1137 g_key_gtk_params.key[1],
1138 g_key_gtk_params.key[2]);
1139 g_gtk_keys_saved = true;
1140 }
1141
1142 wilc_add_rx_gtk(vif, params->key, KeyLen,
1143 key_index, params->seq_len,
1144 params->seq, pu8RxMic,
1145 pu8TxMic, STATION_MODE,
1146 u8mode);
1147 } else {
1148 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1149 pu8RxMic = params->key + 24;
1150 pu8TxMic = params->key + 16;
1151 KeyLen = params->key_len - 16;
1152 }
1153
1154 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1155 g_add_ptk_key_params.key_idx = key_index;
1156 g_add_ptk_key_params.pairwise = pairwise;
1157 if (!mac_addr) {
1158 g_add_ptk_key_params.mac_addr = NULL;
1159 } else {
1160 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1161 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1162 }
1163 g_key_ptk_params.key_len = params->key_len;
1164 g_key_ptk_params.seq_len = params->seq_len;
1165 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1166 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1167 if (params->seq_len > 0) {
1168 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1169 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1170 }
1171 g_key_ptk_params.cipher = params->cipher;
1172
1173 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1174 g_key_ptk_params.key[1],
1175 g_key_ptk_params.key[2]);
1176 g_ptk_keys_saved = true;
1177 }
1178
1179 wilc_add_ptk(vif, params->key, KeyLen,
1180 mac_addr, pu8RxMic, pu8TxMic,
1181 STATION_MODE, u8mode, key_index);
1182 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1183 if (INFO) {
1184 for (i = 0; i < params->key_len; i++)
1185 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1186 }
1187 }
1188 }
1189 break;
1190
1191 default:
1192 netdev_err(netdev, "Not supported cipher\n");
1193 s32Error = -ENOTSUPP;
1194 }
1195
1196 return s32Error;
1197 }
1198
1199 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1200 u8 key_index,
1201 bool pairwise,
1202 const u8 *mac_addr)
1203 {
1204 struct wilc_priv *priv;
1205 struct wilc *wl;
1206 struct wilc_vif *vif;
1207
1208 priv = wiphy_priv(wiphy);
1209 vif = netdev_priv(netdev);
1210 wl = vif->wilc;
1211
1212 if (netdev == wl->vif[0]->ndev) {
1213 g_ptk_keys_saved = false;
1214 g_gtk_keys_saved = false;
1215 g_wep_keys_saved = false;
1216
1217 kfree(g_key_wep_params.key);
1218 g_key_wep_params.key = NULL;
1219
1220 if ((priv->wilc_gtk[key_index]) != NULL) {
1221 kfree(priv->wilc_gtk[key_index]->key);
1222 priv->wilc_gtk[key_index]->key = NULL;
1223 kfree(priv->wilc_gtk[key_index]->seq);
1224 priv->wilc_gtk[key_index]->seq = NULL;
1225
1226 kfree(priv->wilc_gtk[key_index]);
1227 priv->wilc_gtk[key_index] = NULL;
1228 }
1229
1230 if ((priv->wilc_ptk[key_index]) != NULL) {
1231 kfree(priv->wilc_ptk[key_index]->key);
1232 priv->wilc_ptk[key_index]->key = NULL;
1233 kfree(priv->wilc_ptk[key_index]->seq);
1234 priv->wilc_ptk[key_index]->seq = NULL;
1235 kfree(priv->wilc_ptk[key_index]);
1236 priv->wilc_ptk[key_index] = NULL;
1237 }
1238
1239 kfree(g_key_ptk_params.key);
1240 g_key_ptk_params.key = NULL;
1241 kfree(g_key_ptk_params.seq);
1242 g_key_ptk_params.seq = NULL;
1243
1244 kfree(g_key_gtk_params.key);
1245 g_key_gtk_params.key = NULL;
1246 kfree(g_key_gtk_params.seq);
1247 g_key_gtk_params.seq = NULL;
1248
1249 }
1250
1251 if (key_index >= 0 && key_index <= 3) {
1252 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
1253 priv->WILC_WFI_wep_key_len[key_index] = 0;
1254
1255 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
1256 wilc_remove_wep_key(vif, key_index);
1257 } else {
1258 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
1259 wilc_remove_key(priv->hif_drv, mac_addr);
1260 }
1261
1262 return 0;
1263 }
1264
1265 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1266 bool pairwise,
1267 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1268 {
1269 struct wilc_priv *priv;
1270 struct key_params key_params;
1271 u32 i;
1272
1273 priv = wiphy_priv(wiphy);
1274
1275
1276 if (!pairwise) {
1277 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1278
1279 key_params.key = priv->wilc_gtk[key_index]->key;
1280 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1281 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1282 key_params.seq = priv->wilc_gtk[key_index]->seq;
1283 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1284 if (INFO) {
1285 for (i = 0; i < key_params.key_len; i++)
1286 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1287 }
1288 } else {
1289 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1290
1291 key_params.key = priv->wilc_ptk[key_index]->key;
1292 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1293 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1294 key_params.seq = priv->wilc_ptk[key_index]->seq;
1295 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1296 }
1297
1298 callback(cookie, &key_params);
1299
1300 return 0;
1301 }
1302
1303 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1304 bool unicast, bool multicast)
1305 {
1306 struct wilc_priv *priv;
1307 struct wilc_vif *vif;
1308
1309 priv = wiphy_priv(wiphy);
1310 vif = netdev_priv(priv->dev);
1311
1312 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
1313
1314 wilc_set_wep_default_keyid(vif, key_index);
1315
1316 return 0;
1317 }
1318
1319 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1320 const u8 *mac, struct station_info *sinfo)
1321 {
1322 struct wilc_priv *priv;
1323 struct wilc_vif *vif;
1324 u32 i = 0;
1325 u32 associatedsta = 0;
1326 u32 inactive_time = 0;
1327 priv = wiphy_priv(wiphy);
1328 vif = netdev_priv(dev);
1329
1330 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1331 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1332
1333 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1334
1335 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1336 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1337 associatedsta = i;
1338 break;
1339 }
1340 }
1341
1342 if (associatedsta == -1) {
1343 netdev_err(dev, "sta required is not associated\n");
1344 return -ENOENT;
1345 }
1346
1347 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1348
1349 wilc_get_inactive_time(vif, mac, &inactive_time);
1350 sinfo->inactive_time = 1000 * inactive_time;
1351 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1352 }
1353
1354 if (vif->iftype == STATION_MODE) {
1355 struct rf_info strStatistics;
1356
1357 wilc_get_statistics(vif, &strStatistics);
1358
1359 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1360 BIT(NL80211_STA_INFO_RX_PACKETS) |
1361 BIT(NL80211_STA_INFO_TX_PACKETS) |
1362 BIT(NL80211_STA_INFO_TX_FAILED) |
1363 BIT(NL80211_STA_INFO_TX_BITRATE);
1364
1365 sinfo->signal = strStatistics.rssi;
1366 sinfo->rx_packets = strStatistics.rx_cnt;
1367 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1368 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1369 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1370
1371 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1372 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1373 wilc_enable_tcp_ack_filter(true);
1374 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1375 wilc_enable_tcp_ack_filter(false);
1376 }
1377 return 0;
1378 }
1379
1380 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1381 struct bss_parameters *params)
1382 {
1383 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1384 return 0;
1385 }
1386
1387 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1388 {
1389 s32 s32Error = 0;
1390 struct cfg_param_val pstrCfgParamVal;
1391 struct wilc_priv *priv;
1392 struct wilc_vif *vif;
1393
1394 priv = wiphy_priv(wiphy);
1395 vif = netdev_priv(priv->dev);
1396
1397 pstrCfgParamVal.flag = 0;
1398 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
1399
1400 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1401 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1402 priv->dev->ieee80211_ptr->wiphy->retry_short);
1403 pstrCfgParamVal.flag |= RETRY_SHORT;
1404 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1405 }
1406 if (changed & WIPHY_PARAM_RETRY_LONG) {
1407 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
1408 pstrCfgParamVal.flag |= RETRY_LONG;
1409 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1410 }
1411 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1412 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
1413 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1414 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1415 }
1416
1417 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1418 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1419
1420 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1421 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1422 }
1423
1424 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
1425 s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1426 if (s32Error)
1427 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1428
1429 return s32Error;
1430 }
1431
1432 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1433 struct cfg80211_pmksa *pmksa)
1434 {
1435 u32 i;
1436 s32 s32Error = 0;
1437 u8 flag = 0;
1438 struct wilc_vif *vif;
1439 struct wilc_priv *priv = wiphy_priv(wiphy);
1440
1441 vif = netdev_priv(priv->dev);
1442 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1443
1444
1445 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1446 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1447 ETH_ALEN)) {
1448 flag = PMKID_FOUND;
1449 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1450 break;
1451 }
1452 }
1453 if (i < WILC_MAX_NUM_PMKIDS) {
1454 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
1455 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1456 ETH_ALEN);
1457 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1458 PMKID_LEN);
1459 if (!(flag == PMKID_FOUND))
1460 priv->pmkid_list.numpmkid++;
1461 } else {
1462 netdev_err(netdev, "Invalid PMKID index\n");
1463 s32Error = -EINVAL;
1464 }
1465
1466 if (!s32Error) {
1467 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
1468 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1469 }
1470 return s32Error;
1471 }
1472
1473 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1474 struct cfg80211_pmksa *pmksa)
1475 {
1476 u32 i;
1477 s32 s32Error = 0;
1478
1479 struct wilc_priv *priv = wiphy_priv(wiphy);
1480
1481 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1482
1483 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1484 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1485 ETH_ALEN)) {
1486 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
1487 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1488 break;
1489 }
1490 }
1491
1492 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1493 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1494 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1495 priv->pmkid_list.pmkidlist[i + 1].bssid,
1496 ETH_ALEN);
1497 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1498 priv->pmkid_list.pmkidlist[i].pmkid,
1499 PMKID_LEN);
1500 }
1501 priv->pmkid_list.numpmkid--;
1502 } else {
1503 s32Error = -EINVAL;
1504 }
1505
1506 return s32Error;
1507 }
1508
1509 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1510 {
1511 struct wilc_priv *priv = wiphy_priv(wiphy);
1512
1513 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1514
1515 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1516
1517 return 0;
1518 }
1519
1520 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1521 {
1522 u32 index = 0;
1523 u32 i = 0, j = 0;
1524
1525 u8 op_channel_attr_index = 0;
1526 u8 channel_list_attr_index = 0;
1527
1528 while (index < len) {
1529 if (buf[index] == GO_INTENT_ATTR_ID) {
1530 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
1531 }
1532
1533 if (buf[index] == CHANLIST_ATTR_ID)
1534 channel_list_attr_index = index;
1535 else if (buf[index] == OPERCHAN_ATTR_ID)
1536 op_channel_attr_index = index;
1537 index += buf[index + 1] + 3;
1538 }
1539 if (wlan_channel != INVALID_CHANNEL) {
1540 if (channel_list_attr_index) {
1541 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1542 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1543 if (buf[i] == 0x51) {
1544 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1545 buf[j] = wlan_channel;
1546 }
1547 break;
1548 }
1549 }
1550 }
1551
1552 if (op_channel_attr_index) {
1553 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1554 buf[op_channel_attr_index + 6] = 0x51;
1555 buf[op_channel_attr_index + 7] = wlan_channel;
1556 }
1557 }
1558 }
1559
1560 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1561 {
1562 u32 index = 0;
1563 u32 i = 0, j = 0;
1564
1565 u8 op_channel_attr_index = 0;
1566 u8 channel_list_attr_index = 0;
1567
1568 while (index < len) {
1569 if (buf[index] == GO_INTENT_ATTR_ID) {
1570 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
1571
1572 break;
1573 }
1574
1575 if (buf[index] == CHANLIST_ATTR_ID)
1576 channel_list_attr_index = index;
1577 else if (buf[index] == OPERCHAN_ATTR_ID)
1578 op_channel_attr_index = index;
1579 index += buf[index + 1] + 3;
1580 }
1581 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1582 if (channel_list_attr_index) {
1583 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1584 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1585 if (buf[i] == 0x51) {
1586 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1587 buf[j] = wlan_channel;
1588 }
1589 break;
1590 }
1591 }
1592 }
1593
1594 if (op_channel_attr_index) {
1595 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1596 buf[op_channel_attr_index + 6] = 0x51;
1597 buf[op_channel_attr_index + 7] = wlan_channel;
1598 }
1599 }
1600 }
1601
1602 void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
1603 {
1604 struct wilc_priv *priv;
1605 u32 header, pkt_offset;
1606 struct host_if_drv *pstrWFIDrv;
1607 u32 i = 0;
1608 s32 s32Freq;
1609
1610 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1611 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1612
1613 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1614
1615 pkt_offset = GET_PKT_OFFSET(header);
1616
1617 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1618 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1619 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
1620 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1621 return;
1622 } else {
1623 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1624 PRINT_D(GENERIC_DBG, "Success Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID],
1625 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
1626 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1627 } else {
1628 PRINT_D(GENERIC_DBG, "Fail Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID],
1629 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
1630 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1631 }
1632 return;
1633 }
1634 } else {
1635 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1636
1637 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
1638
1639 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1640 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1641
1642 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1643 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1644 return;
1645 }
1646 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1647 switch (buff[ACTION_SUBTYPE_ID]) {
1648 case GAS_INTIAL_REQ:
1649 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1650 break;
1651
1652 case GAS_INTIAL_RSP:
1653 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1654 break;
1655
1656 case PUBLIC_ACT_VENDORSPEC:
1657 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1658 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1659 if (!wilc_ie) {
1660 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1661 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1662 p2p_recv_random = buff[i + 6];
1663 wilc_ie = true;
1664 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
1665 break;
1666 }
1667 }
1668 }
1669 }
1670 if (p2p_local_random > p2p_recv_random) {
1671 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1672 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1673 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1674 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1675 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1676 break;
1677 }
1678 }
1679 }
1680 } else {
1681 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1682 }
1683 }
1684
1685
1686 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
1687 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
1688 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1689 return;
1690 }
1691 break;
1692
1693 default:
1694 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1695 break;
1696 }
1697 }
1698 }
1699
1700 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1701 }
1702 }
1703
1704 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1705 {
1706 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1707
1708
1709 kfree(pv_data->buff);
1710 kfree(pv_data);
1711 }
1712
1713 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1714 {
1715 struct wilc_priv *priv;
1716
1717 priv = (struct wilc_priv *)pUserVoid;
1718
1719 priv->bInP2PlistenState = true;
1720
1721 cfg80211_ready_on_channel(priv->wdev,
1722 priv->strRemainOnChanParams.u64ListenCookie,
1723 priv->strRemainOnChanParams.pstrListenChan,
1724 priv->strRemainOnChanParams.u32ListenDuration,
1725 GFP_KERNEL);
1726 }
1727
1728 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1729 {
1730 struct wilc_priv *priv;
1731
1732 priv = (struct wilc_priv *)pUserVoid;
1733
1734 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1735 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
1736
1737 priv->bInP2PlistenState = false;
1738
1739 cfg80211_remain_on_channel_expired(priv->wdev,
1740 priv->strRemainOnChanParams.u64ListenCookie,
1741 priv->strRemainOnChanParams.pstrListenChan,
1742 GFP_KERNEL);
1743 } else {
1744 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
1745 , priv->strRemainOnChanParams.u32ListenSessionID);
1746 }
1747 }
1748
1749 static int remain_on_channel(struct wiphy *wiphy,
1750 struct wireless_dev *wdev,
1751 struct ieee80211_channel *chan,
1752 unsigned int duration, u64 *cookie)
1753 {
1754 s32 s32Error = 0;
1755 struct wilc_priv *priv;
1756 struct wilc_vif *vif;
1757
1758 priv = wiphy_priv(wiphy);
1759 vif = netdev_priv(priv->dev);
1760
1761 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
1762
1763
1764 if (wdev->iftype == NL80211_IFTYPE_AP) {
1765 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
1766 return s32Error;
1767 }
1768
1769 curr_channel = chan->hw_value;
1770
1771 priv->strRemainOnChanParams.pstrListenChan = chan;
1772 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1773 priv->strRemainOnChanParams.u32ListenDuration = duration;
1774 priv->strRemainOnChanParams.u32ListenSessionID++;
1775
1776 s32Error = wilc_remain_on_channel(vif,
1777 priv->strRemainOnChanParams.u32ListenSessionID,
1778 duration, chan->hw_value,
1779 WILC_WFI_RemainOnChannelExpired,
1780 WILC_WFI_RemainOnChannelReady, (void *)priv);
1781
1782 return s32Error;
1783 }
1784
1785 static int cancel_remain_on_channel(struct wiphy *wiphy,
1786 struct wireless_dev *wdev,
1787 u64 cookie)
1788 {
1789 s32 s32Error = 0;
1790 struct wilc_priv *priv;
1791 struct wilc_vif *vif;
1792
1793 priv = wiphy_priv(wiphy);
1794 vif = netdev_priv(priv->dev);
1795
1796 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1797
1798 s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
1799 return s32Error;
1800 }
1801
1802 static int mgmt_tx(struct wiphy *wiphy,
1803 struct wireless_dev *wdev,
1804 struct cfg80211_mgmt_tx_params *params,
1805 u64 *cookie)
1806 {
1807 struct ieee80211_channel *chan = params->chan;
1808 unsigned int wait = params->wait;
1809 const u8 *buf = params->buf;
1810 size_t len = params->len;
1811 const struct ieee80211_mgmt *mgmt;
1812 struct p2p_mgmt_data *mgmt_tx;
1813 struct wilc_priv *priv;
1814 struct host_if_drv *pstrWFIDrv;
1815 u32 i;
1816 struct wilc_vif *vif;
1817 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1818
1819 vif = netdev_priv(wdev->netdev);
1820 priv = wiphy_priv(wiphy);
1821 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1822
1823 *cookie = (unsigned long)buf;
1824 priv->u64tx_cookie = *cookie;
1825 mgmt = (const struct ieee80211_mgmt *) buf;
1826
1827 if (ieee80211_is_mgmt(mgmt->frame_control)) {
1828 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1829 if (!mgmt_tx)
1830 return -EFAULT;
1831
1832 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1833 if (!mgmt_tx->buff)
1834 kfree(mgmt_tx);
1835 return -EFAULT;
1836
1837 memcpy(mgmt_tx->buff, buf, len);
1838 mgmt_tx->size = len;
1839
1840
1841 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1842 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
1843 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
1844 wilc_set_mac_chnl_num(vif, chan->hw_value);
1845 curr_channel = chan->hw_value;
1846 } else if (ieee80211_is_action(mgmt->frame_control)) {
1847 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
1848
1849
1850 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1851 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1852 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1853 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
1854 wilc_set_mac_chnl_num(vif,
1855 chan->hw_value);
1856 curr_channel = chan->hw_value;
1857 }
1858 switch (buf[ACTION_SUBTYPE_ID]) {
1859 case GAS_INTIAL_REQ:
1860 {
1861 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
1862 break;
1863 }
1864
1865 case GAS_INTIAL_RSP:
1866 {
1867 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
1868 break;
1869 }
1870
1871 case PUBLIC_ACT_VENDORSPEC:
1872 {
1873 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1874 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1875 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1876 get_random_bytes(&p2p_local_random, 1);
1877 p2p_local_random++;
1878 }
1879 }
1880
1881 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1882 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1883 if (p2p_local_random > p2p_recv_random) {
1884 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1885
1886 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1887 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1888 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1889 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1890 else
1891 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1892 break;
1893 }
1894 }
1895
1896 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1897 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1898 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1899 mgmt_tx->size = buf_len;
1900 }
1901 } else {
1902 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1903 }
1904 }
1905
1906 } else {
1907 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
1908 }
1909
1910 break;
1911 }
1912
1913 default:
1914 {
1915 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1916 break;
1917 }
1918 }
1919 }
1920
1921 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
1922 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1923
1924 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
1925 jiffies, pstrWFIDrv->p2p_timeout);
1926 }
1927
1928 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1929 mgmt_tx->buff, mgmt_tx->size,
1930 WILC_WFI_mgmt_tx_complete);
1931 } else {
1932 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
1933 }
1934 return 0;
1935 }
1936
1937 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1938 struct wireless_dev *wdev,
1939 u64 cookie)
1940 {
1941 struct wilc_priv *priv;
1942 struct host_if_drv *pstrWFIDrv;
1943
1944 priv = wiphy_priv(wiphy);
1945 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1946
1947
1948 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
1949 pstrWFIDrv->p2p_timeout = jiffies;
1950
1951 if (!priv->bInP2PlistenState) {
1952 cfg80211_remain_on_channel_expired(priv->wdev,
1953 priv->strRemainOnChanParams.u64ListenCookie,
1954 priv->strRemainOnChanParams.pstrListenChan,
1955 GFP_KERNEL);
1956 }
1957
1958 return 0;
1959 }
1960
1961 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1962 u16 frame_type, bool reg)
1963 {
1964 struct wilc_priv *priv;
1965 struct wilc_vif *vif;
1966 struct wilc *wl;
1967
1968 priv = wiphy_priv(wiphy);
1969 vif = netdev_priv(priv->wdev->netdev);
1970 wl = vif->wilc;
1971
1972 if (!frame_type)
1973 return;
1974
1975 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
1976 switch (frame_type) {
1977 case PROBE_REQ:
1978 {
1979 vif->g_struct_frame_reg[0].frame_type = frame_type;
1980 vif->g_struct_frame_reg[0].reg = reg;
1981 }
1982 break;
1983
1984 case ACTION:
1985 {
1986 vif->g_struct_frame_reg[1].frame_type = frame_type;
1987 vif->g_struct_frame_reg[1].reg = reg;
1988 }
1989 break;
1990
1991 default:
1992 {
1993 break;
1994 }
1995 }
1996
1997 if (!wl->initialized) {
1998 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
1999 return;
2000 }
2001 wilc_frame_register(vif, frame_type, reg);
2002 }
2003
2004 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2005 s32 rssi_thold, u32 rssi_hyst)
2006 {
2007 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2008 return 0;
2009 }
2010
2011 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2012 int idx, u8 *mac, struct station_info *sinfo)
2013 {
2014 struct wilc_priv *priv;
2015 struct wilc_vif *vif;
2016
2017 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2018
2019 if (idx != 0)
2020 return -ENOENT;
2021
2022 priv = wiphy_priv(wiphy);
2023 vif = netdev_priv(priv->dev);
2024
2025 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2026
2027 wilc_get_rssi(vif, &sinfo->signal);
2028
2029 return 0;
2030 }
2031
2032 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2033 bool enabled, int timeout)
2034 {
2035 struct wilc_priv *priv;
2036 struct wilc_vif *vif;
2037
2038 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2039
2040 if (!wiphy)
2041 return -ENOENT;
2042
2043 priv = wiphy_priv(wiphy);
2044 vif = netdev_priv(priv->dev);
2045 if (!priv->hif_drv)
2046 return -EIO;
2047
2048 if (wilc_enable_ps)
2049 wilc_set_power_mgmt(vif, enabled, timeout);
2050
2051
2052 return 0;
2053 }
2054
2055 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2056 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
2057 {
2058 struct wilc_priv *priv;
2059 struct wilc_vif *vif;
2060 struct wilc *wl;
2061
2062 vif = netdev_priv(dev);
2063 priv = wiphy_priv(wiphy);
2064 wl = vif->wilc;
2065
2066 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2067 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2068 p2p_local_random = 0x01;
2069 p2p_recv_random = 0x00;
2070 wilc_ie = false;
2071 wilc_optaining_ip = false;
2072 del_timer(&wilc_during_ip_timer);
2073 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
2074
2075 switch (type) {
2076 case NL80211_IFTYPE_STATION:
2077 wilc_connecting = 0;
2078 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
2079
2080 dev->ieee80211_ptr->iftype = type;
2081 priv->wdev->iftype = type;
2082 vif->monitor_flag = 0;
2083 vif->iftype = STATION_MODE;
2084 wilc_set_operation_mode(vif, STATION_MODE);
2085
2086 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
2087
2088 wilc_enable_ps = true;
2089 wilc_set_power_mgmt(vif, 1, 0);
2090 break;
2091
2092 case NL80211_IFTYPE_P2P_CLIENT:
2093 wilc_connecting = 0;
2094 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
2095
2096 dev->ieee80211_ptr->iftype = type;
2097 priv->wdev->iftype = type;
2098 vif->monitor_flag = 0;
2099 vif->iftype = CLIENT_MODE;
2100 wilc_set_operation_mode(vif, STATION_MODE);
2101
2102 wilc_enable_ps = false;
2103 wilc_set_power_mgmt(vif, 0, 0);
2104 break;
2105
2106 case NL80211_IFTYPE_AP:
2107 wilc_enable_ps = false;
2108 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
2109 dev->ieee80211_ptr->iftype = type;
2110 priv->wdev->iftype = type;
2111 vif->iftype = AP_MODE;
2112
2113 if (wl->initialized) {
2114 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
2115 0);
2116 wilc_set_operation_mode(vif, AP_MODE);
2117 wilc_set_power_mgmt(vif, 0, 0);
2118 }
2119 break;
2120
2121 case NL80211_IFTYPE_P2P_GO:
2122 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2123
2124 wilc_optaining_ip = true;
2125 mod_timer(&wilc_during_ip_timer,
2126 jiffies + msecs_to_jiffies(during_ip_time));
2127 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
2128
2129 wilc_set_operation_mode(vif, AP_MODE);
2130 dev->ieee80211_ptr->iftype = type;
2131 priv->wdev->iftype = type;
2132 vif->iftype = GO_MODE;
2133
2134 wilc_enable_ps = false;
2135 wilc_set_power_mgmt(vif, 0, 0);
2136 break;
2137
2138 default:
2139 netdev_err(dev, "Unknown interface type= %d\n", type);
2140 return -EINVAL;
2141 }
2142
2143 return 0;
2144 }
2145
2146 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2147 struct cfg80211_ap_settings *settings)
2148 {
2149 struct cfg80211_beacon_data *beacon = &(settings->beacon);
2150 struct wilc_priv *priv;
2151 s32 s32Error = 0;
2152 struct wilc *wl;
2153 struct wilc_vif *vif;
2154
2155 priv = wiphy_priv(wiphy);
2156 vif = netdev_priv(dev);
2157 wl = vif ->wilc;
2158 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2159
2160 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
2161 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2162
2163 s32Error = set_channel(wiphy, &settings->chandef);
2164
2165 if (s32Error != 0)
2166 netdev_err(dev, "Error in setting channel\n");
2167
2168 wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
2169 wilc_set_power_mgmt(vif, 0, 0);
2170
2171 s32Error = wilc_add_beacon(vif, settings->beacon_interval,
2172 settings->dtim_period, beacon->head_len,
2173 (u8 *)beacon->head, beacon->tail_len,
2174 (u8 *)beacon->tail);
2175
2176 return s32Error;
2177 }
2178
2179 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2180 struct cfg80211_beacon_data *beacon)
2181 {
2182 struct wilc_priv *priv;
2183 struct wilc_vif *vif;
2184 s32 s32Error = 0;
2185
2186 priv = wiphy_priv(wiphy);
2187 vif = netdev_priv(priv->dev);
2188 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2189
2190
2191 s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
2192 (u8 *)beacon->head, beacon->tail_len,
2193 (u8 *)beacon->tail);
2194
2195 return s32Error;
2196 }
2197
2198 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
2199 {
2200 s32 s32Error = 0;
2201 struct wilc_priv *priv;
2202 struct wilc_vif *vif;
2203 u8 NullBssid[ETH_ALEN] = {0};
2204
2205 if (!wiphy)
2206 return -EFAULT;
2207
2208 priv = wiphy_priv(wiphy);
2209 vif = netdev_priv(priv->dev);
2210
2211 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2212
2213 wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
2214
2215 s32Error = wilc_del_beacon(vif);
2216
2217 if (s32Error)
2218 netdev_err(dev, "Host delete beacon fail\n");
2219
2220 return s32Error;
2221 }
2222
2223 static int add_station(struct wiphy *wiphy, struct net_device *dev,
2224 const u8 *mac, struct station_parameters *params)
2225 {
2226 s32 s32Error = 0;
2227 struct wilc_priv *priv;
2228 struct add_sta_param strStaParams = { {0} };
2229 struct wilc_vif *vif;
2230
2231 if (!wiphy)
2232 return -EFAULT;
2233
2234 priv = wiphy_priv(wiphy);
2235 vif = netdev_priv(dev);
2236
2237 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2238 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2239 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
2240 strStaParams.aid = params->aid;
2241 strStaParams.rates_len = params->supported_rates_len;
2242 strStaParams.rates = params->supported_rates;
2243
2244 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2245
2246 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
2247 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
2248 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
2249 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2250 strStaParams.rates_len);
2251
2252 if (!params->ht_capa) {
2253 strStaParams.ht_supported = false;
2254 } else {
2255 strStaParams.ht_supported = true;
2256 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2257 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2258 memcpy(strStaParams.ht_supp_mcs_set,
2259 &params->ht_capa->mcs,
2260 WILC_SUPP_MCS_SET_SIZE);
2261 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2262 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2263 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2264 }
2265
2266 strStaParams.flags_mask = params->sta_flags_mask;
2267 strStaParams.flags_set = params->sta_flags_set;
2268
2269 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2270 strStaParams.ht_supported);
2271 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2272 strStaParams.ht_capa_info);
2273 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2274 strStaParams.ht_ampdu_params);
2275 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2276 strStaParams.ht_ext_params);
2277 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2278 strStaParams.ht_tx_bf_cap);
2279 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2280 strStaParams.ht_ante_sel);
2281 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2282 strStaParams.flags_mask);
2283 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2284 strStaParams.flags_set);
2285
2286 s32Error = wilc_add_station(vif, &strStaParams);
2287 if (s32Error)
2288 netdev_err(dev, "Host add station fail\n");
2289 }
2290
2291 return s32Error;
2292 }
2293
2294 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2295 struct station_del_parameters *params)
2296 {
2297 const u8 *mac = params->mac;
2298 s32 s32Error = 0;
2299 struct wilc_priv *priv;
2300 struct wilc_vif *vif;
2301
2302 if (!wiphy)
2303 return -EFAULT;
2304
2305 priv = wiphy_priv(wiphy);
2306 vif = netdev_priv(dev);
2307
2308 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2309 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2310
2311
2312 if (!mac) {
2313 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
2314 s32Error = wilc_del_allstation(vif,
2315 priv->assoc_stainfo.au8Sta_AssociatedBss);
2316 } else {
2317 PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
2318 }
2319
2320 s32Error = wilc_del_station(vif, mac);
2321
2322 if (s32Error)
2323 netdev_err(dev, "Host delete station fail\n");
2324 }
2325 return s32Error;
2326 }
2327
2328 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2329 const u8 *mac, struct station_parameters *params)
2330 {
2331 s32 s32Error = 0;
2332 struct wilc_priv *priv;
2333 struct add_sta_param strStaParams = { {0} };
2334 struct wilc_vif *vif;
2335
2336
2337 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2338
2339 if (!wiphy)
2340 return -EFAULT;
2341
2342 priv = wiphy_priv(wiphy);
2343 vif = netdev_priv(dev);
2344
2345 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2346 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2347 strStaParams.aid = params->aid;
2348 strStaParams.rates_len = params->supported_rates_len;
2349 strStaParams.rates = params->supported_rates;
2350
2351 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2352 strStaParams.bssid[0], strStaParams.bssid[1],
2353 strStaParams.bssid[2], strStaParams.bssid[3],
2354 strStaParams.bssid[4], strStaParams.bssid[5]);
2355 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
2356 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2357 strStaParams.rates_len);
2358
2359 if (!params->ht_capa) {
2360 strStaParams.ht_supported = false;
2361 } else {
2362 strStaParams.ht_supported = true;
2363 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2364 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2365 memcpy(strStaParams.ht_supp_mcs_set,
2366 &params->ht_capa->mcs,
2367 WILC_SUPP_MCS_SET_SIZE);
2368 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2369 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2370 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2371 }
2372
2373 strStaParams.flags_mask = params->sta_flags_mask;
2374 strStaParams.flags_set = params->sta_flags_set;
2375
2376 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2377 strStaParams.ht_supported);
2378 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2379 strStaParams.ht_capa_info);
2380 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2381 strStaParams.ht_ampdu_params);
2382 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2383 strStaParams.ht_ext_params);
2384 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2385 strStaParams.ht_tx_bf_cap);
2386 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2387 strStaParams.ht_ante_sel);
2388 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2389 strStaParams.flags_mask);
2390 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2391 strStaParams.flags_set);
2392
2393 s32Error = wilc_edit_station(vif, &strStaParams);
2394 if (s32Error)
2395 netdev_err(dev, "Host edit station fail\n");
2396 }
2397 return s32Error;
2398 }
2399
2400 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2401 const char *name,
2402 unsigned char name_assign_type,
2403 enum nl80211_iftype type,
2404 u32 *flags,
2405 struct vif_params *params)
2406 {
2407 struct wilc_vif *vif;
2408 struct wilc_priv *priv;
2409 struct net_device *new_ifc = NULL;
2410
2411 priv = wiphy_priv(wiphy);
2412
2413
2414
2415 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2416
2417 vif = netdev_priv(priv->wdev->netdev);
2418
2419
2420 if (type == NL80211_IFTYPE_MONITOR) {
2421 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
2422 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->ndev);
2423 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2424 if (new_ifc) {
2425 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
2426 vif = netdev_priv(priv->wdev->netdev);
2427 vif->monitor_flag = 1;
2428 }
2429 }
2430 return priv->wdev;
2431 }
2432
2433 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2434 {
2435 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
2436 return 0;
2437 }
2438
2439 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2440 {
2441 struct wilc_priv *priv = wiphy_priv(wiphy);
2442 struct wilc_vif *vif = netdev_priv(priv->dev);
2443
2444 if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2445 vif->wilc->suspend_event = true;
2446 else
2447 vif->wilc->suspend_event = false;
2448
2449 return 0;
2450 }
2451
2452 static int wilc_resume(struct wiphy *wiphy)
2453 {
2454 struct wilc_priv *priv = wiphy_priv(wiphy);
2455 struct wilc_vif *vif = netdev_priv(priv->dev);
2456
2457 netdev_info(vif->ndev, "cfg resume\n");
2458 return 0;
2459 }
2460
2461 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2462 {
2463 struct wilc_priv *priv = wiphy_priv(wiphy);
2464 struct wilc_vif *vif = netdev_priv(priv->dev);
2465
2466 netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2467 }
2468
2469 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2470 enum nl80211_tx_power_setting type, int mbm)
2471 {
2472 int ret;
2473 s32 tx_power = MBM_TO_DBM(mbm);
2474 struct wilc_priv *priv = wiphy_priv(wiphy);
2475 struct wilc_vif *vif = netdev_priv(priv->dev);
2476
2477 if (tx_power < 0)
2478 tx_power = 0;
2479 else if (tx_power > 18)
2480 tx_power = 18;
2481 ret = wilc_set_tx_power(vif, tx_power);
2482 if (ret)
2483 netdev_err(vif->ndev, "Failed to set tx power\n");
2484
2485 return ret;
2486 }
2487
2488 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2489 int *dbm)
2490 {
2491 int ret;
2492 struct wilc_priv *priv = wiphy_priv(wiphy);
2493 struct wilc_vif *vif = netdev_priv(priv->dev);
2494
2495 ret = wilc_get_tx_power(vif, (u8 *)dbm);
2496 if (ret)
2497 netdev_err(vif->ndev, "Failed to get tx power\n");
2498
2499 return ret;
2500 }
2501
2502 static struct cfg80211_ops wilc_cfg80211_ops = {
2503 .set_monitor_channel = set_channel,
2504 .scan = scan,
2505 .connect = connect,
2506 .disconnect = disconnect,
2507 .add_key = add_key,
2508 .del_key = del_key,
2509 .get_key = get_key,
2510 .set_default_key = set_default_key,
2511 .add_virtual_intf = add_virtual_intf,
2512 .del_virtual_intf = del_virtual_intf,
2513 .change_virtual_intf = change_virtual_intf,
2514
2515 .start_ap = start_ap,
2516 .change_beacon = change_beacon,
2517 .stop_ap = stop_ap,
2518 .add_station = add_station,
2519 .del_station = del_station,
2520 .change_station = change_station,
2521 .get_station = get_station,
2522 .dump_station = dump_station,
2523 .change_bss = change_bss,
2524 .set_wiphy_params = set_wiphy_params,
2525
2526 .set_pmksa = set_pmksa,
2527 .del_pmksa = del_pmksa,
2528 .flush_pmksa = flush_pmksa,
2529 .remain_on_channel = remain_on_channel,
2530 .cancel_remain_on_channel = cancel_remain_on_channel,
2531 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2532 .mgmt_tx = mgmt_tx,
2533 .mgmt_frame_register = wilc_mgmt_frame_register,
2534 .set_power_mgmt = set_power_mgmt,
2535 .set_cqm_rssi_config = set_cqm_rssi_config,
2536
2537 .suspend = wilc_suspend,
2538 .resume = wilc_resume,
2539 .set_wakeup = wilc_set_wakeup,
2540 .set_tx_power = set_tx_power,
2541 .get_tx_power = get_tx_power,
2542
2543 };
2544
2545 int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2546 {
2547 struct wilc_priv *priv;
2548
2549 priv = wiphy_priv(wiphy);
2550 switch (changed) {
2551 case WILC_WFI_RX_PKT:
2552 {
2553 priv->netstats.rx_packets++;
2554 priv->netstats.rx_bytes += pktlen;
2555 priv->netstats.rx_time = get_jiffies_64();
2556 }
2557 break;
2558
2559 case WILC_WFI_TX_PKT:
2560 {
2561 priv->netstats.tx_packets++;
2562 priv->netstats.tx_bytes += pktlen;
2563 priv->netstats.tx_time = get_jiffies_64();
2564
2565 }
2566 break;
2567
2568 default:
2569 break;
2570 }
2571 return 0;
2572 }
2573
2574 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2575 {
2576 struct wireless_dev *wdev;
2577
2578
2579 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
2580
2581 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2582 if (!wdev)
2583 goto _fail_;
2584
2585 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2586 if (!wdev->wiphy)
2587 goto _fail_mem_;
2588
2589 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2590 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2591 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2592 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2593 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2594
2595 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2596
2597 return wdev;
2598
2599 _fail_mem_:
2600 kfree(wdev);
2601 _fail_:
2602 return NULL;
2603 }
2604
2605 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2606 {
2607 struct wilc_priv *priv;
2608 struct wireless_dev *wdev;
2609 s32 s32Error = 0;
2610
2611 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2612
2613 wdev = WILC_WFI_CfgAlloc();
2614 if (!wdev) {
2615 netdev_err(net, "wiphy new allocate failed\n");
2616 return NULL;
2617 }
2618
2619 priv = wdev_priv(wdev);
2620 sema_init(&(priv->SemHandleUpdateStats), 1);
2621 priv->wdev = wdev;
2622 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2623 #ifdef CONFIG_PM
2624 wdev->wiphy->wowlan = &wowlan_support;
2625 #endif
2626 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2627 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
2628
2629 wdev->wiphy->max_scan_ie_len = 1000;
2630 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2631 wdev->wiphy->cipher_suites = cipher_suites;
2632 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2633 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2634
2635 wdev->wiphy->max_remain_on_channel_duration = 500;
2636 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2637 BIT(NL80211_IFTYPE_P2P_CLIENT);
2638 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2639 wdev->iftype = NL80211_IFTYPE_STATION;
2640
2641
2642
2643 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2644 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2645 wdev->wiphy->interface_modes, wdev->iftype);
2646
2647 set_wiphy_dev(wdev->wiphy, dev);
2648
2649 s32Error = wiphy_register(wdev->wiphy);
2650 if (s32Error)
2651 netdev_err(net, "Cannot register wiphy device\n");
2652 else
2653 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2654
2655 priv->dev = net;
2656 return wdev;
2657 }
2658
2659 int wilc_init_host_int(struct net_device *net)
2660 {
2661 int s32Error = 0;
2662
2663 struct wilc_priv *priv;
2664
2665 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2666 priv = wdev_priv(net->ieee80211_ptr);
2667 if (op_ifcs == 0) {
2668 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2669 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2670 }
2671 op_ifcs++;
2672
2673 priv->gbAutoRateAdjusted = false;
2674
2675 priv->bInP2PlistenState = false;
2676
2677 sema_init(&(priv->hSemScanReq), 1);
2678 s32Error = wilc_init(net, &priv->hif_drv);
2679 if (s32Error)
2680 netdev_err(net, "Error while initializing hostinterface\n");
2681
2682 return s32Error;
2683 }
2684
2685 int wilc_deinit_host_int(struct net_device *net)
2686 {
2687 int s32Error = 0;
2688 struct wilc_vif *vif;
2689 struct wilc_priv *priv;
2690
2691 priv = wdev_priv(net->ieee80211_ptr);
2692 vif = netdev_priv(priv->dev);
2693
2694 priv->gbAutoRateAdjusted = false;
2695
2696 priv->bInP2PlistenState = false;
2697
2698 op_ifcs--;
2699
2700 s32Error = wilc_deinit(vif);
2701
2702 clear_shadow_scan();
2703 if (op_ifcs == 0)
2704 del_timer_sync(&wilc_during_ip_timer);
2705
2706 if (s32Error)
2707 netdev_err(net, "Error while deintializing host interface\n");
2708
2709 return s32Error;
2710 }
2711
2712 void wilc_free_wiphy(struct net_device *net)
2713 {
2714 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2715
2716 if (!net) {
2717 PRINT_D(INIT_DBG, "net_device is NULL\n");
2718 return;
2719 }
2720
2721 if (!net->ieee80211_ptr) {
2722 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2723 return;
2724 }
2725
2726 if (!net->ieee80211_ptr->wiphy) {
2727 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2728 return;
2729 }
2730
2731 wiphy_unregister(net->ieee80211_ptr->wiphy);
2732
2733 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2734 wiphy_free(net->ieee80211_ptr->wiphy);
2735 kfree(net->ieee80211_ptr);
2736 }
This page took 0.145176 seconds and 5 git commands to generate.