staging: wilc1000: clear_shadow_scan: remove unused argument
[deliverable/linux.git] / drivers / staging / wilc1000 / wilc_wfi_cfgoperations.c
1 /*!
2 * @file wilc_wfi_cfgopertaions.c
3 * @brief CFG80211 Function Implementation functionality
4 * @author aabouzaeid
5 * mabubakr
6 * mdaftedar
7 * zsalah
8 * @sa wilc_wfi_cfgopertaions.h top level OS wrapper file
9 * @date 31 Aug 2010
10 * @version 1.0
11 */
12
13 #include "wilc_wfi_cfgoperations.h"
14 #include "host_interface.h"
15 #include <linux/errno.h>
16
17 /* The following macros describe the bitfield map used by the firmware to determine its 11i mode */
18 #define NO_ENCRYPT 0
19 #define ENCRYPT_ENABLED BIT(0)
20 #define WEP BIT(1)
21 #define WEP_EXTENDED BIT(2)
22 #define WPA BIT(3)
23 #define WPA2 BIT(4)
24 #define AES BIT(5)
25 #define TKIP BIT(6)
26
27 /*Public action frame index IDs*/
28 #define FRAME_TYPE_ID 0
29 #define ACTION_CAT_ID 24
30 #define ACTION_SUBTYPE_ID 25
31 #define P2P_PUB_ACTION_SUBTYPE 30
32
33 /*Public action frame Attribute IDs*/
34 #define ACTION_FRAME 0xd0
35 #define GO_INTENT_ATTR_ID 0x04
36 #define CHANLIST_ATTR_ID 0x0b
37 #define OPERCHAN_ATTR_ID 0x11
38 #define PUB_ACTION_ATTR_ID 0x04
39 #define P2PELEM_ATTR_ID 0xdd
40
41 /*Public action subtype values*/
42 #define GO_NEG_REQ 0x00
43 #define GO_NEG_RSP 0x01
44 #define GO_NEG_CONF 0x02
45 #define P2P_INV_REQ 0x03
46 #define P2P_INV_RSP 0x04
47 #define PUBLIC_ACT_VENDORSPEC 0x09
48 #define GAS_INTIAL_REQ 0x0a
49 #define GAS_INTIAL_RSP 0x0b
50
51 #define INVALID_CHANNEL 0
52
53 #define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
54 #define SCAN_RESULT_EXPIRE (40 * HZ)
55
56 static const u32 cipher_suites[] = {
57 WLAN_CIPHER_SUITE_WEP40,
58 WLAN_CIPHER_SUITE_WEP104,
59 WLAN_CIPHER_SUITE_TKIP,
60 WLAN_CIPHER_SUITE_CCMP,
61 WLAN_CIPHER_SUITE_AES_CMAC,
62 };
63
64 static const struct ieee80211_txrx_stypes
65 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
66 [NL80211_IFTYPE_STATION] = {
67 .tx = 0xffff,
68 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
69 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
70 },
71 [NL80211_IFTYPE_AP] = {
72 .tx = 0xffff,
73 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
74 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
75 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
76 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
77 BIT(IEEE80211_STYPE_AUTH >> 4) |
78 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
79 BIT(IEEE80211_STYPE_ACTION >> 4)
80 },
81 [NL80211_IFTYPE_P2P_CLIENT] = {
82 .tx = 0xffff,
83 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
84 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
85 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
86 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
87 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
88 BIT(IEEE80211_STYPE_AUTH >> 4) |
89 BIT(IEEE80211_STYPE_DEAUTH >> 4)
90 }
91 };
92
93 /* Time to stay on the channel */
94 #define WILC_WFI_DWELL_PASSIVE 100
95 #define WILC_WFI_DWELL_ACTIVE 40
96
97 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
98 #define DEFAULT_LINK_SPEED 72
99
100
101 #define IS_MANAGMEMENT 0x100
102 #define IS_MANAGMEMENT_CALLBACK 0x080
103 #define IS_MGMT_STATUS_SUCCES 0x040
104 #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
105
106 extern int wilc_mac_open(struct net_device *ndev);
107 extern int wilc_mac_close(struct net_device *ndev);
108
109 static tstrNetworkInfo last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
110 static u32 last_scanned_cnt;
111 struct timer_list wilc_during_ip_timer;
112 static struct timer_list hAgingTimer;
113 static u8 op_ifcs;
114
115 u8 wilc_initialized = 1;
116
117 #define CHAN2G(_channel, _freq, _flags) { \
118 .band = IEEE80211_BAND_2GHZ, \
119 .center_freq = (_freq), \
120 .hw_value = (_channel), \
121 .flags = (_flags), \
122 .max_antenna_gain = 0, \
123 .max_power = 30, \
124 }
125
126 /*Frequency range for channels*/
127 static struct ieee80211_channel ieee80211_2ghz_channels[] = {
128 CHAN2G(1, 2412, 0),
129 CHAN2G(2, 2417, 0),
130 CHAN2G(3, 2422, 0),
131 CHAN2G(4, 2427, 0),
132 CHAN2G(5, 2432, 0),
133 CHAN2G(6, 2437, 0),
134 CHAN2G(7, 2442, 0),
135 CHAN2G(8, 2447, 0),
136 CHAN2G(9, 2452, 0),
137 CHAN2G(10, 2457, 0),
138 CHAN2G(11, 2462, 0),
139 CHAN2G(12, 2467, 0),
140 CHAN2G(13, 2472, 0),
141 CHAN2G(14, 2484, 0),
142 };
143
144 #define RATETAB_ENT(_rate, _hw_value, _flags) { \
145 .bitrate = (_rate), \
146 .hw_value = (_hw_value), \
147 .flags = (_flags), \
148 }
149
150
151 /* Table 6 in section 3.2.1.1 */
152 static struct ieee80211_rate ieee80211_bitrates[] = {
153 RATETAB_ENT(10, 0, 0),
154 RATETAB_ENT(20, 1, 0),
155 RATETAB_ENT(55, 2, 0),
156 RATETAB_ENT(110, 3, 0),
157 RATETAB_ENT(60, 9, 0),
158 RATETAB_ENT(90, 6, 0),
159 RATETAB_ENT(120, 7, 0),
160 RATETAB_ENT(180, 8, 0),
161 RATETAB_ENT(240, 9, 0),
162 RATETAB_ENT(360, 10, 0),
163 RATETAB_ENT(480, 11, 0),
164 RATETAB_ENT(540, 12, 0),
165 };
166
167 struct p2p_mgmt_data {
168 int size;
169 u8 *buff;
170 };
171
172 static u8 wlan_channel = INVALID_CHANNEL;
173 static u8 curr_channel;
174 static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
175 static u8 p2p_local_random = 0x01;
176 static u8 p2p_recv_random = 0x00;
177 static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
178 static bool wilc_ie;
179
180 static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
181 .channels = ieee80211_2ghz_channels,
182 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
183 .bitrates = ieee80211_bitrates,
184 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
185 };
186
187
188 struct add_key_params {
189 u8 key_idx;
190 bool pairwise;
191 u8 *mac_addr;
192 };
193 static struct add_key_params g_add_gtk_key_params;
194 static struct wilc_wfi_key g_key_gtk_params;
195 static struct add_key_params g_add_ptk_key_params;
196 static struct wilc_wfi_key g_key_ptk_params;
197 static struct wilc_wfi_wep_key g_key_wep_params;
198 static bool g_ptk_keys_saved;
199 static bool g_gtk_keys_saved;
200 static bool g_wep_keys_saved;
201
202 #define AGING_TIME (9 * 1000)
203 #define during_ip_time 15000
204
205 static void clear_shadow_scan(void)
206 {
207 int i;
208
209 if (op_ifcs == 0) {
210 del_timer_sync(&hAgingTimer);
211 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
212
213 for (i = 0; i < last_scanned_cnt; i++) {
214 if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
215 kfree(last_scanned_shadow[i].pu8IEs);
216 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
217 }
218
219 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
220 last_scanned_shadow[i].pJoinParams = NULL;
221 }
222 last_scanned_cnt = 0;
223 }
224
225 }
226
227 static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
228 {
229 u8 i;
230 int rssi_v = 0;
231 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
232
233 for (i = 0; i < num_rssi; i++)
234 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
235
236 rssi_v /= num_rssi;
237 return rssi_v;
238 }
239
240 static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
241 {
242 struct wilc_priv *priv;
243 struct wiphy *wiphy;
244 struct cfg80211_bss *bss = NULL;
245 int i;
246 int rssi = 0;
247
248 priv = (struct wilc_priv *)pUserVoid;
249 wiphy = priv->dev->ieee80211_ptr->wiphy;
250
251 for (i = 0; i < last_scanned_cnt; i++) {
252 tstrNetworkInfo *pstrNetworkInfo;
253
254 pstrNetworkInfo = &last_scanned_shadow[i];
255
256 if ((!pstrNetworkInfo->u8Found) || all) {
257 s32 s32Freq;
258 struct ieee80211_channel *channel;
259
260 if (pstrNetworkInfo != NULL) {
261
262 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
263 channel = ieee80211_get_channel(wiphy, s32Freq);
264
265 rssi = get_rssi_avg(pstrNetworkInfo);
266 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
267 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
268 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
269 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
270 cfg80211_put_bss(wiphy, bss);
271 }
272 }
273
274 }
275 }
276
277 }
278
279 static void reset_shadow_found(void *pUserVoid)
280 {
281 int i;
282
283 for (i = 0; i < last_scanned_cnt; i++)
284 last_scanned_shadow[i].u8Found = 0;
285 }
286
287 static void update_scan_time(void *pUserVoid)
288 {
289 int i;
290
291 for (i = 0; i < last_scanned_cnt; i++)
292 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
293 }
294
295 static void remove_network_from_shadow(unsigned long arg)
296 {
297 unsigned long now = jiffies;
298 int i, j;
299
300
301 for (i = 0; i < last_scanned_cnt; i++) {
302 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
303 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
304
305 kfree(last_scanned_shadow[i].pu8IEs);
306 last_scanned_shadow[i].pu8IEs = NULL;
307
308 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
309
310 for (j = i; (j < last_scanned_cnt - 1); j++)
311 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
312
313 last_scanned_cnt--;
314 }
315 }
316
317 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
318 last_scanned_cnt);
319 if (last_scanned_cnt != 0) {
320 hAgingTimer.data = arg;
321 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
322 } else {
323 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
324 }
325 }
326
327 static void clear_duringIP(unsigned long arg)
328 {
329 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
330 wilc_optaining_ip = false;
331 }
332
333 static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
334 {
335 int state = -1;
336 int i;
337
338 if (last_scanned_cnt == 0) {
339 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
340 hAgingTimer.data = (unsigned long)pUserVoid;
341 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
342 state = -1;
343 } else {
344 /* Linear search for now */
345 for (i = 0; i < last_scanned_cnt; i++) {
346 if (memcmp(last_scanned_shadow[i].au8bssid,
347 pstrNetworkInfo->au8bssid, 6) == 0) {
348 state = i;
349 break;
350 }
351 }
352 }
353 return state;
354 }
355
356 static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
357 {
358 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
359 u32 ap_index = 0;
360 u8 rssi_index = 0;
361
362 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
363 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
364 return;
365 }
366 if (ap_found == -1) {
367 ap_index = last_scanned_cnt;
368 last_scanned_cnt++;
369
370 } else {
371 ap_index = ap_found;
372 }
373 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
374 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
375 if (rssi_index == NUM_RSSI) {
376 rssi_index = 0;
377 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
378 }
379 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
380 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
381 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
382 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
383 memcpy(last_scanned_shadow[ap_index].au8ssid,
384 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
385 memcpy(last_scanned_shadow[ap_index].au8bssid,
386 pstrNetworkInfo->au8bssid, ETH_ALEN);
387 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
388 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
389 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
390 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
391 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
392 if (ap_found != -1)
393 kfree(last_scanned_shadow[ap_index].pu8IEs);
394 last_scanned_shadow[ap_index].pu8IEs =
395 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
396 memcpy(last_scanned_shadow[ap_index].pu8IEs,
397 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
398 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
399 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
400 last_scanned_shadow[ap_index].u8Found = 1;
401 if (ap_found != -1)
402 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
403 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
404 }
405
406
407 /**
408 * @brief CfgScanResult
409 * @details Callback function which returns the scan results found
410 *
411 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
412 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
413 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
414 * void* pUserVoid: Private structure associated with the wireless interface
415 * @return NONE
416 * @author mabubakr
417 * @date
418 * @version 1.0
419 */
420 static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
421 {
422 struct wilc_priv *priv;
423 struct wiphy *wiphy;
424 s32 s32Freq;
425 struct ieee80211_channel *channel;
426 struct cfg80211_bss *bss = NULL;
427
428 priv = (struct wilc_priv *)pUserVoid;
429 if (priv->bCfgScanning) {
430 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
431 wiphy = priv->dev->ieee80211_ptr->wiphy;
432
433 if (!wiphy)
434 return;
435
436 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
437 &&
438 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
439 ||
440 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
441 ) {
442 PRINT_ER("wiphy signal type fial\n");
443 return;
444 }
445
446 if (pstrNetworkInfo != NULL) {
447 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
448 channel = ieee80211_get_channel(wiphy, s32Freq);
449
450 if (!channel)
451 return;
452
453 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
454 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
455 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
456
457 if (pstrNetworkInfo->bNewNetwork) {
458 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
459 /* max_scan_ssids */
460 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
461
462
463 priv->u32RcvdChCount++;
464
465
466
467 if (pJoinParams == NULL) {
468 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
469 }
470 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
471
472 /*P2P peers are sent to WPA supplicant and added to shadow table*/
473
474 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
475 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
476 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
477 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
478 cfg80211_put_bss(wiphy, bss);
479 }
480
481
482 } else {
483 PRINT_ER("Discovered networks exceeded the max limit\n");
484 }
485 } else {
486 u32 i;
487 /* So this network is discovered before, we'll just update its RSSI */
488 for (i = 0; i < priv->u32RcvdChCount; i++) {
489 if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
490 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
491
492 last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi;
493 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
494 break;
495 }
496 }
497 }
498 }
499 } else if (enuScanEvent == SCAN_EVENT_DONE) {
500 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
501 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
502 refresh_scan(priv, 1, false);
503
504 if (priv->u32RcvdChCount > 0)
505 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
506 else
507 PRINT_D(CFG80211_DBG, "No networks found\n");
508
509 down(&(priv->hSemScanReq));
510
511 if (priv->pstrScanReq != NULL) {
512 cfg80211_scan_done(priv->pstrScanReq, false);
513 priv->u32RcvdChCount = 0;
514 priv->bCfgScanning = false;
515 priv->pstrScanReq = NULL;
516 }
517 up(&(priv->hSemScanReq));
518
519 }
520 /*Aborting any scan operation during mac close*/
521 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
522 down(&(priv->hSemScanReq));
523
524 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
525 if (priv->pstrScanReq != NULL) {
526
527 update_scan_time(priv);
528 refresh_scan(priv, 1, false);
529
530 cfg80211_scan_done(priv->pstrScanReq, false);
531 priv->bCfgScanning = false;
532 priv->pstrScanReq = NULL;
533 }
534 up(&(priv->hSemScanReq));
535 }
536 }
537 }
538
539
540 /**
541 * @brief CfgConnectResult
542 * @details
543 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
544 * connection response or disconnection notification.
545 * tstrConnectInfo* pstrConnectInfo: COnnection information.
546 * u8 u8MacStatus: Mac Status from firmware
547 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
548 * void* pUserVoid: Private data associated with wireless interface
549 * @return NONE
550 * @author mabubakr
551 * @date 01 MAR 2012
552 * @version 1.0
553 */
554 int wilc_connecting;
555
556 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
557 tstrConnectInfo *pstrConnectInfo,
558 u8 u8MacStatus,
559 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
560 void *pUserVoid)
561 {
562 struct wilc_priv *priv;
563 struct net_device *dev;
564 struct host_if_drv *pstrWFIDrv;
565 u8 NullBssid[ETH_ALEN] = {0};
566 struct wilc *wl;
567 perInterface_wlan_t *nic;
568
569 wilc_connecting = 0;
570
571 priv = (struct wilc_priv *)pUserVoid;
572 dev = priv->dev;
573 nic = netdev_priv(dev);
574 wl = nic->wilc;
575 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
576
577 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
578 /*Initialization*/
579 u16 u16ConnectStatus;
580
581 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
582
583 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
584
585 if ((u8MacStatus == MAC_DISCONNECTED) &&
586 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
587 /* The case here is that our station was waiting for association response frame and has just received it containing status code
588 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
589 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
590 wilc_wlan_set_bssid(priv->dev, NullBssid);
591 eth_zero_addr(wilc_connected_ssid);
592
593 if (!pstrWFIDrv->p2p_connect)
594 wlan_channel = INVALID_CHANNEL;
595
596 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
597 }
598
599 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
600 bool bNeedScanRefresh = false;
601 u32 i;
602
603 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
604 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
605 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
606
607
608 for (i = 0; i < last_scanned_cnt; i++) {
609 if (memcmp(last_scanned_shadow[i].au8bssid,
610 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
611 unsigned long now = jiffies;
612
613 if (time_after(now,
614 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
615 bNeedScanRefresh = true;
616 }
617
618 break;
619 }
620 }
621
622 if (bNeedScanRefresh) {
623 /*Also, refrsh DIRECT- results if */
624 refresh_scan(priv, 1, true);
625
626 }
627
628 }
629
630
631 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
632
633 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
634
635 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
636 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
637 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
638 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
639 /* be replaced by pstrConnectInfo->u16ConnectStatus */
640 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
641 wilc_optaining_ip = false;
642 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
643 pstrDisconnectNotifInfo->u16reason, priv->dev);
644 p2p_local_random = 0x01;
645 p2p_recv_random = 0x00;
646 wilc_ie = false;
647 eth_zero_addr(priv->au8AssociatedBss);
648 wilc_wlan_set_bssid(priv->dev, NullBssid);
649 eth_zero_addr(wilc_connected_ssid);
650
651 if (!pstrWFIDrv->p2p_connect)
652 wlan_channel = INVALID_CHANNEL;
653 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
654 * virtual interface to station*/
655 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
656 pstrDisconnectNotifInfo->u16reason = 3;
657 }
658 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
659 * to scan again and retry the connection*/
660 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
661 pstrDisconnectNotifInfo->u16reason = 1;
662 }
663 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
664 pstrDisconnectNotifInfo->ie_len, false,
665 GFP_KERNEL);
666
667 }
668
669 }
670
671
672 /**
673 * @brief set_channel
674 * @details Set channel for a given wireless interface. Some devices
675 * may support multi-channel operation (by channel hopping) so cfg80211
676 * doesn't verify much. Note, however, that the passed netdev may be
677 * %NULL as well if the user requested changing the channel for the
678 * device itself, or for a monitor interface.
679 * @param[in]
680 * @return int : Return 0 on Success
681 * @author mdaftedar
682 * @date 01 MAR 2012
683 * @version 1.0
684 */
685 static int set_channel(struct wiphy *wiphy,
686 struct cfg80211_chan_def *chandef)
687 {
688 u32 channelnum = 0;
689 struct wilc_priv *priv;
690 int result = 0;
691
692 priv = wiphy_priv(wiphy);
693
694 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
695 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
696
697 curr_channel = channelnum;
698 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
699
700 if (result != 0)
701 PRINT_ER("Error in setting channel %d\n", channelnum);
702
703 return result;
704 }
705
706 /**
707 * @brief scan
708 * @details Request to do a scan. If returning zero, the scan request is given
709 * the driver, and will be valid until passed to cfg80211_scan_done().
710 * For scan results, call cfg80211_inform_bss(); you can call this outside
711 * the scan/scan_done bracket too.
712 * @param[in]
713 * @return int : Return 0 on Success
714 * @author mabubakr
715 * @date 01 MAR 2012
716 * @version 1.0
717 */
718
719 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
720 {
721 struct wilc_priv *priv;
722 u32 i;
723 s32 s32Error = 0;
724 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
725 struct hidden_network strHiddenNetwork;
726
727 priv = wiphy_priv(wiphy);
728
729 priv->pstrScanReq = request;
730
731 priv->u32RcvdChCount = 0;
732
733 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
734
735
736 reset_shadow_found(priv);
737
738 priv->bCfgScanning = true;
739 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
740 /* max_scan_ssids */
741 for (i = 0; i < request->n_channels; i++) {
742 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
743 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
744 }
745
746 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
747 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
748
749 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
750
751 if (request->n_ssids >= 1) {
752
753
754 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
755 strHiddenNetwork.u8ssidnum = request->n_ssids;
756
757
758 for (i = 0; i < request->n_ssids; i++) {
759
760 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
761 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
762 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
763 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
764 } else {
765 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
766 strHiddenNetwork.u8ssidnum -= 1;
767 }
768 }
769 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
770 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
771 au8ScanChanList, request->n_channels,
772 (const u8 *)request->ie, request->ie_len,
773 CfgScanResult, (void *)priv, &strHiddenNetwork);
774 } else {
775 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
776 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
777 au8ScanChanList, request->n_channels,
778 (const u8 *)request->ie, request->ie_len,
779 CfgScanResult, (void *)priv, NULL);
780 }
781
782 } else {
783 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
784 " channels\n");
785 }
786
787 if (s32Error != 0) {
788 s32Error = -EBUSY;
789 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
790 }
791
792 return s32Error;
793 }
794
795 /**
796 * @brief connect
797 * @details Connect to the ESS with the specified parameters. When connected,
798 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
799 * If the connection fails for some reason, call cfg80211_connect_result()
800 * with the status from the AP.
801 * @param[in]
802 * @return int : Return 0 on Success
803 * @author mabubakr
804 * @date 01 MAR 2012
805 * @version 1.0
806 */
807 static int connect(struct wiphy *wiphy, struct net_device *dev,
808 struct cfg80211_connect_params *sme)
809 {
810 s32 s32Error = 0;
811 u32 i;
812 u8 u8security = NO_ENCRYPT;
813 enum AUTHTYPE tenuAuth_type = ANY;
814 char *pcgroup_encrypt_val = NULL;
815 char *pccipher_group = NULL;
816 char *pcwpa_version = NULL;
817
818 struct wilc_priv *priv;
819 struct host_if_drv *pstrWFIDrv;
820 tstrNetworkInfo *pstrNetworkInfo = NULL;
821
822
823 wilc_connecting = 1;
824 priv = wiphy_priv(wiphy);
825 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
826
827 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
828
829 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
830 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
831 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
832 pstrWFIDrv->p2p_connect = 1;
833 } else {
834 pstrWFIDrv->p2p_connect = 0;
835 }
836 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
837
838 for (i = 0; i < last_scanned_cnt; i++) {
839 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
840 memcmp(last_scanned_shadow[i].au8ssid,
841 sme->ssid,
842 sme->ssid_len) == 0) {
843 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
844 if (sme->bssid == NULL) {
845 /* BSSID is not passed from the user, so decision of matching
846 * is done by SSID only */
847 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
848 break;
849 } else {
850 /* BSSID is also passed from the user, so decision of matching
851 * should consider also this passed BSSID */
852 if (memcmp(last_scanned_shadow[i].au8bssid,
853 sme->bssid,
854 ETH_ALEN) == 0) {
855 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
856 break;
857 }
858 }
859 }
860 }
861
862 if (i < last_scanned_cnt) {
863 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
864
865 pstrNetworkInfo = &last_scanned_shadow[i];
866
867 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
868 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
869 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
870 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
871 } else {
872 s32Error = -ENOENT;
873 if (last_scanned_cnt == 0)
874 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
875 else
876 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
877
878 goto done;
879 }
880
881 priv->WILC_WFI_wep_default = 0;
882 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
883 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
884
885 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
886 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
887
888 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
889
890 if (INFO) {
891 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
892 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
893 }
894
895 if (sme->crypto.cipher_group != NO_ENCRYPT) {
896 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
897 * we will add to it the pairwise cipher suite(s) */
898 pcwpa_version = "Default";
899 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
900 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
901 u8security = ENCRYPT_ENABLED | WEP;
902 pcgroup_encrypt_val = "WEP40";
903 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
904 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
905
906 if (INFO) {
907 for (i = 0; i < sme->key_len; i++)
908 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
909 }
910 priv->WILC_WFI_wep_default = sme->key_idx;
911 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
912 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
913
914 g_key_wep_params.key_len = sme->key_len;
915 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
916 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
917 g_key_wep_params.key_idx = sme->key_idx;
918 g_wep_keys_saved = true;
919
920 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
921 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
922 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
923 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
924 pcgroup_encrypt_val = "WEP104";
925 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
926
927 priv->WILC_WFI_wep_default = sme->key_idx;
928 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
929 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
930
931 g_key_wep_params.key_len = sme->key_len;
932 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
933 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
934 g_key_wep_params.key_idx = sme->key_idx;
935 g_wep_keys_saved = true;
936
937 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
938 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
939 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
940 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
941 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
942 pcgroup_encrypt_val = "WPA2_TKIP";
943 pccipher_group = "TKIP";
944 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
945 /* tenuSecurity_t = WPA2_AES; */
946 u8security = ENCRYPT_ENABLED | WPA2 | AES;
947 pcgroup_encrypt_val = "WPA2_AES";
948 pccipher_group = "AES";
949 }
950 pcwpa_version = "WPA_VERSION_2";
951 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
952 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
953 u8security = ENCRYPT_ENABLED | WPA | TKIP;
954 pcgroup_encrypt_val = "WPA_TKIP";
955 pccipher_group = "TKIP";
956 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
957 /* tenuSecurity_t = WPA_AES; */
958 u8security = ENCRYPT_ENABLED | WPA | AES;
959 pcgroup_encrypt_val = "WPA_AES";
960 pccipher_group = "AES";
961
962 }
963 pcwpa_version = "WPA_VERSION_1";
964
965 } else {
966 s32Error = -ENOTSUPP;
967 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
968
969 goto done;
970 }
971
972 }
973
974 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
975 * add to it the pairwise cipher suite(s) */
976 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
977 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
978 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
979 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
980 u8security = u8security | TKIP;
981 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
982 u8security = u8security | AES;
983 }
984 }
985 }
986
987 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
988
989 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
990 switch (sme->auth_type) {
991 case NL80211_AUTHTYPE_OPEN_SYSTEM:
992 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
993 tenuAuth_type = OPEN_SYSTEM;
994 break;
995
996 case NL80211_AUTHTYPE_SHARED_KEY:
997 tenuAuth_type = SHARED_KEY;
998 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
999 break;
1000
1001 default:
1002 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1003 }
1004
1005
1006 /* ai: key_mgmt: enterprise case */
1007 if (sme->crypto.n_akm_suites) {
1008 switch (sme->crypto.akm_suites[0]) {
1009 case WLAN_AKM_SUITE_8021X:
1010 tenuAuth_type = IEEE8021;
1011 break;
1012
1013 default:
1014 break;
1015 }
1016 }
1017
1018
1019 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1020
1021 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1022 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1023
1024 curr_channel = pstrNetworkInfo->u8channel;
1025
1026 if (!pstrWFIDrv->p2p_connect)
1027 wlan_channel = pstrNetworkInfo->u8channel;
1028
1029 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
1030
1031 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
1032 sme->ssid_len, sme->ie, sme->ie_len,
1033 CfgConnectResult, (void *)priv, u8security,
1034 tenuAuth_type, pstrNetworkInfo->u8channel,
1035 pstrNetworkInfo->pJoinParams);
1036 if (s32Error != 0) {
1037 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
1038 s32Error = -ENOENT;
1039 goto done;
1040 }
1041
1042 done:
1043
1044 return s32Error;
1045 }
1046
1047
1048 /**
1049 * @brief disconnect
1050 * @details Disconnect from the BSS/ESS.
1051 * @param[in]
1052 * @return int : Return 0 on Success
1053 * @author mdaftedar
1054 * @date 01 MAR 2012
1055 * @version 1.0
1056 */
1057 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
1058 {
1059 s32 s32Error = 0;
1060 struct wilc_priv *priv;
1061 struct host_if_drv *pstrWFIDrv;
1062 u8 NullBssid[ETH_ALEN] = {0};
1063
1064 wilc_connecting = 0;
1065 priv = wiphy_priv(wiphy);
1066
1067 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
1068 if (!pstrWFIDrv->p2p_connect)
1069 wlan_channel = INVALID_CHANNEL;
1070 wilc_wlan_set_bssid(priv->dev, NullBssid);
1071
1072 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1073
1074 p2p_local_random = 0x01;
1075 p2p_recv_random = 0x00;
1076 wilc_ie = false;
1077 pstrWFIDrv->p2p_timeout = 0;
1078
1079 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
1080 if (s32Error != 0) {
1081 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1082 s32Error = -EINVAL;
1083 }
1084
1085 return s32Error;
1086 }
1087
1088 /**
1089 * @brief add_key
1090 * @details Add a key with the given parameters. @mac_addr will be %NULL
1091 * when adding a group key.
1092 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1093 * @return int : Return 0 on Success
1094 * @author mdaftedar
1095 * @date 01 MAR 2012
1096 * @version 1.0
1097 */
1098 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1099 bool pairwise,
1100 const u8 *mac_addr, struct key_params *params)
1101
1102 {
1103 s32 s32Error = 0, KeyLen = params->key_len;
1104 u32 i;
1105 struct wilc_priv *priv;
1106 const u8 *pu8RxMic = NULL;
1107 const u8 *pu8TxMic = NULL;
1108 u8 u8mode = NO_ENCRYPT;
1109 u8 u8gmode = NO_ENCRYPT;
1110 u8 u8pmode = NO_ENCRYPT;
1111 enum AUTHTYPE tenuAuth_type = ANY;
1112 struct wilc *wl;
1113 perInterface_wlan_t *nic;
1114
1115 priv = wiphy_priv(wiphy);
1116 nic = netdev_priv(netdev);
1117 wl = nic->wilc;
1118
1119 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1120
1121 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
1122
1123 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1124 params->key[1],
1125 params->key[2]);
1126
1127
1128 switch (params->cipher) {
1129 case WLAN_CIPHER_SUITE_WEP40:
1130 case WLAN_CIPHER_SUITE_WEP104:
1131 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1132
1133 priv->WILC_WFI_wep_default = key_index;
1134 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
1135 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
1136
1137 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1138 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1139
1140 for (i = 0; i < params->key_len; i++)
1141 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1142
1143 tenuAuth_type = OPEN_SYSTEM;
1144
1145 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1146 u8mode = ENCRYPT_ENABLED | WEP;
1147 else
1148 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1149
1150 wilc_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
1151 break;
1152 }
1153 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
1154 priv->WILC_WFI_wep_default = key_index;
1155 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
1156 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
1157
1158 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1159 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1160 if (INFO) {
1161 for (i = 0; i < params->key_len; i++)
1162 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1163 }
1164 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
1165 }
1166
1167 break;
1168
1169 case WLAN_CIPHER_SUITE_TKIP:
1170 case WLAN_CIPHER_SUITE_CCMP:
1171 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1172
1173 if (priv->wilc_gtk[key_index] == NULL) {
1174 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
1175 priv->wilc_gtk[key_index]->key = NULL;
1176 priv->wilc_gtk[key_index]->seq = NULL;
1177
1178 }
1179 if (priv->wilc_ptk[key_index] == NULL) {
1180 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
1181 priv->wilc_ptk[key_index]->key = NULL;
1182 priv->wilc_ptk[key_index]->seq = NULL;
1183 }
1184
1185
1186
1187 if (!pairwise) {
1188 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1189 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1190 else
1191 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1192
1193 priv->wilc_groupkey = u8gmode;
1194
1195 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1196
1197 pu8TxMic = params->key + 24;
1198 pu8RxMic = params->key + 16;
1199 KeyLen = params->key_len - 16;
1200 }
1201 /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
1202 kfree(priv->wilc_gtk[key_index]->key);
1203
1204 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
1205 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
1206
1207 /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
1208 kfree(priv->wilc_gtk[key_index]->seq);
1209
1210 if ((params->seq_len) > 0) {
1211 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
1212 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
1213 }
1214
1215 priv->wilc_gtk[key_index]->cipher = params->cipher;
1216 priv->wilc_gtk[key_index]->key_len = params->key_len;
1217 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1218
1219 if (INFO) {
1220 for (i = 0; i < params->key_len; i++)
1221 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1222 for (i = 0; i < params->seq_len; i++)
1223 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1224 }
1225
1226
1227 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
1228 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1229
1230 } else {
1231 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]);
1232
1233 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1234 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1235 else
1236 u8pmode = priv->wilc_groupkey | AES;
1237
1238
1239 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1240
1241 pu8TxMic = params->key + 24;
1242 pu8RxMic = params->key + 16;
1243 KeyLen = params->key_len - 16;
1244 }
1245
1246 kfree(priv->wilc_ptk[key_index]->key);
1247
1248 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
1249
1250 kfree(priv->wilc_ptk[key_index]->seq);
1251
1252 if ((params->seq_len) > 0)
1253 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
1254
1255 if (INFO) {
1256 for (i = 0; i < params->key_len; i++)
1257 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1258
1259 for (i = 0; i < params->seq_len; i++)
1260 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1261 }
1262
1263 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
1264
1265 if ((params->seq_len) > 0)
1266 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
1267
1268 priv->wilc_ptk[key_index]->cipher = params->cipher;
1269 priv->wilc_ptk[key_index]->key_len = params->key_len;
1270 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1271
1272 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
1273 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1274 }
1275 break;
1276 }
1277
1278 {
1279 u8mode = 0;
1280 if (!pairwise) {
1281 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1282 /* swap the tx mic by rx mic */
1283 pu8RxMic = params->key + 24;
1284 pu8TxMic = params->key + 16;
1285 KeyLen = params->key_len - 16;
1286 }
1287
1288 /*save keys only on interface 0 (wifi interface)*/
1289 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
1290 g_add_gtk_key_params.key_idx = key_index;
1291 g_add_gtk_key_params.pairwise = pairwise;
1292 if (!mac_addr) {
1293 g_add_gtk_key_params.mac_addr = NULL;
1294 } else {
1295 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1296 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1297 }
1298 g_key_gtk_params.key_len = params->key_len;
1299 g_key_gtk_params.seq_len = params->seq_len;
1300 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1301 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1302 if (params->seq_len > 0) {
1303 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1304 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1305 }
1306 g_key_gtk_params.cipher = params->cipher;
1307
1308 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1309 g_key_gtk_params.key[1],
1310 g_key_gtk_params.key[2]);
1311 g_gtk_keys_saved = true;
1312 }
1313
1314 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
1315 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
1316 } else {
1317 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1318 /* swap the tx mic by rx mic */
1319 pu8RxMic = params->key + 24;
1320 pu8TxMic = params->key + 16;
1321 KeyLen = params->key_len - 16;
1322 }
1323
1324 /*save keys only on interface 0 (wifi interface)*/
1325 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
1326 g_add_ptk_key_params.key_idx = key_index;
1327 g_add_ptk_key_params.pairwise = pairwise;
1328 if (!mac_addr) {
1329 g_add_ptk_key_params.mac_addr = NULL;
1330 } else {
1331 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1332 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1333 }
1334 g_key_ptk_params.key_len = params->key_len;
1335 g_key_ptk_params.seq_len = params->seq_len;
1336 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1337 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1338 if (params->seq_len > 0) {
1339 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1340 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1341 }
1342 g_key_ptk_params.cipher = params->cipher;
1343
1344 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1345 g_key_ptk_params.key[1],
1346 g_key_ptk_params.key[2]);
1347 g_ptk_keys_saved = true;
1348 }
1349
1350 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
1351 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1352 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1353 if (INFO) {
1354 for (i = 0; i < params->key_len; i++)
1355 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1356 }
1357 }
1358 }
1359 break;
1360
1361 default:
1362 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1363 s32Error = -ENOTSUPP;
1364
1365 }
1366
1367 return s32Error;
1368 }
1369
1370 /**
1371 * @brief del_key
1372 * @details Remove a key given the @mac_addr (%NULL for a group key)
1373 * and @key_index, return -ENOENT if the key doesn't exist.
1374 * @param[in]
1375 * @return int : Return 0 on Success
1376 * @author mdaftedar
1377 * @date 01 MAR 2012
1378 * @version 1.0
1379 */
1380 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1381 u8 key_index,
1382 bool pairwise,
1383 const u8 *mac_addr)
1384 {
1385 struct wilc_priv *priv;
1386 struct wilc *wl;
1387 perInterface_wlan_t *nic;
1388
1389 priv = wiphy_priv(wiphy);
1390 nic = netdev_priv(netdev);
1391 wl = nic->wilc;
1392
1393 /*delete saved keys, if any*/
1394 if (netdev == wl->vif[0].ndev) {
1395 g_ptk_keys_saved = false;
1396 g_gtk_keys_saved = false;
1397 g_wep_keys_saved = false;
1398
1399 /*Delete saved WEP keys params, if any*/
1400 kfree(g_key_wep_params.key);
1401 g_key_wep_params.key = NULL;
1402
1403 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1404
1405 if ((priv->wilc_gtk[key_index]) != NULL) {
1406
1407 kfree(priv->wilc_gtk[key_index]->key);
1408 priv->wilc_gtk[key_index]->key = NULL;
1409 kfree(priv->wilc_gtk[key_index]->seq);
1410 priv->wilc_gtk[key_index]->seq = NULL;
1411
1412 kfree(priv->wilc_gtk[key_index]);
1413 priv->wilc_gtk[key_index] = NULL;
1414
1415 }
1416
1417 if ((priv->wilc_ptk[key_index]) != NULL) {
1418
1419 kfree(priv->wilc_ptk[key_index]->key);
1420 priv->wilc_ptk[key_index]->key = NULL;
1421 kfree(priv->wilc_ptk[key_index]->seq);
1422 priv->wilc_ptk[key_index]->seq = NULL;
1423 kfree(priv->wilc_ptk[key_index]);
1424 priv->wilc_ptk[key_index] = NULL;
1425 }
1426
1427 /*Delete saved PTK and GTK keys params, if any*/
1428 kfree(g_key_ptk_params.key);
1429 g_key_ptk_params.key = NULL;
1430 kfree(g_key_ptk_params.seq);
1431 g_key_ptk_params.seq = NULL;
1432
1433 kfree(g_key_gtk_params.key);
1434 g_key_gtk_params.key = NULL;
1435 kfree(g_key_gtk_params.seq);
1436 g_key_gtk_params.seq = NULL;
1437
1438 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
1439 wilc_set_machw_change_vir_if(netdev, false);
1440 }
1441
1442 if (key_index >= 0 && key_index <= 3) {
1443 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
1444 priv->WILC_WFI_wep_key_len[key_index] = 0;
1445
1446 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
1447 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
1448 } else {
1449 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
1450 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
1451 }
1452
1453 return 0;
1454 }
1455
1456 /**
1457 * @brief get_key
1458 * @details Get information about the key with the given parameters.
1459 * @mac_addr will be %NULL when requesting information for a group
1460 * key. All pointers given to the @callback function need not be valid
1461 * after it returns. This function should return an error if it is
1462 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1463 * @param[in]
1464 * @return int : Return 0 on Success
1465 * @author mdaftedar
1466 * @date 01 MAR 2012
1467 * @version 1.0
1468 */
1469 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1470 bool pairwise,
1471 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1472 {
1473 struct wilc_priv *priv;
1474 struct key_params key_params;
1475 u32 i;
1476
1477 priv = wiphy_priv(wiphy);
1478
1479
1480 if (!pairwise) {
1481 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1482
1483 key_params.key = priv->wilc_gtk[key_index]->key;
1484 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1485 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1486 key_params.seq = priv->wilc_gtk[key_index]->seq;
1487 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1488 if (INFO) {
1489 for (i = 0; i < key_params.key_len; i++)
1490 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1491 }
1492 } else {
1493 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1494
1495 key_params.key = priv->wilc_ptk[key_index]->key;
1496 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1497 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1498 key_params.seq = priv->wilc_ptk[key_index]->seq;
1499 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1500 }
1501
1502 callback(cookie, &key_params);
1503
1504 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
1505 }
1506
1507 /**
1508 * @brief set_default_key
1509 * @details Set the default management frame key on an interface
1510 * @param[in]
1511 * @return int : Return 0 on Success.
1512 * @author mdaftedar
1513 * @date 01 MAR 2012
1514 * @version 1.0
1515 */
1516 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1517 bool unicast, bool multicast)
1518 {
1519 struct wilc_priv *priv;
1520
1521
1522 priv = wiphy_priv(wiphy);
1523
1524 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
1525
1526 if (key_index != priv->WILC_WFI_wep_default) {
1527
1528 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
1529 }
1530
1531 return 0;
1532 }
1533
1534 /**
1535 * @brief get_station
1536 * @details Get station information for the station identified by @mac
1537 * @param[in] NONE
1538 * @return int : Return 0 on Success.
1539 * @author mdaftedar
1540 * @date 01 MAR 2012
1541 * @version 1.0
1542 */
1543
1544 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1545 const u8 *mac, struct station_info *sinfo)
1546 {
1547 struct wilc_priv *priv;
1548 perInterface_wlan_t *nic;
1549 u32 i = 0;
1550 u32 associatedsta = 0;
1551 u32 inactive_time = 0;
1552 priv = wiphy_priv(wiphy);
1553 nic = netdev_priv(dev);
1554
1555 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1556 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1557
1558 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1559
1560 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1561
1562 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1563 associatedsta = i;
1564 break;
1565 }
1566
1567 }
1568
1569 if (associatedsta == -1) {
1570 PRINT_ER("Station required is not associated\n");
1571 return -ENOENT;
1572 }
1573
1574 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1575
1576 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
1577 sinfo->inactive_time = 1000 * inactive_time;
1578 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1579
1580 }
1581
1582 if (nic->iftype == STATION_MODE) {
1583 struct rf_info strStatistics;
1584
1585 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
1586
1587 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1588 BIT(NL80211_STA_INFO_RX_PACKETS) |
1589 BIT(NL80211_STA_INFO_TX_PACKETS) |
1590 BIT(NL80211_STA_INFO_TX_FAILED) |
1591 BIT(NL80211_STA_INFO_TX_BITRATE);
1592
1593 sinfo->signal = strStatistics.rssi;
1594 sinfo->rx_packets = strStatistics.rx_cnt;
1595 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1596 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1597 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1598
1599 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1600 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1601 wilc_enable_tcp_ack_filter(true);
1602 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1603 wilc_enable_tcp_ack_filter(false);
1604
1605 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1606 sinfo->tx_failed, sinfo->txrate.legacy);
1607 }
1608 return 0;
1609 }
1610
1611
1612 /**
1613 * @brief change_bss
1614 * @details Modify parameters for a given BSS.
1615 * @param[in]
1616 * -use_cts_prot: Whether to use CTS protection
1617 * (0 = no, 1 = yes, -1 = do not change)
1618 * -use_short_preamble: Whether the use of short preambles is allowed
1619 * (0 = no, 1 = yes, -1 = do not change)
1620 * -use_short_slot_time: Whether the use of short slot time is allowed
1621 * (0 = no, 1 = yes, -1 = do not change)
1622 * -basic_rates: basic rates in IEEE 802.11 format
1623 * (or NULL for no change)
1624 * -basic_rates_len: number of basic rates
1625 * -ap_isolate: do not forward packets between connected stations
1626 * -ht_opmode: HT Operation mode
1627 * (u16 = opmode, -1 = do not change)
1628 * @return int : Return 0 on Success.
1629 * @author mdaftedar
1630 * @date 01 MAR 2012
1631 * @version 1.0
1632 */
1633 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1634 struct bss_parameters *params)
1635 {
1636 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1637 return 0;
1638 }
1639
1640 /**
1641 * @brief set_wiphy_params
1642 * @details Notify that wiphy parameters have changed;
1643 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1644 * have changed.
1645 * @return int : Return 0 on Success
1646 * @author mdaftedar
1647 * @date 01 MAR 2012
1648 * @version 1.0
1649 */
1650 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1651 {
1652 s32 s32Error = 0;
1653 struct cfg_param_val pstrCfgParamVal;
1654 struct wilc_priv *priv;
1655
1656 priv = wiphy_priv(wiphy);
1657
1658 pstrCfgParamVal.flag = 0;
1659 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
1660
1661 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1662 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1663 priv->dev->ieee80211_ptr->wiphy->retry_short);
1664 pstrCfgParamVal.flag |= RETRY_SHORT;
1665 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1666 }
1667 if (changed & WIPHY_PARAM_RETRY_LONG) {
1668
1669 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
1670 pstrCfgParamVal.flag |= RETRY_LONG;
1671 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1672
1673 }
1674 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1675 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
1676 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1677 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1678
1679 }
1680
1681 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1682 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1683
1684 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1685 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1686
1687 }
1688
1689 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
1690 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
1691 if (s32Error)
1692 PRINT_ER("Error in setting WIPHY PARAMS\n");
1693
1694
1695 return s32Error;
1696 }
1697
1698 /**
1699 * @brief set_pmksa
1700 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1701 * devices running firmwares capable of generating the (re) association
1702 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1703 * @param[in]
1704 * @return int : Return 0 on Success
1705 * @author mdaftedar
1706 * @date 01 MAR 2012
1707 * @version 1.0
1708 */
1709 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1710 struct cfg80211_pmksa *pmksa)
1711 {
1712 u32 i;
1713 s32 s32Error = 0;
1714 u8 flag = 0;
1715
1716 struct wilc_priv *priv = wiphy_priv(wiphy);
1717
1718 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1719
1720
1721 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1722 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1723 ETH_ALEN)) {
1724 /*If bssid already exists and pmkid value needs to reset*/
1725 flag = PMKID_FOUND;
1726 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1727 break;
1728 }
1729 }
1730 if (i < WILC_MAX_NUM_PMKIDS) {
1731 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
1732 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1733 ETH_ALEN);
1734 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1735 PMKID_LEN);
1736 if (!(flag == PMKID_FOUND))
1737 priv->pmkid_list.numpmkid++;
1738 } else {
1739 PRINT_ER("Invalid PMKID index\n");
1740 s32Error = -EINVAL;
1741 }
1742
1743 if (!s32Error) {
1744 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
1745 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
1746 }
1747 return s32Error;
1748 }
1749
1750 /**
1751 * @brief del_pmksa
1752 * @details Delete a cached PMKID.
1753 * @param[in]
1754 * @return int : Return 0 on Success
1755 * @author mdaftedar
1756 * @date 01 MAR 2012
1757 * @version 1.0
1758 */
1759 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1760 struct cfg80211_pmksa *pmksa)
1761 {
1762
1763 u32 i;
1764 s32 s32Error = 0;
1765
1766 struct wilc_priv *priv = wiphy_priv(wiphy);
1767
1768 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1769
1770 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1771 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1772 ETH_ALEN)) {
1773 /*If bssid is found, reset the values*/
1774 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
1775 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1776 break;
1777 }
1778 }
1779
1780 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1781 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1782 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1783 priv->pmkid_list.pmkidlist[i + 1].bssid,
1784 ETH_ALEN);
1785 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1786 priv->pmkid_list.pmkidlist[i].pmkid,
1787 PMKID_LEN);
1788 }
1789 priv->pmkid_list.numpmkid--;
1790 } else {
1791 s32Error = -EINVAL;
1792 }
1793
1794 return s32Error;
1795 }
1796
1797 /**
1798 * @brief flush_pmksa
1799 * @details Flush all cached PMKIDs.
1800 * @param[in]
1801 * @return int : Return 0 on Success
1802 * @author mdaftedar
1803 * @date 01 MAR 2012
1804 * @version 1.0
1805 */
1806 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1807 {
1808 struct wilc_priv *priv = wiphy_priv(wiphy);
1809
1810 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1811
1812 /*Get cashed Pmkids and set all with zeros*/
1813 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1814
1815 return 0;
1816 }
1817
1818
1819 /**
1820 * @brief WILC_WFI_CfgParseRxAction
1821 * @details Function parses the received frames and modifies the following attributes:
1822 * -GO Intent
1823 * -Channel list
1824 * -Operating Channel
1825 *
1826 * @param[in] u8* Buffer, u32 length
1827 * @return NONE.
1828 * @author mdaftedar
1829 * @date 12 DEC 2012
1830 * @version
1831 */
1832
1833 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1834 {
1835 u32 index = 0;
1836 u32 i = 0, j = 0;
1837
1838 u8 op_channel_attr_index = 0;
1839 u8 channel_list_attr_index = 0;
1840
1841 while (index < len) {
1842 if (buf[index] == GO_INTENT_ATTR_ID) {
1843 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
1844 }
1845
1846 if (buf[index] == CHANLIST_ATTR_ID)
1847 channel_list_attr_index = index;
1848 else if (buf[index] == OPERCHAN_ATTR_ID)
1849 op_channel_attr_index = index;
1850 index += buf[index + 1] + 3; /* ID,Length byte */
1851 }
1852 if (wlan_channel != INVALID_CHANNEL) {
1853 /*Modify channel list attribute*/
1854 if (channel_list_attr_index) {
1855 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1856 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1857 if (buf[i] == 0x51) {
1858 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1859 buf[j] = wlan_channel;
1860 }
1861 break;
1862 }
1863 }
1864 }
1865 /*Modify operating channel attribute*/
1866 if (op_channel_attr_index) {
1867 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1868 buf[op_channel_attr_index + 6] = 0x51;
1869 buf[op_channel_attr_index + 7] = wlan_channel;
1870 }
1871 }
1872 }
1873
1874 /**
1875 * @brief WILC_WFI_CfgParseTxAction
1876 * @details Function parses the transmitted action frames and modifies the
1877 * GO Intent attribute
1878 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1879 * @return NONE.
1880 * @author mdaftedar
1881 * @date 12 DEC 2012
1882 * @version
1883 */
1884 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1885 {
1886 u32 index = 0;
1887 u32 i = 0, j = 0;
1888
1889 u8 op_channel_attr_index = 0;
1890 u8 channel_list_attr_index = 0;
1891
1892 while (index < len) {
1893 if (buf[index] == GO_INTENT_ATTR_ID) {
1894 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
1895
1896 break;
1897 }
1898
1899 if (buf[index] == CHANLIST_ATTR_ID)
1900 channel_list_attr_index = index;
1901 else if (buf[index] == OPERCHAN_ATTR_ID)
1902 op_channel_attr_index = index;
1903 index += buf[index + 1] + 3; /* ID,Length byte */
1904 }
1905 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1906 /*Modify channel list attribute*/
1907 if (channel_list_attr_index) {
1908 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1909 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1910 if (buf[i] == 0x51) {
1911 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1912 buf[j] = wlan_channel;
1913 }
1914 break;
1915 }
1916 }
1917 }
1918 /*Modify operating channel attribute*/
1919 if (op_channel_attr_index) {
1920 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1921 buf[op_channel_attr_index + 6] = 0x51;
1922 buf[op_channel_attr_index + 7] = wlan_channel;
1923 }
1924 }
1925 }
1926
1927 /* @brief WILC_WFI_p2p_rx
1928 * @details
1929 * @param[in]
1930 *
1931 * @return None
1932 * @author Mai Daftedar
1933 * @date 2 JUN 2013
1934 * @version 1.0
1935 */
1936
1937 void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
1938 {
1939
1940 struct wilc_priv *priv;
1941 u32 header, pkt_offset;
1942 struct host_if_drv *pstrWFIDrv;
1943 u32 i = 0;
1944 s32 s32Freq;
1945
1946 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1947 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
1948
1949 /* Get WILC header */
1950 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1951
1952 /* The packet offset field conain info about what type of managment frame */
1953 /* we are dealing with and ack status */
1954 pkt_offset = GET_PKT_OFFSET(header);
1955
1956 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1957 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1958 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
1959 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1960 return;
1961 } else {
1962 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1963 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],
1964 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
1965 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1966 } else {
1967 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],
1968 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
1969 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1970 }
1971 return;
1972 }
1973 } else {
1974
1975 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1976
1977 /*Upper layer is informed that the frame is received on this freq*/
1978 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
1979
1980 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1981 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1982
1983 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1984 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1985 return;
1986 }
1987 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1988
1989 switch (buff[ACTION_SUBTYPE_ID]) {
1990 case GAS_INTIAL_REQ:
1991 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1992 break;
1993
1994 case GAS_INTIAL_RSP:
1995 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1996 break;
1997
1998 case PUBLIC_ACT_VENDORSPEC:
1999 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
2000 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2001 if (!wilc_ie) {
2002 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
2003 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
2004 p2p_recv_random = buff[i + 6];
2005 wilc_ie = true;
2006 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
2007 break;
2008 }
2009 }
2010 }
2011 }
2012 if (p2p_local_random > p2p_recv_random) {
2013 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2014 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2015 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
2016 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
2017 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2018 break;
2019 }
2020 }
2021 }
2022 } else {
2023 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
2024 }
2025 }
2026
2027
2028 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
2029 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2030 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
2031 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
2032 return;
2033 }
2034 break;
2035
2036 default:
2037 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2038 break;
2039 }
2040 }
2041 }
2042
2043 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
2044 }
2045 }
2046
2047 /**
2048 * @brief WILC_WFI_mgmt_tx_complete
2049 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2050 * @param[in] priv
2051 * transmitting status
2052 * @return None
2053 * @author Amr Abdelmoghny
2054 * @date 20 MAY 2013
2055 * @version 1.0
2056 */
2057 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2058 {
2059 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2060
2061
2062 kfree(pv_data->buff);
2063 kfree(pv_data);
2064 }
2065
2066 /**
2067 * @brief WILC_WFI_RemainOnChannelReady
2068 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2069 * @param
2070 * @return none
2071 * @author Amr abdelmoghny
2072 * @date 9 JUNE 2013
2073 * @version
2074 */
2075
2076 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2077 {
2078 struct wilc_priv *priv;
2079
2080 priv = (struct wilc_priv *)pUserVoid;
2081
2082 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
2083
2084 priv->bInP2PlistenState = true;
2085
2086 cfg80211_ready_on_channel(priv->wdev,
2087 priv->strRemainOnChanParams.u64ListenCookie,
2088 priv->strRemainOnChanParams.pstrListenChan,
2089 priv->strRemainOnChanParams.u32ListenDuration,
2090 GFP_KERNEL);
2091 }
2092
2093 /**
2094 * @brief WILC_WFI_RemainOnChannelExpired
2095 * @details Callback function, called on expiration of remain-on-channel duration
2096 * @param
2097 * @return none
2098 * @author Amr abdelmoghny
2099 * @date 15 MAY 2013
2100 * @version
2101 */
2102
2103 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
2104 {
2105 struct wilc_priv *priv;
2106
2107 priv = (struct wilc_priv *)pUserVoid;
2108
2109 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
2110 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
2111
2112 priv->bInP2PlistenState = false;
2113
2114 /*Inform wpas of remain-on-channel expiration*/
2115 cfg80211_remain_on_channel_expired(priv->wdev,
2116 priv->strRemainOnChanParams.u64ListenCookie,
2117 priv->strRemainOnChanParams.pstrListenChan,
2118 GFP_KERNEL);
2119 } else {
2120 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2121 , priv->strRemainOnChanParams.u32ListenSessionID);
2122 }
2123 }
2124
2125
2126 /**
2127 * @brief remain_on_channel
2128 * @details Request the driver to remain awake on the specified
2129 * channel for the specified duration to complete an off-channel
2130 * operation (e.g., public action frame exchange). When the driver is
2131 * ready on the requested channel, it must indicate this with an event
2132 * notification by calling cfg80211_ready_on_channel().
2133 * @param[in]
2134 * @return int : Return 0 on Success
2135 * @author mdaftedar
2136 * @date 01 MAR 2012
2137 * @version 1.0
2138 */
2139 static int remain_on_channel(struct wiphy *wiphy,
2140 struct wireless_dev *wdev,
2141 struct ieee80211_channel *chan,
2142 unsigned int duration, u64 *cookie)
2143 {
2144 s32 s32Error = 0;
2145 struct wilc_priv *priv;
2146
2147 priv = wiphy_priv(wiphy);
2148
2149 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2150
2151
2152 if (wdev->iftype == NL80211_IFTYPE_AP) {
2153 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2154 return s32Error;
2155 }
2156
2157 curr_channel = chan->hw_value;
2158
2159 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2160 priv->strRemainOnChanParams.pstrListenChan = chan;
2161 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
2162 priv->strRemainOnChanParams.u32ListenDuration = duration;
2163 priv->strRemainOnChanParams.u32ListenSessionID++;
2164
2165 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
2166 , priv->strRemainOnChanParams.u32ListenSessionID
2167 , duration
2168 , chan->hw_value
2169 , WILC_WFI_RemainOnChannelExpired
2170 , WILC_WFI_RemainOnChannelReady
2171 , (void *)priv);
2172
2173 return s32Error;
2174 }
2175
2176 /**
2177 * @brief cancel_remain_on_channel
2178 * @details Cancel an on-going remain-on-channel operation.
2179 * This allows the operation to be terminated prior to timeout based on
2180 * the duration value.
2181 * @param[in] struct wiphy *wiphy,
2182 * @param[in] struct net_device *dev
2183 * @param[in] u64 cookie,
2184 * @return int : Return 0 on Success
2185 * @author mdaftedar
2186 * @date 01 MAR 2012
2187 * @version 1.0
2188 */
2189 static int cancel_remain_on_channel(struct wiphy *wiphy,
2190 struct wireless_dev *wdev,
2191 u64 cookie)
2192 {
2193 s32 s32Error = 0;
2194 struct wilc_priv *priv;
2195
2196 priv = wiphy_priv(wiphy);
2197
2198 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2199
2200 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
2201 return s32Error;
2202 }
2203 /**
2204 * @brief WILC_WFI_mgmt_tx_frame
2205 * @details
2206 *
2207 * @param[in]
2208 * @return NONE.
2209 * @author mdaftedar
2210 * @date 01 JUL 2012
2211 * @version
2212 */
2213 static int mgmt_tx(struct wiphy *wiphy,
2214 struct wireless_dev *wdev,
2215 struct cfg80211_mgmt_tx_params *params,
2216 u64 *cookie)
2217 {
2218 struct ieee80211_channel *chan = params->chan;
2219 unsigned int wait = params->wait;
2220 const u8 *buf = params->buf;
2221 size_t len = params->len;
2222 const struct ieee80211_mgmt *mgmt;
2223 struct p2p_mgmt_data *mgmt_tx;
2224 struct wilc_priv *priv;
2225 struct host_if_drv *pstrWFIDrv;
2226 u32 i;
2227 perInterface_wlan_t *nic;
2228 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
2229
2230 nic = netdev_priv(wdev->netdev);
2231 priv = wiphy_priv(wiphy);
2232 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
2233
2234 *cookie = (unsigned long)buf;
2235 priv->u64tx_cookie = *cookie;
2236 mgmt = (const struct ieee80211_mgmt *) buf;
2237
2238 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2239
2240 /*mgmt frame allocation*/
2241 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
2242 if (mgmt_tx == NULL) {
2243 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
2244 return -EFAULT;
2245 }
2246 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
2247 if (mgmt_tx->buff == NULL) {
2248 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
2249 kfree(mgmt_tx);
2250 return -EFAULT;
2251 }
2252 memcpy(mgmt_tx->buff, buf, len);
2253 mgmt_tx->size = len;
2254
2255
2256 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2257 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2258 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
2259 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
2260 /*Save the current channel after we tune to it*/
2261 curr_channel = chan->hw_value;
2262 } else if (ieee80211_is_action(mgmt->frame_control)) {
2263 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
2264
2265
2266 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2267 /*Only set the channel, if not a negotiation confirmation frame
2268 * (If Negotiation confirmation frame, force it
2269 * to be transmitted on the same negotiation channel)*/
2270
2271 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2272 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2273 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
2274 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
2275 /*Save the current channel after we tune to it*/
2276 curr_channel = chan->hw_value;
2277 }
2278 switch (buf[ACTION_SUBTYPE_ID]) {
2279 case GAS_INTIAL_REQ:
2280 {
2281 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2282 break;
2283 }
2284
2285 case GAS_INTIAL_RSP:
2286 {
2287 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2288 break;
2289 }
2290
2291 case PUBLIC_ACT_VENDORSPEC:
2292 {
2293 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
2294 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2295 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2296 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
2297 get_random_bytes(&p2p_local_random, 1);
2298 p2p_local_random++;
2299 }
2300 }
2301
2302 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2303 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2304 if (p2p_local_random > p2p_recv_random) {
2305 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
2306
2307 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2308 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
2309 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
2310 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
2311 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
2312
2313 /*If using supplicant go intent, no need at all*/
2314 /*to parse transmitted negotiation frames*/
2315 else
2316 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
2317 break;
2318 }
2319 }
2320
2321 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
2322 /*
2323 * Adding WILC information element to allow two WILC devices to
2324 * identify each other and connect
2325 */
2326 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
2327 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
2328 mgmt_tx->size = buf_len;
2329 }
2330 } else {
2331 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
2332 }
2333 }
2334
2335 } else {
2336 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2337 }
2338
2339 break;
2340 }
2341
2342 default:
2343 {
2344 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2345 break;
2346 }
2347 }
2348
2349 }
2350
2351 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
2352 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
2353
2354 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2355 jiffies, pstrWFIDrv->p2p_timeout);
2356 }
2357
2358 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2359 mgmt_tx->buff, mgmt_tx->size,
2360 WILC_WFI_mgmt_tx_complete);
2361 } else {
2362 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2363 }
2364 return 0;
2365 }
2366
2367 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2368 struct wireless_dev *wdev,
2369 u64 cookie)
2370 {
2371 struct wilc_priv *priv;
2372 struct host_if_drv *pstrWFIDrv;
2373
2374 priv = wiphy_priv(wiphy);
2375 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
2376
2377
2378 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
2379 pstrWFIDrv->p2p_timeout = jiffies;
2380
2381 if (!priv->bInP2PlistenState) {
2382 cfg80211_remain_on_channel_expired(priv->wdev,
2383 priv->strRemainOnChanParams.u64ListenCookie,
2384 priv->strRemainOnChanParams.pstrListenChan,
2385 GFP_KERNEL);
2386 }
2387
2388 return 0;
2389 }
2390
2391 /**
2392 * @brief wilc_mgmt_frame_register
2393 * @details Notify driver that a management frame type was
2394 * registered. Note that this callback may not sleep, and cannot run
2395 * concurrently with itself.
2396 * @param[in]
2397 * @return NONE.
2398 * @author mdaftedar
2399 * @date 01 JUL 2012
2400 * @version
2401 */
2402 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2403 u16 frame_type, bool reg)
2404 {
2405
2406 struct wilc_priv *priv;
2407 perInterface_wlan_t *nic;
2408 struct wilc *wl;
2409
2410 priv = wiphy_priv(wiphy);
2411 nic = netdev_priv(priv->wdev->netdev);
2412 wl = nic->wilc;
2413
2414 if (!frame_type)
2415 return;
2416
2417 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2418 switch (frame_type) {
2419 case PROBE_REQ:
2420 {
2421 nic->g_struct_frame_reg[0].frame_type = frame_type;
2422 nic->g_struct_frame_reg[0].reg = reg;
2423 }
2424 break;
2425
2426 case ACTION:
2427 {
2428 nic->g_struct_frame_reg[1].frame_type = frame_type;
2429 nic->g_struct_frame_reg[1].reg = reg;
2430 }
2431 break;
2432
2433 default:
2434 {
2435 break;
2436 }
2437
2438 }
2439 /*If mac is closed, then return*/
2440 if (!wl->initialized) {
2441 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2442 return;
2443 }
2444 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
2445
2446
2447 }
2448
2449 /**
2450 * @brief set_cqm_rssi_config
2451 * @details Configure connection quality monitor RSSI threshold.
2452 * @param[in] struct wiphy *wiphy:
2453 * @param[in] struct net_device *dev:
2454 * @param[in] s32 rssi_thold:
2455 * @param[in] u32 rssi_hyst:
2456 * @return int : Return 0 on Success
2457 * @author mdaftedar
2458 * @date 01 MAR 2012
2459 * @version 1.0
2460 */
2461 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2462 s32 rssi_thold, u32 rssi_hyst)
2463 {
2464 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2465 return 0;
2466
2467 }
2468 /**
2469 * @brief dump_station
2470 * @details Configure connection quality monitor RSSI threshold.
2471 * @param[in] struct wiphy *wiphy:
2472 * @param[in] struct net_device *dev
2473 * @param[in] int idx
2474 * @param[in] u8 *mac
2475 * @param[in] struct station_info *sinfo
2476 * @return int : Return 0 on Success
2477 * @author mdaftedar
2478 * @date 01 MAR 2012
2479 * @version 1.0
2480 */
2481 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2482 int idx, u8 *mac, struct station_info *sinfo)
2483 {
2484 struct wilc_priv *priv;
2485
2486 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2487
2488 if (idx != 0)
2489 return -ENOENT;
2490
2491 priv = wiphy_priv(wiphy);
2492
2493 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2494
2495 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
2496
2497 return 0;
2498
2499 }
2500
2501
2502 /**
2503 * @brief set_power_mgmt
2504 * @details
2505 * @param[in]
2506 * @return int : Return 0 on Success.
2507 * @author mdaftedar
2508 * @date 01 JUL 2012
2509 * @version 1.0
2510 */
2511 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2512 bool enabled, int timeout)
2513 {
2514 struct wilc_priv *priv;
2515
2516 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2517
2518 if (wiphy == NULL)
2519 return -ENOENT;
2520
2521 priv = wiphy_priv(wiphy);
2522 if (priv->hWILCWFIDrv == NULL) {
2523 PRINT_ER("Driver is NULL\n");
2524 return -EIO;
2525 }
2526
2527 if (wilc_enable_ps)
2528 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
2529
2530
2531 return 0;
2532
2533 }
2534
2535 /**
2536 * @brief change_virtual_intf
2537 * @details Change type/configuration of virtual interface,
2538 * keep the struct wireless_dev's iftype updated.
2539 * @param[in] NONE
2540 * @return int : Return 0 on Success.
2541 * @author mdaftedar
2542 * @date 01 MAR 2012
2543 * @version 1.0
2544 */
2545 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2546 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
2547 {
2548 struct wilc_priv *priv;
2549 perInterface_wlan_t *nic;
2550 u8 interface_type;
2551 u16 TID = 0;
2552 u8 i;
2553 struct wilc *wl;
2554
2555 nic = netdev_priv(dev);
2556 priv = wiphy_priv(wiphy);
2557 wl = nic->wilc;
2558
2559 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2560 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2561 p2p_local_random = 0x01;
2562 p2p_recv_random = 0x00;
2563 wilc_ie = false;
2564 wilc_optaining_ip = false;
2565 del_timer(&wilc_during_ip_timer);
2566 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
2567 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2568 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2569 wilc_set_machw_change_vir_if(dev, true);
2570 }
2571
2572 switch (type) {
2573 case NL80211_IFTYPE_STATION:
2574 wilc_connecting = 0;
2575 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
2576
2577 /* send delba over wlan interface */
2578
2579
2580 dev->ieee80211_ptr->iftype = type;
2581 priv->wdev->iftype = type;
2582 nic->monitor_flag = 0;
2583 nic->iftype = STATION_MODE;
2584
2585 /*Remove the enteries of the previously connected clients*/
2586 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
2587 interface_type = nic->iftype;
2588 nic->iftype = STATION_MODE;
2589
2590 if (wl->initialized) {
2591 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2592 wl->vif[0].bssid, TID);
2593 /* ensure that the message Q is empty */
2594 wilc_wait_msg_queue_idle();
2595
2596 /*Eliminate host interface blocking state*/
2597 up(&wl->cfg_event);
2598
2599 wilc1000_wlan_deinit(dev);
2600 wilc1000_wlan_init(dev, nic);
2601 wilc_initialized = 1;
2602 nic->iftype = interface_type;
2603
2604 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
2605 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2606 wilc_set_mac_address(wl->vif[0].hif_drv,
2607 wl->vif[0].src_addr);
2608 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
2609
2610 /*Add saved WEP keys, if any*/
2611 if (g_wep_keys_saved) {
2612 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2613 g_key_wep_params.key_idx);
2614 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2615 g_key_wep_params.key,
2616 g_key_wep_params.key_len,
2617 g_key_wep_params.key_idx);
2618 }
2619
2620 /*No matter the driver handler passed here, it will be overwriiten*/
2621 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2622 wilc_flush_join_req(priv->hWILCWFIDrv);
2623
2624 /*Add saved PTK and GTK keys, if any*/
2625 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2626 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2627 g_key_ptk_params.key[1],
2628 g_key_ptk_params.key[2]);
2629 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2630 g_key_gtk_params.key[1],
2631 g_key_gtk_params.key[2]);
2632 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2633 wl->vif[0].ndev,
2634 g_add_ptk_key_params.key_idx,
2635 g_add_ptk_key_params.pairwise,
2636 g_add_ptk_key_params.mac_addr,
2637 (struct key_params *)(&g_key_ptk_params));
2638
2639 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2640 wl->vif[0].ndev,
2641 g_add_gtk_key_params.key_idx,
2642 g_add_gtk_key_params.pairwise,
2643 g_add_gtk_key_params.mac_addr,
2644 (struct key_params *)(&g_key_gtk_params));
2645 }
2646
2647 if (wl->initialized) {
2648 for (i = 0; i < num_reg_frame; i++) {
2649 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2650 nic->g_struct_frame_reg[i].reg);
2651 wilc_frame_register(priv->hWILCWFIDrv,
2652 nic->g_struct_frame_reg[i].frame_type,
2653 nic->g_struct_frame_reg[i].reg);
2654 }
2655 }
2656
2657 wilc_enable_ps = true;
2658 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
2659 }
2660 break;
2661
2662 case NL80211_IFTYPE_P2P_CLIENT:
2663 wilc_enable_ps = false;
2664 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2665 wilc_connecting = 0;
2666 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
2667
2668 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2669 wl->vif[0].bssid, TID);
2670
2671 dev->ieee80211_ptr->iftype = type;
2672 priv->wdev->iftype = type;
2673 nic->monitor_flag = 0;
2674
2675 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2676 nic->iftype = CLIENT_MODE;
2677
2678
2679 if (wl->initialized) {
2680 /* ensure that the message Q is empty */
2681 wilc_wait_msg_queue_idle();
2682
2683 wilc1000_wlan_deinit(dev);
2684 wilc1000_wlan_init(dev, nic);
2685 wilc_initialized = 1;
2686
2687 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2688 wilc_set_mac_address(wl->vif[0].hif_drv,
2689 wl->vif[0].src_addr);
2690 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
2691
2692 /*Add saved WEP keys, if any*/
2693 if (g_wep_keys_saved) {
2694 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2695 g_key_wep_params.key_idx);
2696 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2697 g_key_wep_params.key,
2698 g_key_wep_params.key_len,
2699 g_key_wep_params.key_idx);
2700 }
2701
2702 /*No matter the driver handler passed here, it will be overwriiten*/
2703 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2704 wilc_flush_join_req(priv->hWILCWFIDrv);
2705
2706 /*Add saved PTK and GTK keys, if any*/
2707 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2708 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2709 g_key_ptk_params.key[1],
2710 g_key_ptk_params.key[2]);
2711 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2712 g_key_gtk_params.key[1],
2713 g_key_gtk_params.key[2]);
2714 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2715 wl->vif[0].ndev,
2716 g_add_ptk_key_params.key_idx,
2717 g_add_ptk_key_params.pairwise,
2718 g_add_ptk_key_params.mac_addr,
2719 (struct key_params *)(&g_key_ptk_params));
2720
2721 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2722 wl->vif[0].ndev,
2723 g_add_gtk_key_params.key_idx,
2724 g_add_gtk_key_params.pairwise,
2725 g_add_gtk_key_params.mac_addr,
2726 (struct key_params *)(&g_key_gtk_params));
2727 }
2728
2729 /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/
2730 refresh_scan(priv, 1, true);
2731 wilc_set_machw_change_vir_if(dev, false);
2732
2733 if (wl->initialized) {
2734 for (i = 0; i < num_reg_frame; i++) {
2735 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2736 nic->g_struct_frame_reg[i].reg);
2737 wilc_frame_register(priv->hWILCWFIDrv,
2738 nic->g_struct_frame_reg[i].frame_type,
2739 nic->g_struct_frame_reg[i].reg);
2740 }
2741 }
2742 }
2743 break;
2744
2745 case NL80211_IFTYPE_AP:
2746 wilc_enable_ps = false;
2747 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
2748 dev->ieee80211_ptr->iftype = type;
2749 priv->wdev->iftype = type;
2750 nic->iftype = AP_MODE;
2751 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
2752
2753 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
2754 wilc_wlan_get_firmware(dev);
2755 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
2756 if (wl->initialized) {
2757 nic->iftype = AP_MODE;
2758 wilc_mac_close(dev);
2759 wilc_mac_open(dev);
2760
2761 for (i = 0; i < num_reg_frame; i++) {
2762 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2763 nic->g_struct_frame_reg[i].reg);
2764 wilc_frame_register(priv->hWILCWFIDrv,
2765 nic->g_struct_frame_reg[i].frame_type,
2766 nic->g_struct_frame_reg[i].reg);
2767 }
2768 }
2769 break;
2770
2771 case NL80211_IFTYPE_P2P_GO:
2772 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2773
2774 wilc_optaining_ip = true;
2775 mod_timer(&wilc_during_ip_timer,
2776 jiffies + msecs_to_jiffies(during_ip_time));
2777 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2778 /*Delete block ack has to be the latest config packet*/
2779 /*sent before downloading new FW. This is because it blocks on*/
2780 /*hWaitResponse semaphore, which allows previous config*/
2781 /*packets to actually take action on old FW*/
2782 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2783 wl->vif[0].bssid, TID);
2784 wilc_enable_ps = false;
2785 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
2786 dev->ieee80211_ptr->iftype = type;
2787 priv->wdev->iftype = type;
2788
2789 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
2790
2791 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2792
2793
2794 nic->iftype = GO_MODE;
2795
2796 /* ensure that the message Q is empty */
2797 wilc_wait_msg_queue_idle();
2798 wilc1000_wlan_deinit(dev);
2799 wilc1000_wlan_init(dev, nic);
2800 wilc_initialized = 1;
2801
2802
2803 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
2804 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2805 wilc_set_mac_address(wl->vif[0].hif_drv,
2806 wl->vif[0].src_addr);
2807 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
2808
2809 /*Add saved WEP keys, if any*/
2810 if (g_wep_keys_saved) {
2811 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2812 g_key_wep_params.key_idx);
2813 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2814 g_key_wep_params.key,
2815 g_key_wep_params.key_len,
2816 g_key_wep_params.key_idx);
2817 }
2818
2819 /*No matter the driver handler passed here, it will be overwriiten*/
2820 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2821 wilc_flush_join_req(priv->hWILCWFIDrv);
2822
2823 /*Add saved PTK and GTK keys, if any*/
2824 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2825 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2826 g_key_ptk_params.key[1],
2827 g_key_ptk_params.key[2],
2828 g_key_ptk_params.cipher);
2829 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2830 g_key_gtk_params.key[1],
2831 g_key_gtk_params.key[2],
2832 g_key_gtk_params.cipher);
2833 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2834 wl->vif[0].ndev,
2835 g_add_ptk_key_params.key_idx,
2836 g_add_ptk_key_params.pairwise,
2837 g_add_ptk_key_params.mac_addr,
2838 (struct key_params *)(&g_key_ptk_params));
2839
2840 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2841 wl->vif[0].ndev,
2842 g_add_gtk_key_params.key_idx,
2843 g_add_gtk_key_params.pairwise,
2844 g_add_gtk_key_params.mac_addr,
2845 (struct key_params *)(&g_key_gtk_params));
2846 }
2847
2848 if (wl->initialized) {
2849 for (i = 0; i < num_reg_frame; i++) {
2850 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2851 nic->g_struct_frame_reg[i].reg);
2852 wilc_frame_register(priv->hWILCWFIDrv,
2853 nic->g_struct_frame_reg[i].frame_type,
2854 nic->g_struct_frame_reg[i].reg);
2855 }
2856 }
2857 break;
2858
2859 default:
2860 PRINT_ER("Unknown interface type= %d\n", type);
2861 return -EINVAL;
2862 }
2863
2864 return 0;
2865 }
2866
2867 /* (austin.2013-07-23)
2868 *
2869 * To support revised cfg80211_ops
2870 *
2871 * add_beacon --> start_ap
2872 * set_beacon --> change_beacon
2873 * del_beacon --> stop_ap
2874 *
2875 * beacon_parameters --> cfg80211_ap_settings
2876 * cfg80211_beacon_data
2877 *
2878 * applicable for linux kernel 3.4+
2879 */
2880
2881 /**
2882 * @brief start_ap
2883 * @details Add a beacon with given parameters, @head, @interval
2884 * and @dtim_period will be valid, @tail is optional.
2885 * @param[in] wiphy
2886 * @param[in] dev The net device structure
2887 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2888 * @return int : Return 0 on Success.
2889 * @author austin
2890 * @date 23 JUL 2013
2891 * @version 1.0
2892 */
2893 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2894 struct cfg80211_ap_settings *settings)
2895 {
2896 struct cfg80211_beacon_data *beacon = &(settings->beacon);
2897 struct wilc_priv *priv;
2898 s32 s32Error = 0;
2899 struct wilc *wl;
2900 perInterface_wlan_t *nic;
2901
2902 priv = wiphy_priv(wiphy);
2903 nic = netdev_priv(dev);
2904 wl = nic->wilc;
2905 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2906
2907 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
2908 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2909
2910 s32Error = set_channel(wiphy, &settings->chandef);
2911
2912 if (s32Error != 0)
2913 PRINT_ER("Error in setting channel\n");
2914
2915 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
2916
2917 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
2918 settings->beacon_interval,
2919 settings->dtim_period,
2920 beacon->head_len, (u8 *)beacon->head,
2921 beacon->tail_len, (u8 *)beacon->tail);
2922
2923 return s32Error;
2924 }
2925
2926 /**
2927 * @brief change_beacon
2928 * @details Add a beacon with given parameters, @head, @interval
2929 * and @dtim_period will be valid, @tail is optional.
2930 * @param[in] wiphy
2931 * @param[in] dev The net device structure
2932 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2933 * @return int : Return 0 on Success.
2934 * @author austin
2935 * @date 23 JUL 2013
2936 * @version 1.0
2937 */
2938 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2939 struct cfg80211_beacon_data *beacon)
2940 {
2941 struct wilc_priv *priv;
2942 s32 s32Error = 0;
2943
2944 priv = wiphy_priv(wiphy);
2945 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2946
2947
2948 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
2949 0,
2950 0,
2951 beacon->head_len, (u8 *)beacon->head,
2952 beacon->tail_len, (u8 *)beacon->tail);
2953
2954 return s32Error;
2955 }
2956
2957 /**
2958 * @brief stop_ap
2959 * @details Remove beacon configuration and stop sending the beacon.
2960 * @param[in]
2961 * @return int : Return 0 on Success.
2962 * @author austin
2963 * @date 23 JUL 2013
2964 * @version 1.0
2965 */
2966 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
2967 {
2968 s32 s32Error = 0;
2969 struct wilc_priv *priv;
2970 u8 NullBssid[ETH_ALEN] = {0};
2971
2972 if (!wiphy)
2973 return -EFAULT;
2974
2975 priv = wiphy_priv(wiphy);
2976
2977 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2978
2979 wilc_wlan_set_bssid(dev, NullBssid);
2980
2981 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
2982
2983 if (s32Error)
2984 PRINT_ER("Host delete beacon fail\n");
2985
2986 return s32Error;
2987 }
2988
2989 /**
2990 * @brief add_station
2991 * @details Add a new station.
2992 * @param[in]
2993 * @return int : Return 0 on Success.
2994 * @author mdaftedar
2995 * @date 01 MAR 2012
2996 * @version 1.0
2997 */
2998 static int add_station(struct wiphy *wiphy, struct net_device *dev,
2999 const u8 *mac, struct station_parameters *params)
3000 {
3001 s32 s32Error = 0;
3002 struct wilc_priv *priv;
3003 struct add_sta_param strStaParams = { {0} };
3004 perInterface_wlan_t *nic;
3005
3006 if (!wiphy)
3007 return -EFAULT;
3008
3009 priv = wiphy_priv(wiphy);
3010 nic = netdev_priv(dev);
3011
3012 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3013 memcpy(strStaParams.bssid, mac, ETH_ALEN);
3014 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
3015 strStaParams.aid = params->aid;
3016 strStaParams.rates_len = params->supported_rates_len;
3017 strStaParams.rates = params->supported_rates;
3018
3019 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3020
3021 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],
3022 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
3023 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
3024 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3025 strStaParams.rates_len);
3026
3027 if (params->ht_capa == NULL) {
3028 strStaParams.ht_supported = false;
3029 } else {
3030 strStaParams.ht_supported = true;
3031 strStaParams.ht_capa_info = params->ht_capa->cap_info;
3032 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
3033 memcpy(strStaParams.ht_supp_mcs_set,
3034 &params->ht_capa->mcs,
3035 WILC_SUPP_MCS_SET_SIZE);
3036 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
3037 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
3038 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
3039 }
3040
3041 strStaParams.flags_mask = params->sta_flags_mask;
3042 strStaParams.flags_set = params->sta_flags_set;
3043
3044 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3045 strStaParams.ht_supported);
3046 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3047 strStaParams.ht_capa_info);
3048 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3049 strStaParams.ht_ampdu_params);
3050 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3051 strStaParams.ht_ext_params);
3052 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3053 strStaParams.ht_tx_bf_cap);
3054 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3055 strStaParams.ht_ante_sel);
3056 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3057 strStaParams.flags_mask);
3058 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3059 strStaParams.flags_set);
3060
3061 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
3062 if (s32Error)
3063 PRINT_ER("Host add station fail\n");
3064 }
3065
3066 return s32Error;
3067 }
3068
3069 /**
3070 * @brief del_station
3071 * @details Remove a station; @mac may be NULL to remove all stations.
3072 * @param[in]
3073 * @return int : Return 0 on Success.
3074 * @author mdaftedar
3075 * @date 01 MAR 2012
3076 * @version 1.0
3077 */
3078 static int del_station(struct wiphy *wiphy, struct net_device *dev,
3079 struct station_del_parameters *params)
3080 {
3081 const u8 *mac = params->mac;
3082 s32 s32Error = 0;
3083 struct wilc_priv *priv;
3084 perInterface_wlan_t *nic;
3085
3086 if (!wiphy)
3087 return -EFAULT;
3088
3089 priv = wiphy_priv(wiphy);
3090 nic = netdev_priv(dev);
3091
3092 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3093 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3094
3095
3096 if (mac == NULL) {
3097 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
3098 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
3099 } else {
3100 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]);
3101 }
3102
3103 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
3104
3105 if (s32Error)
3106 PRINT_ER("Host delete station fail\n");
3107 }
3108 return s32Error;
3109 }
3110
3111 /**
3112 * @brief change_station
3113 * @details Modify a given station.
3114 * @param[in]
3115 * @return int : Return 0 on Success.
3116 * @author mdaftedar
3117 * @date 01 MAR 2012
3118 * @version 1.0
3119 */
3120 static int change_station(struct wiphy *wiphy, struct net_device *dev,
3121 const u8 *mac, struct station_parameters *params)
3122 {
3123 s32 s32Error = 0;
3124 struct wilc_priv *priv;
3125 struct add_sta_param strStaParams = { {0} };
3126 perInterface_wlan_t *nic;
3127
3128
3129 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3130
3131 if (!wiphy)
3132 return -EFAULT;
3133
3134 priv = wiphy_priv(wiphy);
3135 nic = netdev_priv(dev);
3136
3137 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3138 memcpy(strStaParams.bssid, mac, ETH_ALEN);
3139 strStaParams.aid = params->aid;
3140 strStaParams.rates_len = params->supported_rates_len;
3141 strStaParams.rates = params->supported_rates;
3142
3143 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3144 strStaParams.bssid[0], strStaParams.bssid[1],
3145 strStaParams.bssid[2], strStaParams.bssid[3],
3146 strStaParams.bssid[4], strStaParams.bssid[5]);
3147 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
3148 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3149 strStaParams.rates_len);
3150
3151 if (params->ht_capa == NULL) {
3152 strStaParams.ht_supported = false;
3153 } else {
3154 strStaParams.ht_supported = true;
3155 strStaParams.ht_capa_info = params->ht_capa->cap_info;
3156 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
3157 memcpy(strStaParams.ht_supp_mcs_set,
3158 &params->ht_capa->mcs,
3159 WILC_SUPP_MCS_SET_SIZE);
3160 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
3161 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
3162 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
3163 }
3164
3165 strStaParams.flags_mask = params->sta_flags_mask;
3166 strStaParams.flags_set = params->sta_flags_set;
3167
3168 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3169 strStaParams.ht_supported);
3170 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3171 strStaParams.ht_capa_info);
3172 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3173 strStaParams.ht_ampdu_params);
3174 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3175 strStaParams.ht_ext_params);
3176 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3177 strStaParams.ht_tx_bf_cap);
3178 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3179 strStaParams.ht_ante_sel);
3180 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3181 strStaParams.flags_mask);
3182 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3183 strStaParams.flags_set);
3184
3185 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
3186 if (s32Error)
3187 PRINT_ER("Host edit station fail\n");
3188 }
3189 return s32Error;
3190 }
3191
3192
3193 /**
3194 * @brief add_virtual_intf
3195 * @details
3196 * @param[in]
3197 * @return int : Return 0 on Success.
3198 * @author mdaftedar
3199 * @date 01 JUL 2012
3200 * @version 1.0
3201 */
3202 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3203 const char *name,
3204 unsigned char name_assign_type,
3205 enum nl80211_iftype type,
3206 u32 *flags,
3207 struct vif_params *params)
3208 {
3209 perInterface_wlan_t *nic;
3210 struct wilc_priv *priv;
3211 struct net_device *new_ifc = NULL;
3212
3213 priv = wiphy_priv(wiphy);
3214
3215
3216
3217 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3218
3219 nic = netdev_priv(priv->wdev->netdev);
3220
3221
3222 if (type == NL80211_IFTYPE_MONITOR) {
3223 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3224 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3225 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3226 if (new_ifc != NULL) {
3227 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
3228 nic = netdev_priv(priv->wdev->netdev);
3229 nic->monitor_flag = 1;
3230 } else
3231 PRINT_ER("Error in initializing monitor interface\n ");
3232 }
3233 return priv->wdev;
3234 }
3235
3236 /**
3237 * @brief del_virtual_intf
3238 * @details
3239 * @param[in]
3240 * @return int : Return 0 on Success.
3241 * @author mdaftedar
3242 * @date 01 JUL 2012
3243 * @version 1.0
3244 */
3245 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
3246 {
3247 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
3248 return 0;
3249 }
3250
3251 static struct cfg80211_ops wilc_cfg80211_ops = {
3252
3253 .set_monitor_channel = set_channel,
3254 .scan = scan,
3255 .connect = connect,
3256 .disconnect = disconnect,
3257 .add_key = add_key,
3258 .del_key = del_key,
3259 .get_key = get_key,
3260 .set_default_key = set_default_key,
3261 .add_virtual_intf = add_virtual_intf,
3262 .del_virtual_intf = del_virtual_intf,
3263 .change_virtual_intf = change_virtual_intf,
3264
3265 .start_ap = start_ap,
3266 .change_beacon = change_beacon,
3267 .stop_ap = stop_ap,
3268 .add_station = add_station,
3269 .del_station = del_station,
3270 .change_station = change_station,
3271 .get_station = get_station,
3272 .dump_station = dump_station,
3273 .change_bss = change_bss,
3274 .set_wiphy_params = set_wiphy_params,
3275
3276 .set_pmksa = set_pmksa,
3277 .del_pmksa = del_pmksa,
3278 .flush_pmksa = flush_pmksa,
3279 .remain_on_channel = remain_on_channel,
3280 .cancel_remain_on_channel = cancel_remain_on_channel,
3281 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
3282 .mgmt_tx = mgmt_tx,
3283 .mgmt_frame_register = wilc_mgmt_frame_register,
3284 .set_power_mgmt = set_power_mgmt,
3285 .set_cqm_rssi_config = set_cqm_rssi_config,
3286
3287 };
3288
3289
3290
3291
3292
3293 /**
3294 * @brief WILC_WFI_update_stats
3295 * @details Modify parameters for a given BSS.
3296 * @param[in]
3297 * @return int : Return 0 on Success.
3298 * @author mdaftedar
3299 * @date 01 MAR 2012
3300 * @version 1.0
3301 */
3302 int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3303 {
3304
3305 struct wilc_priv *priv;
3306
3307 priv = wiphy_priv(wiphy);
3308 switch (changed) {
3309
3310 case WILC_WFI_RX_PKT:
3311 {
3312 priv->netstats.rx_packets++;
3313 priv->netstats.rx_bytes += pktlen;
3314 priv->netstats.rx_time = get_jiffies_64();
3315 }
3316 break;
3317
3318 case WILC_WFI_TX_PKT:
3319 {
3320 priv->netstats.tx_packets++;
3321 priv->netstats.tx_bytes += pktlen;
3322 priv->netstats.tx_time = get_jiffies_64();
3323
3324 }
3325 break;
3326
3327 default:
3328 break;
3329 }
3330 return 0;
3331 }
3332
3333 /**
3334 * @brief WILC_WFI_CfgAlloc
3335 * @details Allocation of the wireless device structure and assigning it
3336 * to the cfg80211 operations structure.
3337 * @param[in] NONE
3338 * @return wireless_dev : Returns pointer to wireless_dev structure.
3339 * @author mdaftedar
3340 * @date 01 MAR 2012
3341 * @version 1.0
3342 */
3343 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
3344 {
3345
3346 struct wireless_dev *wdev;
3347
3348
3349 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3350 /*Allocating the wireless device structure*/
3351 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3352 if (!wdev) {
3353 PRINT_ER("Cannot allocate wireless device\n");
3354 goto _fail_;
3355 }
3356
3357 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
3358 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
3359 if (!wdev->wiphy) {
3360 PRINT_ER("Cannot allocate wiphy\n");
3361 goto _fail_mem_;
3362
3363 }
3364
3365 /* enable 802.11n HT */
3366 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3367 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3368 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3369 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3370 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
3371
3372 /*wiphy bands*/
3373 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3374
3375 return wdev;
3376
3377 _fail_mem_:
3378 kfree(wdev);
3379 _fail_:
3380 return NULL;
3381
3382 }
3383 /**
3384 * @brief wilc_create_wiphy
3385 * @details Registering of the wiphy structure and interface modes
3386 * @param[in] NONE
3387 * @return NONE
3388 * @author mdaftedar
3389 * @date 01 MAR 2012
3390 * @version 1.0
3391 */
3392 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
3393 {
3394 struct wilc_priv *priv;
3395 struct wireless_dev *wdev;
3396 s32 s32Error = 0;
3397
3398 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3399
3400 wdev = WILC_WFI_CfgAlloc();
3401 if (wdev == NULL) {
3402 PRINT_ER("CfgAlloc Failed\n");
3403 return NULL;
3404 }
3405
3406
3407 /*Return hardware description structure (wiphy)'s priv*/
3408 priv = wdev_priv(wdev);
3409 sema_init(&(priv->SemHandleUpdateStats), 1);
3410
3411 /*Link the wiphy with wireless structure*/
3412 priv->wdev = wdev;
3413
3414 /*Maximum number of probed ssid to be added by user for the scan request*/
3415 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
3416 /*Maximum number of pmkids to be cashed*/
3417 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3418 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
3419
3420 wdev->wiphy->max_scan_ie_len = 1000;
3421
3422 /*signal strength in mBm (100*dBm) */
3423 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3424
3425 /*Set the availaible cipher suites*/
3426 wdev->wiphy->cipher_suites = cipher_suites;
3427 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3428 /*Setting default managment types: for register action frame: */
3429 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
3430
3431 wdev->wiphy->max_remain_on_channel_duration = 500;
3432 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3433 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3434 BIT(NL80211_IFTYPE_P2P_CLIENT);
3435 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
3436 wdev->iftype = NL80211_IFTYPE_STATION;
3437
3438
3439
3440 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3441 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3442 wdev->wiphy->interface_modes, wdev->iftype);
3443
3444 set_wiphy_dev(wdev->wiphy, dev);
3445
3446 /*Register wiphy structure*/
3447 s32Error = wiphy_register(wdev->wiphy);
3448 if (s32Error) {
3449 PRINT_ER("Cannot register wiphy device\n");
3450 /*should define what action to be taken in such failure*/
3451 } else {
3452 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3453 }
3454
3455 priv->dev = net;
3456 return wdev;
3457
3458
3459 }
3460 /**
3461 * @brief WILC_WFI_WiphyFree
3462 * @details Freeing allocation of the wireless device structure
3463 * @param[in] NONE
3464 * @return NONE
3465 * @author mdaftedar
3466 * @date 01 MAR 2012
3467 * @version 1.0
3468 */
3469 int wilc_init_host_int(struct net_device *net)
3470 {
3471
3472 int s32Error = 0;
3473
3474 struct wilc_priv *priv;
3475
3476 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3477 priv = wdev_priv(net->ieee80211_ptr);
3478 if (op_ifcs == 0) {
3479 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
3480 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
3481 }
3482 op_ifcs++;
3483 if (s32Error < 0) {
3484 PRINT_ER("Failed to creat refresh Timer\n");
3485 return s32Error;
3486 }
3487
3488 priv->gbAutoRateAdjusted = false;
3489
3490 priv->bInP2PlistenState = false;
3491
3492 sema_init(&(priv->hSemScanReq), 1);
3493 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
3494 if (s32Error)
3495 PRINT_ER("Error while initializing hostinterface\n");
3496
3497 return s32Error;
3498 }
3499
3500 /**
3501 * @brief WILC_WFI_WiphyFree
3502 * @details Freeing allocation of the wireless device structure
3503 * @param[in] NONE
3504 * @return NONE
3505 * @author mdaftedar
3506 * @date 01 MAR 2012
3507 * @version 1.0
3508 */
3509 int wilc_deinit_host_int(struct net_device *net)
3510 {
3511 int s32Error = 0;
3512
3513 struct wilc_priv *priv;
3514
3515 priv = wdev_priv(net->ieee80211_ptr);
3516
3517 priv->gbAutoRateAdjusted = false;
3518
3519 priv->bInP2PlistenState = false;
3520
3521 op_ifcs--;
3522
3523 s32Error = wilc_deinit(priv->hWILCWFIDrv);
3524
3525 /* Clear the Shadow scan */
3526 clear_shadow_scan();
3527 if (op_ifcs == 0) {
3528 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
3529 del_timer_sync(&wilc_during_ip_timer);
3530 }
3531
3532 if (s32Error)
3533 PRINT_ER("Error while deintializing host interface\n");
3534
3535 return s32Error;
3536 }
3537
3538
3539 /**
3540 * @brief WILC_WFI_WiphyFree
3541 * @details Freeing allocation of the wireless device structure
3542 * @param[in] NONE
3543 * @return NONE
3544 * @author mdaftedar
3545 * @date 01 MAR 2012
3546 * @version 1.0
3547 */
3548 void wilc_free_wiphy(struct net_device *net)
3549 {
3550 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3551
3552 if (!net) {
3553 PRINT_D(INIT_DBG, "net_device is NULL\n");
3554 return;
3555 }
3556
3557 if (!net->ieee80211_ptr) {
3558 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3559 return;
3560 }
3561
3562 if (!net->ieee80211_ptr->wiphy) {
3563 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3564 return;
3565 }
3566
3567 wiphy_unregister(net->ieee80211_ptr->wiphy);
3568
3569 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3570 wiphy_free(net->ieee80211_ptr->wiphy);
3571 kfree(net->ieee80211_ptr);
3572 }
This page took 0.183394 seconds and 5 git commands to generate.