blob: 648472925de0a93e67b0a4b40eb525fc6265a00d [file] [log] [blame]
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001/*!
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 "wilc_wlan.c"
15#ifdef WILC_SDIO
16#include "linux_wlan_sdio.h" /* tony : for set_wiphy_dev() */
17#endif
18
19
20#define IS_MANAGMEMENT 0x100
21#define IS_MANAGMEMENT_CALLBACK 0x080
22#define IS_MGMT_STATUS_SUCCES 0x040
23#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
24
25extern void linux_wlan_free(void *vp);
26extern int linux_wlan_get_firmware(perInterface_wlan_t *p_nic);
27extern void linux_wlan_unlock(void *vp);
28extern WILC_Uint16 Set_machw_change_vir_if(WILC_Bool bValue);
29
30extern int mac_open(struct net_device *ndev);
31extern int mac_close(struct net_device *ndev);
32
33tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
34WILC_Uint32 u32LastScannedNtwrksCountShadow;
35#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
36WILC_TimerHandle hDuringIpTimer;
37#endif
38WILC_TimerHandle hAgingTimer;
39static WILC_Uint8 op_ifcs;
40extern WILC_Uint8 u8ConnectedSSID[6];
41
42/*BugID_5137*/
43WILC_Uint8 g_wilc_initialized = 1;
44extern linux_wlan_t *g_linux_wlan;
45#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
46extern WILC_Bool g_obtainingIP;
47#endif
48
49#define CHAN2G(_channel, _freq, _flags) { \
50 .band = IEEE80211_BAND_2GHZ, \
51 .center_freq = (_freq), \
52 .hw_value = (_channel), \
53 .flags = (_flags), \
54 .max_antenna_gain = 0, \
55 .max_power = 30, \
56}
57
58/*Frequency range for channels*/
59static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
60 CHAN2G(1, 2412, 0),
61 CHAN2G(2, 2417, 0),
62 CHAN2G(3, 2422, 0),
63 CHAN2G(4, 2427, 0),
64 CHAN2G(5, 2432, 0),
65 CHAN2G(6, 2437, 0),
66 CHAN2G(7, 2442, 0),
67 CHAN2G(8, 2447, 0),
68 CHAN2G(9, 2452, 0),
69 CHAN2G(10, 2457, 0),
70 CHAN2G(11, 2462, 0),
71 CHAN2G(12, 2467, 0),
72 CHAN2G(13, 2472, 0),
73 CHAN2G(14, 2484, 0),
74};
75
76#define RATETAB_ENT(_rate, _hw_value, _flags) { \
77 .bitrate = (_rate), \
78 .hw_value = (_hw_value), \
79 .flags = (_flags), \
80}
81
82
83/* Table 6 in section 3.2.1.1 */
84static struct ieee80211_rate WILC_WFI_rates[] = {
85 RATETAB_ENT(10, 0, 0),
86 RATETAB_ENT(20, 1, 0),
87 RATETAB_ENT(55, 2, 0),
88 RATETAB_ENT(110, 3, 0),
89 RATETAB_ENT(60, 9, 0),
90 RATETAB_ENT(90, 6, 0),
91 RATETAB_ENT(120, 7, 0),
92 RATETAB_ENT(180, 8, 0),
93 RATETAB_ENT(240, 9, 0),
94 RATETAB_ENT(360, 10, 0),
95 RATETAB_ENT(480, 11, 0),
96 RATETAB_ENT(540, 12, 0),
97};
98
99#ifdef WILC_P2P
100struct p2p_mgmt_data {
101 int size;
102 u8 *buff;
103};
104
105/*Global variable used to state the current connected STA channel*/
106WILC_Uint8 u8WLANChannel = INVALID_CHANNEL;
107
108/*BugID_5442*/
109WILC_Uint8 u8CurrChannel;
110
111WILC_Uint8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
112WILC_Uint8 u8P2Plocalrandom = 0x01;
113WILC_Uint8 u8P2Precvrandom = 0x00;
114WILC_Uint8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
115WILC_Bool bWilc_ie = WILC_FALSE;
116#endif
117
118static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
119 .channels = WILC_WFI_2ghz_channels,
120 .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels),
121 .bitrates = WILC_WFI_rates,
122 .n_bitrates = ARRAY_SIZE(WILC_WFI_rates),
123};
124
125
126/*BugID_5137*/
127struct add_key_params {
128 u8 key_idx;
129 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
130 bool pairwise;
131 #endif
132 u8 *mac_addr;
133};
134struct add_key_params g_add_gtk_key_params;
135struct wilc_wfi_key g_key_gtk_params;
136struct add_key_params g_add_ptk_key_params;
137struct wilc_wfi_key g_key_ptk_params;
138struct wilc_wfi_wep_key g_key_wep_params;
139WILC_Uint8 g_flushing_in_progress;
140WILC_Bool g_ptk_keys_saved = WILC_FALSE;
141WILC_Bool g_gtk_keys_saved = WILC_FALSE;
142WILC_Bool g_wep_keys_saved = WILC_FALSE;
143
144#define AGING_TIME (9 * 1000)
145#define duringIP_TIME 15000
146
147void clear_shadow_scan(void *pUserVoid)
148{
149 struct WILC_WFI_priv *priv;
150 int i;
151 priv = (struct WILC_WFI_priv *)pUserVoid;
152 if (op_ifcs == 0) {
153 WILC_TimerDestroy(&hAgingTimer, WILC_NULL);
154 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
155
156 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
157 if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) {
158 WILC_FREE(astrLastScannedNtwrksShadow[i].pu8IEs);
159 astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL;
160 }
161
162 host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
163 astrLastScannedNtwrksShadow[i].pJoinParams = NULL;
164 }
165 u32LastScannedNtwrksCountShadow = 0;
166 }
167
168}
169
170uint32_t get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
171{
172 uint8_t i;
173 int rssi_v = 0;
174 uint8_t num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
175
176 for (i = 0; i < num_rssi; i++)
177 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
178
179 rssi_v /= num_rssi;
180 return rssi_v;
181}
182
183void refresh_scan(void *pUserVoid, uint8_t all, WILC_Bool bDirectScan)
184{
185 struct WILC_WFI_priv *priv;
186 struct wiphy *wiphy;
187 struct cfg80211_bss *bss = NULL;
188 int i;
189 int rssi = 0;
190
191 priv = (struct WILC_WFI_priv *)pUserVoid;
192 wiphy = priv->dev->ieee80211_ptr->wiphy;
193
194 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
195 tstrNetworkInfo *pstrNetworkInfo;
196 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
197
198
199 if ((!pstrNetworkInfo->u8Found) || all) {
200 WILC_Sint32 s32Freq;
201 struct ieee80211_channel *channel;
202
203 if (pstrNetworkInfo != WILC_NULL) {
204
205 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
206 s32Freq = ieee80211_channel_to_frequency((WILC_Sint32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
207 #else
208 s32Freq = ieee80211_channel_to_frequency((WILC_Sint32)pstrNetworkInfo->u8channel);
209 #endif
210
211 channel = ieee80211_get_channel(wiphy, s32Freq);
212
213 rssi = get_rssi_avg(pstrNetworkInfo);
214 if (WILC_memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
215#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
216 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
217 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
218 (size_t)pstrNetworkInfo->u16IEsLen, (((WILC_Sint32)rssi) * 100), GFP_KERNEL);
219#else
220 bss = cfg80211_inform_bss(wiphy, channel, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
221 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
222 (size_t)pstrNetworkInfo->u16IEsLen, (((WILC_Sint32)rssi) * 100), GFP_KERNEL);
223#endif
224#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
225 cfg80211_put_bss(wiphy, bss);
226#else
227 cfg80211_put_bss(bss);
228#endif
229 }
230 }
231
232 }
233 }
234
235}
236
237void reset_shadow_found(void *pUserVoid)
238{
239 struct WILC_WFI_priv *priv;
240 int i;
241 priv = (struct WILC_WFI_priv *)pUserVoid;
242 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
243 astrLastScannedNtwrksShadow[i].u8Found = 0;
244
245 }
246}
247
248void update_scan_time(void *pUserVoid)
249{
250 struct WILC_WFI_priv *priv;
251 int i;
252 priv = (struct WILC_WFI_priv *)pUserVoid;
253 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
254 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
255 }
256}
257
258void remove_network_from_shadow(void *pUserVoid)
259{
260 struct WILC_WFI_priv *priv;
261 unsigned long now = jiffies;
262 int i, j;
263
264 priv = (struct WILC_WFI_priv *)pUserVoid;
265
266 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
267 if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
268 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s \n", astrLastScannedNtwrksShadow[i].au8ssid);
269
270 if (astrLastScannedNtwrksShadow[i].pu8IEs != NULL) {
271 WILC_FREE(astrLastScannedNtwrksShadow[i].pu8IEs);
272 astrLastScannedNtwrksShadow[i].pu8IEs = NULL;
273 }
274
275 host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
276
277 for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) {
278 astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1];
279 }
280 u32LastScannedNtwrksCountShadow--;
281 }
282 }
283
284 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow);
285 if (u32LastScannedNtwrksCountShadow != 0)
286 WILC_TimerStart(&(hAgingTimer), AGING_TIME, pUserVoid, WILC_NULL);
287 else
288 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
289}
290
291#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
292void clear_duringIP(void *pUserVoid)
293{
294 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
295 g_obtainingIP = WILC_FALSE;
296}
297#endif
298
299int8_t is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
300{
301 struct WILC_WFI_priv *priv;
302 int8_t state = -1;
303 int i;
304
305 priv = (struct WILC_WFI_priv *)pUserVoid;
306 if (u32LastScannedNtwrksCountShadow == 0) {
307 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
308 WILC_TimerStart(&(hAgingTimer), AGING_TIME, pUserVoid, WILC_NULL);
309 state = -1;
310 } else {
311 /* Linear search for now */
312 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
313 if (WILC_memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
314 pstrNetworkInfo->au8bssid, 6) == 0) {
315 state = i;
316 break;
317 }
318 }
319 }
320 return state;
321}
322
323void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
324{
325 struct WILC_WFI_priv *priv;
326 int8_t ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
327 uint32_t ap_index = 0;
328 uint8_t rssi_index = 0;
329 priv = (struct WILC_WFI_priv *)pUserVoid;
330
331 if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
332 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
333 return;
334 }
335 if (ap_found == -1) {
336 ap_index = u32LastScannedNtwrksCountShadow;
337 u32LastScannedNtwrksCountShadow++;
338
339 } else {
340 ap_index = ap_found;
341 }
342 rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
343 astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
344 if (rssi_index == NUM_RSSI) {
345 rssi_index = 0;
346 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
347 }
348 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
349
350 astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
351 astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
352
353 astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
354 WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
355 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
356
357 WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
358 pstrNetworkInfo->au8bssid, ETH_ALEN);
359
360 astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
361 astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
362 astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
363
364 astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
365 astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
366 if (ap_found != -1)
367 WILC_FREE(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
368 astrLastScannedNtwrksShadow[ap_index].pu8IEs =
369 (WILC_Uint8 *)WILC_MALLOC(pstrNetworkInfo->u16IEsLen); /* will be deallocated by the WILC_WFI_CfgScan() function */
370 WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
371 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
372
373 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
374 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
375 astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
376 if (ap_found != -1)
377 host_int_freeJoinParams(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
378 astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
379
380}
381
382
383/**
384 * @brief CfgScanResult
385 * @details Callback function which returns the scan results found
386 *
387 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
388 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
389 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
390 * void* pUserVoid: Private structure associated with the wireless interface
391 * @return NONE
392 * @author mabubakr
393 * @date
394 * @version 1.0
395 */
396static void CfgScanResult(tenuScanEvent enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
397{
398 struct WILC_WFI_priv *priv;
399 struct wiphy *wiphy;
400 WILC_Sint32 s32Freq;
401 struct ieee80211_channel *channel;
402 WILC_Sint32 s32Error = WILC_SUCCESS;
403 struct cfg80211_bss *bss = NULL;
404
405 priv = (struct WILC_WFI_priv *)pUserVoid;
406 if (priv->bCfgScanning == WILC_TRUE) {
407 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
408 wiphy = priv->dev->ieee80211_ptr->wiphy;
409 WILC_NULLCHECK(s32Error, wiphy);
410 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
411 &&
412 ((((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100) < 0
413 ||
414 (((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100) > 100)
415 ) {
416 WILC_ERRORREPORT(s32Error, WILC_FAIL);
417 }
418
419 if (pstrNetworkInfo != WILC_NULL) {
420 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
421 s32Freq = ieee80211_channel_to_frequency((WILC_Sint32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
422 #else
423 s32Freq = ieee80211_channel_to_frequency((WILC_Sint32)pstrNetworkInfo->u8channel);
424 #endif
425 channel = ieee80211_get_channel(wiphy, s32Freq);
426
427 WILC_NULLCHECK(s32Error, channel);
428
429 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
430 "BeaconPeriod: %d \n", channel->center_freq, (((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100),
431 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
432
433 if (pstrNetworkInfo->bNewNetwork == WILC_TRUE) {
434 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
435 /* max_scan_ssids */
436 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
437
438
439 priv->u32RcvdChCount++;
440
441
442
443 if (pJoinParams == NULL) {
444 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
445 }
446 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
447
448 /*P2P peers are sent to WPA supplicant and added to shadow table*/
449
450 if (!(WILC_memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
451#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
452 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
453 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
454 (size_t)pstrNetworkInfo->u16IEsLen, (((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
455#else
456 bss = cfg80211_inform_bss(wiphy, channel, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
457 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
458 (size_t)pstrNetworkInfo->u16IEsLen, (((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
459#endif
460#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
461 cfg80211_put_bss(wiphy, bss);
462#else
463 cfg80211_put_bss(bss);
464#endif
465 }
466
467
468 } else {
469 PRINT_ER("Discovered networks exceeded the max limit\n");
470 }
471 } else {
472 WILC_Uint32 i;
473 /* So this network is discovered before, we'll just update its RSSI */
474 for (i = 0; i < priv->u32RcvdChCount; i++) {
475 if (WILC_memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
476 PRINT_D(CFG80211_DBG, "Update RSSI of %s \n", astrLastScannedNtwrksShadow[i].au8ssid);
477
478 astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
479 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
480 break;
481 }
482 }
483 }
484 }
485 } else if (enuScanEvent == SCAN_EVENT_DONE) {
486 PRINT_D(CFG80211_DBG, "Scan Done[%p] \n", priv->dev);
487 PRINT_D(CFG80211_DBG, "Refreshing Scan ... \n");
488 refresh_scan(priv, 1, WILC_FALSE);
489
490 if (priv->u32RcvdChCount > 0) {
491 PRINT_D(CFG80211_DBG, "%d Network(s) found \n", priv->u32RcvdChCount);
492 } else {
493 PRINT_D(CFG80211_DBG, "No networks found \n");
494 }
495
496 WILC_SemaphoreAcquire(&(priv->hSemScanReq), NULL);
497
498 if (priv->pstrScanReq != WILC_NULL) {
499 cfg80211_scan_done(priv->pstrScanReq, WILC_FALSE);
500 priv->u32RcvdChCount = 0;
501 priv->bCfgScanning = WILC_FALSE;
502 priv->pstrScanReq = WILC_NULL;
503 }
504 WILC_SemaphoreRelease(&(priv->hSemScanReq), NULL);
505
506 }
507 /*Aborting any scan operation during mac close*/
508 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
509 WILC_SemaphoreAcquire(&(priv->hSemScanReq), NULL);
510
511 PRINT_D(CFG80211_DBG, "Scan Aborted \n");
512 if (priv->pstrScanReq != WILC_NULL) {
513
514 update_scan_time(priv);
515 refresh_scan(priv, 1, WILC_FALSE);
516
517 cfg80211_scan_done(priv->pstrScanReq, WILC_FALSE);
518 priv->bCfgScanning = WILC_FALSE;
519 priv->pstrScanReq = WILC_NULL;
520 }
521 WILC_SemaphoreRelease(&(priv->hSemScanReq), NULL);
522 }
523 }
524
525
526 WILC_CATCH(s32Error)
527 {
528 }
529}
530
531
532/**
533 * @brief WILC_WFI_Set_PMKSA
534 * @details Check if pmksa is cached and set it.
535 * @param[in]
536 * @return int : Return 0 on Success
537 * @author mdaftedar
538 * @date 01 MAR 2012
539 * @version 1.0
540 */
541int WILC_WFI_Set_PMKSA(WILC_Uint8 *bssid, struct WILC_WFI_priv *priv)
542{
543 WILC_Uint32 i;
544 WILC_Sint32 s32Error = WILC_SUCCESS;
545
546
547 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
548
549 if (!WILC_memcmp(bssid, priv->pmkid_list.pmkidlist[i].bssid,
550 ETH_ALEN)) {
551 PRINT_D(CFG80211_DBG, "PMKID successful comparison");
552
553 /*If bssid is found, set the values*/
554 s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
555
556 if (s32Error != WILC_SUCCESS)
557 PRINT_ER("Error in pmkid\n");
558
559 break;
560 }
561 }
562
563 return s32Error;
564
565
566}
567int linux_wlan_set_bssid(struct net_device *wilc_netdev, uint8_t *pBSSID);
568
569
570/**
571 * @brief CfgConnectResult
572 * @details
573 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
574 * connection response or disconnection notification.
575 * tstrConnectInfo* pstrConnectInfo: COnnection information.
576 * WILC_Uint8 u8MacStatus: Mac Status from firmware
577 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
578 * void* pUserVoid: Private data associated with wireless interface
579 * @return NONE
580 * @author mabubakr
581 * @date 01 MAR 2012
582 * @version 1.0
583 */
584int connecting;
585
586static void CfgConnectResult(tenuConnDisconnEvent enuConnDisconnEvent,
587 tstrConnectInfo *pstrConnectInfo,
588 WILC_Uint8 u8MacStatus,
589 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
590 void *pUserVoid)
591{
592 struct WILC_WFI_priv *priv;
593 struct net_device *dev;
594 #ifdef WILC_P2P
595 tstrWILC_WFIDrv *pstrWFIDrv;
596 #endif
597 WILC_Uint8 NullBssid[ETH_ALEN] = {0};
598 connecting = 0;
599
600 priv = (struct WILC_WFI_priv *)pUserVoid;
601 dev = priv->dev;
602 #ifdef WILC_P2P
603 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
604 #endif
605
606 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
607 /*Initialization*/
608 WILC_Uint16 u16ConnectStatus = WLAN_STATUS_SUCCESS;
609
610 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
611
612 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
613
614 if ((u8MacStatus == MAC_DISCONNECTED) &&
615 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
616 /* The case here is that our station was waiting for association response frame and has just received it containing status code
617 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
618 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
619 linux_wlan_set_bssid(priv->dev, NullBssid);
620 WILC_memset(u8ConnectedSSID, 0, ETH_ALEN);
621
622 /*BugID_5457*/
623 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
624 #ifdef WILC_P2P
625 if (!pstrWFIDrv->u8P2PConnect)
626 u8WLANChannel = INVALID_CHANNEL;
627 #endif
628
629 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d \n", u16ConnectStatus, u8MacStatus);
630 }
631
632 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
633 WILC_Bool bNeedScanRefresh = WILC_FALSE;
634 WILC_Uint32 i;
635
636 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
637 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
638 WILC_memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
639
640 /* set bssid in frame filter */
641 /* linux_wlan_set_bssid(dev,pstrConnectInfo->au8bssid); */
642
643 /* BugID_4209: if this network has expired in the scan results in the above nl80211 layer, refresh them here by calling
644 * cfg80211_inform_bss() with the last Scan results before calling cfg80211_connect_result() to avoid
645 * Linux kernel warning generated at the nl80211 layer */
646
647 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
648 if (WILC_memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
649 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
650 unsigned long now = jiffies;
651
652 if (time_after(now,
653 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
654 bNeedScanRefresh = WILC_TRUE;
655 }
656
657 break;
658 }
659 }
660
661 if (bNeedScanRefresh == WILC_TRUE) {
662 /* RefreshScanResult(priv); */
663 /*BugID_5418*/
664 /*Also, refrsh DIRECT- results if */
665 refresh_scan(priv, 1, WILC_TRUE);
666
667 }
668
669 }
670
671
672 PRINT_D(CFG80211_DBG, "Association request info elements length = %d\n", pstrConnectInfo->ReqIEsLen);
673
674 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
675
676 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
677 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
678 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
679 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
680 /* be replaced by pstrConnectInfo->u16ConnectStatus */
681 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
682 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
683 g_obtainingIP = WILC_FALSE;
684 #endif
685 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
686 pstrDisconnectNotifInfo->u16reason, priv->dev);
687 u8P2Plocalrandom = 0x01;
688 u8P2Precvrandom = 0x00;
689 bWilc_ie = WILC_FALSE;
690 WILC_memset(priv->au8AssociatedBss, 0, ETH_ALEN);
691 linux_wlan_set_bssid(priv->dev, NullBssid);
692 WILC_memset(u8ConnectedSSID, 0, ETH_ALEN);
693
694 /*BugID_5457*/
695 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
696 #ifdef WILC_P2P
697 if (!pstrWFIDrv->u8P2PConnect)
698 u8WLANChannel = INVALID_CHANNEL;
699 #endif
700 /*BugID_5315*/
701 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
702 * virtual interface to station*/
703 if ((pstrWFIDrv->IFC_UP) && (dev == g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) {
704 pstrDisconnectNotifInfo->u16reason = 3;
705 }
706 /*BugID_5315*/
707 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
708 * to scan again and retry the connection*/
709 else if ((!pstrWFIDrv->IFC_UP) && (dev == g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) {
710 pstrDisconnectNotifInfo->u16reason = 1;
711 }
712 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
713 pstrDisconnectNotifInfo->ie_len, GFP_KERNEL);
714
715 }
716
717}
718
719
720/**
721 * @brief WILC_WFI_CfgSetChannel
722 * @details Set channel for a given wireless interface. Some devices
723 * may support multi-channel operation (by channel hopping) so cfg80211
724 * doesn't verify much. Note, however, that the passed netdev may be
725 * %NULL as well if the user requested changing the channel for the
726 * device itself, or for a monitor interface.
727 * @param[in]
728 * @return int : Return 0 on Success
729 * @author mdaftedar
730 * @date 01 MAR 2012
731 * @version 1.0
732 */
733#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
734/*
735 * struct changed from v3.8.0
736 * tony, sswd, WILC-KR, 2013-10-29
737 * struct cfg80211_chan_def {
738 * struct ieee80211_channel *chan;
739 * enum nl80211_chan_width width;
740 * u32 center_freq1;
741 * u32 center_freq2;
742 * };
743 */
744static int WILC_WFI_CfgSetChannel(struct wiphy *wiphy,
745 struct cfg80211_chan_def *chandef)
746#else
747static int WILC_WFI_CfgSetChannel(struct wiphy *wiphy,
748 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32)
749 struct net_device *netdev,
750 #endif
751 struct ieee80211_channel *channel,
752 enum nl80211_channel_type channel_type)
753#endif
754{
755
756 WILC_Uint32 channelnum = 0;
757 struct WILC_WFI_priv *priv;
758 WILC_Sint32 s32Error = WILC_SUCCESS;
759 priv = wiphy_priv(wiphy);
760
761#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) /* tony for v3.8.0 support */
762 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
763 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
764#else
765 channelnum = ieee80211_frequency_to_channel(channel->center_freq);
766
767 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, channel->center_freq);
768#endif
769
770 u8CurrChannel = channelnum;
771 s32Error = host_int_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
772
773 if (s32Error != WILC_SUCCESS)
774 PRINT_ER("Error in setting channel %d\n", channelnum);
775
776 return s32Error;
777}
778
779/**
780 * @brief WILC_WFI_CfgScan
781 * @details Request to do a scan. If returning zero, the scan request is given
782 * the driver, and will be valid until passed to cfg80211_scan_done().
783 * For scan results, call cfg80211_inform_bss(); you can call this outside
784 * the scan/scan_done bracket too.
785 * @param[in]
786 * @return int : Return 0 on Success
787 * @author mabubakr
788 * @date 01 MAR 2012
789 * @version 1.0
790 */
791
792/*
793 * kernel version 3.8.8 supported
794 * tony, sswd, WILC-KR, 2013-10-29
795 */
796#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
797static int WILC_WFI_CfgScan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
798#else
799static int WILC_WFI_CfgScan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request)
800#endif
801{
802 struct WILC_WFI_priv *priv;
803 WILC_Uint32 i;
804 WILC_Sint32 s32Error = WILC_SUCCESS;
805 WILC_Uint8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
806 tstrHiddenNetwork strHiddenNetwork;
807
808 priv = wiphy_priv(wiphy);
809
810#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
811 PRINT_D(CORECONFIG_DBG, "Scan on netdev [%p] host if [%x]\n", dev, (WILC_Uint32)priv->hWILCWFIDrv);
812#endif
813
814 /*if(connecting)
815 * return -EBUSY; */
816
817 /*BugID_4800: if in AP mode, return.*/
818 /*This check is to handle the situation when user*/
819 /*requests "create group" during a running scan*/
820 /* host_int_set_wfi_drv_handler(priv->hWILCWFIDrv); */
821#if 0
822#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) /* tony for v3.8.0 support */
823 if (priv->dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) {
824 PRINT_D(GENERIC_DBG, "Required scan while in AP mode");
825 return s32Error;
826 }
827#else
828 if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) {
829 PRINT_D(GENERIC_DBG, "Required scan while in AP mode");
830 s32Error = WILC_BUSY;
831 return s32Error;
832 }
833#endif
834#endif /* end of if 0 */
835 priv->pstrScanReq = request;
836
837 priv->u32RcvdChCount = 0;
838
839 host_int_set_wfi_drv_handler((WILC_Uint32)priv->hWILCWFIDrv);
840
841
842 reset_shadow_found(priv);
843
844 priv->bCfgScanning = WILC_TRUE;
845 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
846 /* max_scan_ssids */
847 for (i = 0; i < request->n_channels; i++) {
848 au8ScanChanList[i] = (WILC_Uint8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
849 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
850 }
851
852 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
853 PRINT_D(CFG80211_DBG, "Scan Request IE len = %d\n", request->ie_len);
854
855 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
856
857 if (request->n_ssids >= 1) {
858
859
860 strHiddenNetwork.pstrHiddenNetworkInfo = WILC_MALLOC(request->n_ssids * sizeof(tstrHiddenNetwork));
861 strHiddenNetwork.u8ssidnum = request->n_ssids;
862
863
864 /*BugID_4156*/
865 for (i = 0; i < request->n_ssids; i++) {
866
867 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
868 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = WILC_MALLOC(request->ssids[i].ssid_len);
869 WILC_memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
870 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
871 } else {
872 PRINT_D(CFG80211_DBG, "Received one NULL SSID \n");
873 strHiddenNetwork.u8ssidnum -= 1;
874 }
875 }
876 PRINT_D(CFG80211_DBG, "Trigger Scan Request \n");
877 s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
878 au8ScanChanList, request->n_channels,
879 (const WILC_Uint8 *)request->ie, request->ie_len,
880 CfgScanResult, (void *)priv, &strHiddenNetwork);
881 } else {
882 PRINT_D(CFG80211_DBG, "Trigger Scan Request \n");
883 s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
884 au8ScanChanList, request->n_channels,
885 (const WILC_Uint8 *)request->ie, request->ie_len,
886 CfgScanResult, (void *)priv, NULL);
887 }
888
889 } else {
890 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
891 " channels \n");
892 }
893
894 if (s32Error != WILC_SUCCESS) {
895 s32Error = -EBUSY;
896 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
897 }
898
899 return s32Error;
900}
901
902/**
903 * @brief WILC_WFI_CfgConnect
904 * @details Connect to the ESS with the specified parameters. When connected,
905 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
906 * If the connection fails for some reason, call cfg80211_connect_result()
907 * with the status from the AP.
908 * @param[in]
909 * @return int : Return 0 on Success
910 * @author mabubakr
911 * @date 01 MAR 2012
912 * @version 1.0
913 */
914static int WILC_WFI_CfgConnect(struct wiphy *wiphy, struct net_device *dev,
915 struct cfg80211_connect_params *sme)
916{
917 WILC_Sint32 s32Error = WILC_SUCCESS;
918 WILC_Uint32 i;
919 /* SECURITY_T tenuSecurity_t = NO_SECURITY; */
920 WILC_Uint8 u8security = NO_ENCRYPT;
921 AUTHTYPE_T tenuAuth_type = ANY;
922 WILC_Char *pcgroup_encrypt_val;
923 WILC_Char *pccipher_group;
924 WILC_Char *pcwpa_version;
925
926 struct WILC_WFI_priv *priv;
927 tstrWILC_WFIDrv *pstrWFIDrv;
928 tstrNetworkInfo *pstrNetworkInfo = NULL;
929
930
931 connecting = 1;
932 priv = wiphy_priv(wiphy);
933 pstrWFIDrv = (tstrWILC_WFIDrv *)(priv->hWILCWFIDrv);
934
935 host_int_set_wfi_drv_handler((WILC_Uint32)priv->hWILCWFIDrv);
936
937 /* host_int_set_wfi_drv_handler((WILC_Uint32)priv->hWILCWFIDrv); */
938 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%x]\n", sme->ssid, dev, (WILC_Uint32)priv->hWILCWFIDrv);
939 #ifdef WILC_P2P
940 if (!(WILC_strncmp(sme->ssid, "DIRECT-", 7))) {
941 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
942 pstrWFIDrv->u8P2PConnect = 1;
943 } else
944 pstrWFIDrv->u8P2PConnect = 0;
945 #endif
946 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d \n", sme->ssid, sme->auth_type);
947
948 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
949 if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
950 WILC_memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
951 sme->ssid,
952 sme->ssid_len) == 0) {
953 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
954 if (sme->bssid == NULL) {
955 /* BSSID is not passed from the user, so decision of matching
956 * is done by SSID only */
957 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
958 break;
959 } else {
960 /* BSSID is also passed from the user, so decision of matching
961 * should consider also this passed BSSID */
962 if (WILC_memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
963 sme->bssid,
964 ETH_ALEN) == 0) {
965 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
966 break;
967 }
968 }
969 }
970 }
971
972 if (i < u32LastScannedNtwrksCountShadow) {
973 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
974
975 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
976
977 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
978 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
979 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
980 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
981 } else {
982 s32Error = -ENOENT;
983 if (u32LastScannedNtwrksCountShadow == 0)
984 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
985 else
986 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
987
988 goto done;
989 }
990
991 priv->WILC_WFI_wep_default = 0;
992 WILC_memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
993 WILC_memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
994
995 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
996 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
997
998 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
999
1000 if (INFO) {
1001 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
1002 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
1003 }
1004
1005 if (sme->crypto.cipher_group != NO_ENCRYPT) {
1006 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
1007 * we will add to it the pairwise cipher suite(s) */
1008 pcwpa_version = "Default";
1009 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
1010 /* case NL80211_WPA_VERSION_1: */
1011 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
1012 /* tenuSecurity_t = WEP_40; */
1013 u8security = ENCRYPT_ENABLED | WEP;
1014 pcgroup_encrypt_val = "WEP40";
1015 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
1016 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
1017
1018 if (INFO) {
1019 for (i = 0; i < sme->key_len; i++)
1020 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
1021 }
1022 priv->WILC_WFI_wep_default = sme->key_idx;
1023 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
1024 WILC_memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
1025
1026 /*BugID_5137*/
1027 g_key_wep_params.key_len = sme->key_len;
1028 g_key_wep_params.key = WILC_MALLOC(sme->key_len);
1029 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
1030 g_key_wep_params.key_idx = sme->key_idx;
1031 g_wep_keys_saved = WILC_TRUE;
1032
1033 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, sme->key_idx);
1034 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
1035 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
1036 /* tenuSecurity_t = WEP_104; */
1037 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1038 pcgroup_encrypt_val = "WEP104";
1039 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
1040
1041 priv->WILC_WFI_wep_default = sme->key_idx;
1042 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
1043 WILC_memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
1044
1045 /*BugID_5137*/
1046 g_key_wep_params.key_len = sme->key_len;
1047 g_key_wep_params.key = WILC_MALLOC(sme->key_len);
1048 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
1049 g_key_wep_params.key_idx = sme->key_idx;
1050 g_wep_keys_saved = WILC_TRUE;
1051
1052 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, sme->key_idx);
1053 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
1054 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
1055 /* case NL80211_WPA_VERSION_2: */
1056 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
1057 /* tenuSecurity_t = WPA2_TKIP; */
1058 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
1059 pcgroup_encrypt_val = "WPA2_TKIP";
1060 pccipher_group = "TKIP";
1061 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
1062 /* tenuSecurity_t = WPA2_AES; */
1063 u8security = ENCRYPT_ENABLED | WPA2 | AES;
1064 pcgroup_encrypt_val = "WPA2_AES";
1065 pccipher_group = "AES";
1066 }
1067 pcwpa_version = "WPA_VERSION_2";
1068 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
1069 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
1070 /* tenuSecurity_t = WPA_TKIP; */
1071 u8security = ENCRYPT_ENABLED | WPA | TKIP;
1072 pcgroup_encrypt_val = "WPA_TKIP";
1073 pccipher_group = "TKIP";
1074 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
1075 /* tenuSecurity_t = WPA_AES; */
1076 u8security = ENCRYPT_ENABLED | WPA | AES;
1077 pcgroup_encrypt_val = "WPA_AES";
1078 pccipher_group = "AES";
1079
1080 }
1081 pcwpa_version = "WPA_VERSION_1";
1082
1083 /* break; */
1084 } else {
1085 s32Error = -ENOTSUPP;
1086 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1087
1088 goto done;
1089 }
1090
1091 }
1092
1093 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
1094 * add to it the pairwise cipher suite(s) */
1095 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1096 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
1097 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
1098 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
1099 u8security = u8security | TKIP;
1100 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
1101 u8security = u8security | AES;
1102 }
1103 }
1104 }
1105
1106 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
1107
1108 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
1109 switch (sme->auth_type) {
1110 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1111 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
1112 tenuAuth_type = OPEN_SYSTEM;
1113 break;
1114
1115 case NL80211_AUTHTYPE_SHARED_KEY:
1116 tenuAuth_type = SHARED_KEY;
1117 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
1118 break;
1119
1120 default:
1121 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1122 }
1123
1124
1125 /* ai: key_mgmt: enterprise case */
1126 if (sme->crypto.n_akm_suites) {
1127 switch (sme->crypto.akm_suites[0]) {
1128 case WLAN_AKM_SUITE_8021X:
1129 tenuAuth_type = IEEE8021;
1130 break;
1131
1132 default:
1133 break;
1134 }
1135 }
1136
1137
1138 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1139
1140 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1141 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1142
1143 /*BugID_5442*/
1144 u8CurrChannel = pstrNetworkInfo->u8channel;
1145
1146 if (!pstrWFIDrv->u8P2PConnect) {
1147 u8WLANChannel = pstrNetworkInfo->u8channel;
1148 }
1149
1150 linux_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
1151
1152 s32Error = host_int_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
1153 sme->ssid_len, sme->ie, sme->ie_len,
1154 CfgConnectResult, (void *)priv, u8security,
1155 tenuAuth_type, pstrNetworkInfo->u8channel,
1156 pstrNetworkInfo->pJoinParams);
1157 if (s32Error != WILC_SUCCESS) {
1158 PRINT_ER("host_int_set_join_req(): Error(%d) \n", s32Error);
1159 s32Error = -ENOENT;
1160 goto done;
1161 }
1162
1163done:
1164
1165 return s32Error;
1166}
1167
1168
1169/**
1170 * @brief WILC_WFI_disconnect
1171 * @details Disconnect from the BSS/ESS.
1172 * @param[in]
1173 * @return int : Return 0 on Success
1174 * @author mdaftedar
1175 * @date 01 MAR 2012
1176 * @version 1.0
1177 */
1178static int WILC_WFI_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
1179{
1180 WILC_Sint32 s32Error = WILC_SUCCESS;
1181 struct WILC_WFI_priv *priv;
1182 #ifdef WILC_P2P
1183 tstrWILC_WFIDrv *pstrWFIDrv;
1184 #endif
1185 uint8_t NullBssid[ETH_ALEN] = {0};
1186 connecting = 0;
1187 priv = wiphy_priv(wiphy);
1188
1189 /*BugID_5457*/
1190 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
1191 #ifdef WILC_P2P
1192 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
1193 if (!pstrWFIDrv->u8P2PConnect)
1194 u8WLANChannel = INVALID_CHANNEL;
1195 #endif
1196 linux_wlan_set_bssid(priv->dev, NullBssid);
1197
1198 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1199
1200 u8P2Plocalrandom = 0x01;
1201 u8P2Precvrandom = 0x00;
1202 bWilc_ie = WILC_FALSE;
1203 #ifdef WILC_P2P
1204 pstrWFIDrv->u64P2p_MgmtTimeout = 0;
1205 #endif
1206
1207 s32Error = host_int_disconnect(priv->hWILCWFIDrv, reason_code);
1208 if (s32Error != WILC_SUCCESS) {
1209 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1210 s32Error = -EINVAL;
1211 }
1212
1213 return s32Error;
1214}
1215
1216/**
1217 * @brief WILC_WFI_add_key
1218 * @details Add a key with the given parameters. @mac_addr will be %NULL
1219 * when adding a group key.
1220 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1221 * @return int : Return 0 on Success
1222 * @author mdaftedar
1223 * @date 01 MAR 2012
1224 * @version 1.0
1225 */
1226static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1227 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
1228 bool pairwise,
1229 #endif
1230 const u8 *mac_addr, struct key_params *params)
1231
1232{
1233 WILC_Sint32 s32Error = WILC_SUCCESS, KeyLen = params->key_len;
1234 WILC_Uint32 i;
1235 struct WILC_WFI_priv *priv;
1236 WILC_Uint8 *pu8RxMic = NULL;
1237 WILC_Uint8 *pu8TxMic = NULL;
1238 WILC_Uint8 u8mode = NO_ENCRYPT;
1239 #ifdef WILC_AP_EXTERNAL_MLME
1240 WILC_Uint8 u8gmode = NO_ENCRYPT;
1241 WILC_Uint8 u8pmode = NO_ENCRYPT;
1242 AUTHTYPE_T tenuAuth_type = ANY;
1243 #endif
1244
1245 priv = wiphy_priv(wiphy);
1246
1247 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1248
1249 /*BugID_5137*/
1250 PRINT_D(CFG80211_DBG, "%x %x %d\n", (WILC_Uint32)wiphy, (WILC_Uint32)netdev, key_index);
1251
1252 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1253 params->key[1],
1254 params->key[2]);
1255
1256
1257 switch (params->cipher) {
1258 case WLAN_CIPHER_SUITE_WEP40:
1259 case WLAN_CIPHER_SUITE_WEP104:
1260 #ifdef WILC_AP_EXTERNAL_MLME
1261 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1262
1263 priv->WILC_WFI_wep_default = key_index;
1264 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
1265 WILC_memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
1266
1267 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1268 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1269
1270 for (i = 0; i < params->key_len; i++)
1271 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1272
1273 tenuAuth_type = OPEN_SYSTEM;
1274
1275 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1276 u8mode = ENCRYPT_ENABLED | WEP;
1277 else
1278 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1279
1280 host_int_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
1281 break;
1282 }
1283 #endif
1284 if (WILC_memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
1285 priv->WILC_WFI_wep_default = key_index;
1286 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
1287 WILC_memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
1288
1289 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1290 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1291 if (INFO) {
1292 for (i = 0; i < params->key_len; i++)
1293 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1294 }
1295 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
1296 }
1297
1298 break;
1299
1300 case WLAN_CIPHER_SUITE_TKIP:
1301 case WLAN_CIPHER_SUITE_CCMP:
1302 #ifdef WILC_AP_EXTERNAL_MLME
1303 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1304
1305 if (priv->wilc_gtk[key_index] == NULL) {
1306 priv->wilc_gtk[key_index] = (struct wilc_wfi_key *)WILC_MALLOC(sizeof(struct wilc_wfi_key));
1307 priv->wilc_gtk[key_index]->key = WILC_NULL;
1308 priv->wilc_gtk[key_index]->seq = WILC_NULL;
1309
1310 }
1311 if (priv->wilc_ptk[key_index] == NULL) {
1312 priv->wilc_ptk[key_index] = (struct wilc_wfi_key *)WILC_MALLOC(sizeof(struct wilc_wfi_key));
1313 priv->wilc_ptk[key_index]->key = WILC_NULL;
1314 priv->wilc_ptk[key_index]->seq = WILC_NULL;
1315 }
1316
1317
1318
1319 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
1320 if (!pairwise)
1321 #else
1322 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1323 #endif
1324 {
1325 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1326 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1327 else
1328 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1329
1330 priv->wilc_groupkey = u8gmode;
1331
1332 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1333
1334 pu8TxMic = params->key + 24;
1335 pu8RxMic = params->key + 16;
1336 KeyLen = params->key_len - 16;
1337 }
1338 /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
1339 if (priv->wilc_gtk[key_index]->key)
1340 WILC_FREE(priv->wilc_gtk[key_index]->key);
1341
1342 priv->wilc_gtk[key_index]->key = (WILC_Uint8 *)WILC_MALLOC(params->key_len);
1343 WILC_memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
1344
1345 /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
1346 if (priv->wilc_gtk[key_index]->seq)
1347 WILC_FREE(priv->wilc_gtk[key_index]->seq);
1348
1349 if ((params->seq_len) > 0) {
1350 priv->wilc_gtk[key_index]->seq = (WILC_Uint8 *)WILC_MALLOC(params->seq_len);
1351 WILC_memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
1352 }
1353
1354 priv->wilc_gtk[key_index]->cipher = params->cipher;
1355 priv->wilc_gtk[key_index]->key_len = params->key_len;
1356 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1357
1358 if (INFO) {
1359 for (i = 0; i < params->key_len; i++)
1360 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1361 for (i = 0; i < params->seq_len; i++)
1362 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1363 }
1364
1365
1366 host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
1367 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1368
1369 } else {
1370 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]);
1371
1372 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1373 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1374 else
1375 u8pmode = priv->wilc_groupkey | AES;
1376
1377
1378 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1379
1380 pu8TxMic = params->key + 24;
1381 pu8RxMic = params->key + 16;
1382 KeyLen = params->key_len - 16;
1383 }
1384
1385 if (priv->wilc_ptk[key_index]->key)
1386 WILC_FREE(priv->wilc_ptk[key_index]->key);
1387
1388 priv->wilc_ptk[key_index]->key = (WILC_Uint8 *)WILC_MALLOC(params->key_len);
1389
1390 if (priv->wilc_ptk[key_index]->seq)
1391 WILC_FREE(priv->wilc_ptk[key_index]->seq);
1392
1393 if ((params->seq_len) > 0)
1394 priv->wilc_ptk[key_index]->seq = (WILC_Uint8 *)WILC_MALLOC(params->seq_len);
1395
1396 if (INFO) {
1397 for (i = 0; i < params->key_len; i++)
1398 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1399
1400 for (i = 0; i < params->seq_len; i++)
1401 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1402 }
1403
1404 WILC_memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
1405
1406 if ((params->seq_len) > 0)
1407 WILC_memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
1408
1409 priv->wilc_ptk[key_index]->cipher = params->cipher;
1410 priv->wilc_ptk[key_index]->key_len = params->key_len;
1411 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1412
1413 host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
1414 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1415 }
1416 break;
1417 }
1418 #endif
1419
1420 {
1421 u8mode = 0;
1422 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
1423 if (!pairwise)
1424 #else
1425 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1426 #endif
1427 {
1428 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1429 /* swap the tx mic by rx mic */
1430 pu8RxMic = params->key + 24;
1431 pu8TxMic = params->key + 16;
1432 KeyLen = params->key_len - 16;
1433 }
1434
1435 /*BugID_5137*/
1436 /*save keys only on interface 0 (wifi interface)*/
1437 if (!g_gtk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
1438 g_add_gtk_key_params.key_idx = key_index;
1439 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
1440 g_add_gtk_key_params.pairwise = pairwise;
1441 #endif
1442 if (!mac_addr) {
1443 g_add_gtk_key_params.mac_addr = NULL;
1444 } else {
1445 g_add_gtk_key_params.mac_addr = WILC_MALLOC(ETH_ALEN);
1446 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1447 }
1448 g_key_gtk_params.key_len = params->key_len;
1449 g_key_gtk_params.seq_len = params->seq_len;
1450 g_key_gtk_params.key = WILC_MALLOC(params->key_len);
1451 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1452 if (params->seq_len > 0) {
1453 g_key_gtk_params.seq = WILC_MALLOC(params->seq_len);
1454 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1455 }
1456 g_key_gtk_params.cipher = params->cipher;
1457
1458 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1459 g_key_gtk_params.key[1],
1460 g_key_gtk_params.key[2]);
1461 g_gtk_keys_saved = WILC_TRUE;
1462 }
1463
1464 host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
1465 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
1466 /* host_int_add_tx_gtk(priv->hWILCWFIDrv,params->key_len,params->key,key_index); */
1467 } else {
1468 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1469 /* swap the tx mic by rx mic */
1470 pu8RxMic = params->key + 24;
1471 pu8TxMic = params->key + 16;
1472 KeyLen = params->key_len - 16;
1473 }
1474
1475 /*BugID_5137*/
1476 /*save keys only on interface 0 (wifi interface)*/
1477 if (!g_ptk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
1478 g_add_ptk_key_params.key_idx = key_index;
1479 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
1480 g_add_ptk_key_params.pairwise = pairwise;
1481 #endif
1482 if (!mac_addr) {
1483 g_add_ptk_key_params.mac_addr = NULL;
1484 } else {
1485 g_add_ptk_key_params.mac_addr = WILC_MALLOC(ETH_ALEN);
1486 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1487 }
1488 g_key_ptk_params.key_len = params->key_len;
1489 g_key_ptk_params.seq_len = params->seq_len;
1490 g_key_ptk_params.key = WILC_MALLOC(params->key_len);
1491 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1492 if (params->seq_len > 0) {
1493 g_key_ptk_params.seq = WILC_MALLOC(params->seq_len);
1494 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1495 }
1496 g_key_ptk_params.cipher = params->cipher;
1497
1498 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1499 g_key_ptk_params.key[1],
1500 g_key_ptk_params.key[2]);
1501 g_ptk_keys_saved = WILC_TRUE;
1502 }
1503
1504 host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
1505 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1506 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1507 if (INFO) {
1508 for (i = 0; i < params->key_len; i++)
1509 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1510 }
1511 }
1512 }
1513 break;
1514
1515 default:
1516 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1517 s32Error = -ENOTSUPP;
1518
1519 }
1520
1521 return s32Error;
1522}
1523
1524/**
1525 * @brief WILC_WFI_del_key
1526 * @details Remove a key given the @mac_addr (%NULL for a group key)
1527 * and @key_index, return -ENOENT if the key doesn't exist.
1528 * @param[in]
1529 * @return int : Return 0 on Success
1530 * @author mdaftedar
1531 * @date 01 MAR 2012
1532 * @version 1.0
1533 */
1534static int WILC_WFI_del_key(struct wiphy *wiphy, struct net_device *netdev,
1535 u8 key_index,
1536 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
1537 bool pairwise,
1538 #endif
1539 const u8 *mac_addr)
1540{
1541 struct WILC_WFI_priv *priv;
1542 WILC_Sint32 s32Error = WILC_SUCCESS;
1543
1544 priv = wiphy_priv(wiphy);
1545
1546 /*BugID_5137*/
1547 /*delete saved keys, if any*/
1548 if (netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
1549 g_ptk_keys_saved = WILC_FALSE;
1550 g_gtk_keys_saved = WILC_FALSE;
1551 g_wep_keys_saved = WILC_FALSE;
1552
1553 /*Delete saved WEP keys params, if any*/
1554 if (g_key_wep_params.key != NULL) {
1555 WILC_FREE(g_key_wep_params.key);
1556 g_key_wep_params.key = NULL;
1557 }
1558
1559 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1560
1561 #ifdef WILC_AP_EXTERNAL_MLME
1562 if ((priv->wilc_gtk[key_index]) != NULL) {
1563
1564 if (priv->wilc_gtk[key_index]->key != NULL) {
1565
1566 WILC_FREE(priv->wilc_gtk[key_index]->key);
1567 priv->wilc_gtk[key_index]->key = NULL;
1568 }
1569 if (priv->wilc_gtk[key_index]->seq) {
1570
1571 WILC_FREE(priv->wilc_gtk[key_index]->seq);
1572 priv->wilc_gtk[key_index]->seq = NULL;
1573 }
1574
1575 WILC_FREE(priv->wilc_gtk[key_index]);
1576 priv->wilc_gtk[key_index] = NULL;
1577
1578 }
1579
1580 if ((priv->wilc_ptk[key_index]) != NULL) {
1581
1582 if (priv->wilc_ptk[key_index]->key) {
1583
1584 WILC_FREE(priv->wilc_ptk[key_index]->key);
1585 priv->wilc_ptk[key_index]->key = NULL;
1586 }
1587 if (priv->wilc_ptk[key_index]->seq) {
1588
1589 WILC_FREE(priv->wilc_ptk[key_index]->seq);
1590 priv->wilc_ptk[key_index]->seq = NULL;
1591 }
1592 WILC_FREE(priv->wilc_ptk[key_index]);
1593 priv->wilc_ptk[key_index] = NULL;
1594 }
1595 #endif
1596
1597 /*Delete saved PTK and GTK keys params, if any*/
1598 if (g_key_ptk_params.key != NULL) {
1599 WILC_FREE(g_key_ptk_params.key);
1600 g_key_ptk_params.key = NULL;
1601 }
1602 if (g_key_ptk_params.seq != NULL) {
1603 WILC_FREE(g_key_ptk_params.seq);
1604 g_key_ptk_params.seq = NULL;
1605 }
1606
1607 if (g_key_gtk_params.key != NULL) {
1608 WILC_FREE(g_key_gtk_params.key);
1609 g_key_gtk_params.key = NULL;
1610 }
1611 if (g_key_gtk_params.seq != NULL) {
1612 WILC_FREE(g_key_gtk_params.seq);
1613 g_key_gtk_params.seq = NULL;
1614 }
1615
1616 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
1617 Set_machw_change_vir_if(WILC_FALSE);
1618 }
1619
1620 if (key_index >= 0 && key_index <= 3) {
1621 WILC_memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
1622 priv->WILC_WFI_wep_key_len[key_index] = 0;
1623
1624 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
1625 host_int_remove_wep_key(priv->hWILCWFIDrv, key_index);
1626 } else {
1627 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
1628 host_int_remove_key(priv->hWILCWFIDrv, mac_addr);
1629 }
1630
1631 return s32Error;
1632}
1633
1634/**
1635 * @brief WILC_WFI_get_key
1636 * @details Get information about the key with the given parameters.
1637 * @mac_addr will be %NULL when requesting information for a group
1638 * key. All pointers given to the @callback function need not be valid
1639 * after it returns. This function should return an error if it is
1640 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1641 * @param[in]
1642 * @return int : Return 0 on Success
1643 * @author mdaftedar
1644 * @date 01 MAR 2012
1645 * @version 1.0
1646 */
1647static int WILC_WFI_get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1648 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
1649 bool pairwise,
1650 #endif
1651 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1652{
1653
1654 WILC_Sint32 s32Error = WILC_SUCCESS;
1655
1656 struct WILC_WFI_priv *priv;
1657 struct key_params key_params;
1658 WILC_Uint32 i;
1659 priv = wiphy_priv(wiphy);
1660
1661
1662 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
1663 if (!pairwise)
1664 #else
1665 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1666 #endif
1667 {
1668 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1669
1670 key_params.key = priv->wilc_gtk[key_index]->key;
1671 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1672 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1673 key_params.seq = priv->wilc_gtk[key_index]->seq;
1674 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1675 if (INFO) {
1676 for (i = 0; i < key_params.key_len; i++)
1677 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1678 }
1679 } else {
1680 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1681
1682 key_params.key = priv->wilc_ptk[key_index]->key;
1683 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1684 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1685 key_params.seq = priv->wilc_ptk[key_index]->seq;
1686 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1687 }
1688
1689 callback(cookie, &key_params);
1690
1691 return s32Error; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
1692}
1693
1694/**
1695 * @brief WILC_WFI_set_default_key
1696 * @details Set the default management frame key on an interface
1697 * @param[in]
1698 * @return int : Return 0 on Success.
1699 * @author mdaftedar
1700 * @date 01 MAR 2012
1701 * @version 1.0
1702 */
1703static int WILC_WFI_set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index
1704 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37)
1705 , bool unicast, bool multicast
1706 #endif
1707 )
1708{
1709 WILC_Sint32 s32Error = WILC_SUCCESS;
1710 struct WILC_WFI_priv *priv;
1711
1712
1713 priv = wiphy_priv(wiphy);
1714
1715 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d \n", key_index);
1716
1717 if (key_index != priv->WILC_WFI_wep_default) {
1718
1719 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, key_index);
1720 }
1721
1722 return s32Error;
1723}
1724
1725/**
1726 * @brief WILC_WFI_dump_survey
1727 * @details Get site survey information
1728 * @param[in]
1729 * @return int : Return 0 on Success.
1730 * @author mdaftedar
1731 * @date 01 MAR 2012
1732 * @version 1.0
1733 */
1734static int WILC_WFI_dump_survey(struct wiphy *wiphy, struct net_device *netdev,
1735 int idx, struct survey_info *info)
1736{
1737 WILC_Sint32 s32Error = WILC_SUCCESS;
1738
1739
1740 if (idx != 0) {
1741 s32Error = -ENOENT;
1742 PRINT_ER("Error Idx value doesn't equal zero: Error(%d)\n", s32Error);
1743
1744 }
1745
1746 return s32Error;
1747}
1748
1749
1750/**
1751 * @brief WILC_WFI_get_station
1752 * @details Get station information for the station identified by @mac
1753 * @param[in] NONE
1754 * @return int : Return 0 on Success.
1755 * @author mdaftedar
1756 * @date 01 MAR 2012
1757 * @version 1.0
1758 */
1759
1760extern uint32_t Statisitcs_totalAcks, Statisitcs_DroppedAcks;
1761static int WILC_WFI_get_station(struct wiphy *wiphy, struct net_device *dev,
1762 u8 *mac, struct station_info *sinfo)
1763{
1764 WILC_Sint32 s32Error = WILC_SUCCESS;
1765 struct WILC_WFI_priv *priv;
1766 perInterface_wlan_t *nic;
1767 #ifdef WILC_AP_EXTERNAL_MLME
1768 WILC_Uint32 i = 0;
1769 WILC_Uint32 associatedsta = 0;
1770 WILC_Uint32 inactive_time = 0;
1771 #endif
1772 priv = wiphy_priv(wiphy);
1773 nic = netdev_priv(dev);
1774
1775 #ifdef WILC_AP_EXTERNAL_MLME
1776 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1777 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1778
1779 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1780
1781 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1782
1783 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1784 associatedsta = i;
1785 break;
1786 }
1787
1788 }
1789
1790 if (associatedsta == -1) {
1791 s32Error = -ENOENT;
1792 PRINT_ER("Station required is not associated : Error(%d)\n", s32Error);
1793
1794 return s32Error;
1795 }
1796
1797#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) //0421
1798 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1799#else
1800 sinfo->filled |= STATION_INFO_INACTIVE_TIME;
1801#endif
1802
1803 host_int_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
1804 sinfo->inactive_time = 1000 * inactive_time;
1805 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1806
1807 }
1808 #endif
1809
1810 if (nic->iftype == STATION_MODE) {
1811 tstrStatistics strStatistics;
1812 host_int_get_statistics(priv->hWILCWFIDrv, &strStatistics);
1813
1814 /*
1815 * tony: 2013-11-13
1816 * tx_failed introduced more than
1817 * kernel version 3.0.0
1818 */
1819 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) //0421
1820 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1821 BIT( NL80211_STA_INFO_RX_PACKETS) |
1822 BIT(NL80211_STA_INFO_TX_PACKETS) |
1823 BIT(NL80211_STA_INFO_TX_FAILED) |
1824 BIT(NL80211_STA_INFO_TX_BITRATE);
1825 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
1826 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS
1827 | STATION_INFO_TX_FAILED | STATION_INFO_TX_BITRATE;
1828 #else
1829 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS
1830 | STATION_INFO_TX_BITRATE;
1831 #endif
1832
1833 sinfo->signal = strStatistics.s8RSSI;
1834 sinfo->rx_packets = strStatistics.u32RxCount;
1835 sinfo->tx_packets = strStatistics.u32TxCount + strStatistics.u32TxFailureCount;
1836 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
1837 sinfo->tx_failed = strStatistics.u32TxFailureCount;
1838 #endif
1839 sinfo->txrate.legacy = strStatistics.u8LinkSpeed * 10;
1840
1841#ifdef TCP_ENHANCEMENTS
1842 if ((strStatistics.u8LinkSpeed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED)) {
1843 Enable_TCP_ACK_Filter(WILC_TRUE);
1844 } else if (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED) {
1845 Enable_TCP_ACK_Filter(WILC_FALSE);
1846 }
1847#endif
1848
1849 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
1850 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1851 sinfo->tx_failed, sinfo->txrate.legacy);
1852 #else
1853 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1854 sinfo->txrate.legacy);
1855 #endif
1856 }
1857 return s32Error;
1858}
1859
1860
1861/**
1862 * @brief WILC_WFI_change_bss
1863 * @details Modify parameters for a given BSS.
1864 * @param[in]
1865 * -use_cts_prot: Whether to use CTS protection
1866 * (0 = no, 1 = yes, -1 = do not change)
1867 * -use_short_preamble: Whether the use of short preambles is allowed
1868 * (0 = no, 1 = yes, -1 = do not change)
1869 * -use_short_slot_time: Whether the use of short slot time is allowed
1870 * (0 = no, 1 = yes, -1 = do not change)
1871 * -basic_rates: basic rates in IEEE 802.11 format
1872 * (or NULL for no change)
1873 * -basic_rates_len: number of basic rates
1874 * -ap_isolate: do not forward packets between connected stations
1875 * -ht_opmode: HT Operation mode
1876 * (u16 = opmode, -1 = do not change)
1877 * @return int : Return 0 on Success.
1878 * @author mdaftedar
1879 * @date 01 MAR 2012
1880 * @version 1.0
1881 */
1882static int WILC_WFI_change_bss(struct wiphy *wiphy, struct net_device *dev,
1883 struct bss_parameters *params)
1884{
1885 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1886 return 0;
1887}
1888
1889/**
1890 * @brief WILC_WFI_auth
1891 * @details Request to authenticate with the specified peer
1892 * @param[in]
1893 * @return int : Return 0 on Success.
1894 * @author mdaftedar
1895 * @date 01 MAR 2012
1896 * @version 1.0
1897 */
1898static int WILC_WFI_auth(struct wiphy *wiphy, struct net_device *dev,
1899 struct cfg80211_auth_request *req)
1900{
1901 PRINT_D(CFG80211_DBG, "In Authentication Function\n");
1902 return 0;
1903}
1904
1905/**
1906 * @brief WILC_WFI_assoc
1907 * @details Request to (re)associate with the specified peer
1908 * @param[in]
1909 * @return int : Return 0 on Success.
1910 * @author mdaftedar
1911 * @date 01 MAR 2012
1912 * @version 1.0
1913 */
1914static int WILC_WFI_assoc(struct wiphy *wiphy, struct net_device *dev,
1915 struct cfg80211_assoc_request *req)
1916{
1917 PRINT_D(CFG80211_DBG, "In Association Function\n");
1918 return 0;
1919}
1920
1921/**
1922 * @brief WILC_WFI_deauth
1923 * @details Request to deauthenticate from the specified peer
1924 * @param[in]
1925 * @return int : Return 0 on Success.
1926 * @author mdaftedar
1927 * @date 01 MAR 2012
1928 * @version 1.0
1929 */
1930static int WILC_WFI_deauth(struct wiphy *wiphy, struct net_device *dev,
1931 struct cfg80211_deauth_request *req, void *cookie)
1932{
1933 PRINT_D(CFG80211_DBG, "In De-authentication Function\n");
1934 return 0;
1935}
1936
1937/**
1938 * @brief WILC_WFI_disassoc
1939 * @details Request to disassociate from the specified peer
1940 * @param[in]
1941 * @return int : Return 0 on Success
1942 * @author mdaftedar
1943 * @date 01 MAR 2012
1944 * @version 1.0
1945 */
1946static int WILC_WFI_disassoc(struct wiphy *wiphy, struct net_device *dev,
1947 struct cfg80211_disassoc_request *req, void *cookie)
1948{
1949 PRINT_D(CFG80211_DBG, "In Disassociation Function\n");
1950 return 0;
1951}
1952
1953/**
1954 * @brief WILC_WFI_set_wiphy_params
1955 * @details Notify that wiphy parameters have changed;
1956 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1957 * have changed.
1958 * @return int : Return 0 on Success
1959 * @author mdaftedar
1960 * @date 01 MAR 2012
1961 * @version 1.0
1962 */
1963static int WILC_WFI_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1964{
1965 WILC_Sint32 s32Error = WILC_SUCCESS;
1966 tstrCfgParamVal pstrCfgParamVal;
1967 struct WILC_WFI_priv *priv;
1968
1969 priv = wiphy_priv(wiphy);
1970/* priv = netdev_priv(priv->wdev->netdev); */
1971
1972 pstrCfgParamVal.u32SetCfgFlag = 0;
1973 PRINT_D(CFG80211_DBG, "Setting Wiphy params \n");
1974
1975 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1976 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1977 priv->dev->ieee80211_ptr->wiphy->retry_short);
1978 pstrCfgParamVal.u32SetCfgFlag |= RETRY_SHORT;
1979 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1980 }
1981 if (changed & WIPHY_PARAM_RETRY_LONG) {
1982
1983 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
1984 pstrCfgParamVal.u32SetCfgFlag |= RETRY_LONG;
1985 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1986
1987 }
1988 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1989 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
1990 pstrCfgParamVal.u32SetCfgFlag |= FRAG_THRESHOLD;
1991 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1992
1993 }
1994
1995 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1996 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1997
1998 pstrCfgParamVal.u32SetCfgFlag |= RTS_THRESHOLD;
1999 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
2000
2001 }
2002
2003 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
2004 s32Error = hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
2005 if (s32Error)
2006 PRINT_ER("Error in setting WIPHY PARAMS\n");
2007
2008
2009 return s32Error;
2010}
2011#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32)
2012/**
2013 * @brief WILC_WFI_set_bitrate_mask
2014 * @details set the bitrate mask configuration
2015 * @param[in]
2016 * @return int : Return 0 on Success
2017 * @author mdaftedar
2018 * @date 01 MAR 2012
2019 * @version 1.0
2020 */
2021static int WILC_WFI_set_bitrate_mask(struct wiphy *wiphy,
2022 struct net_device *dev, const u8 *peer,
2023 const struct cfg80211_bitrate_mask *mask)
2024{
2025 WILC_Sint32 s32Error = WILC_SUCCESS;
2026 /* strCfgParamVal pstrCfgParamVal; */
2027 /* struct WILC_WFI_priv* priv; */
2028
2029 PRINT_D(CFG80211_DBG, "Setting Bitrate mask function\n");
2030#if 0
2031 priv = wiphy_priv(wiphy);
2032 /* priv = netdev_priv(priv->wdev->netdev); */
2033
2034 pstrCfgParamVal.curr_tx_rate = mask->control[IEEE80211_BAND_2GHZ].legacy;
2035
2036 PRINT_D(CFG80211_DBG, "Tx rate = %d\n", pstrCfgParamVal.curr_tx_rate);
2037 s32Error = hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
2038
2039 if (s32Error)
2040 PRINT_ER("Error in setting bitrate\n");
2041#endif
2042 return s32Error;
2043
2044}
2045
2046/**
2047 * @brief WILC_WFI_set_pmksa
2048 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
2049 * devices running firmwares capable of generating the (re) association
2050 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
2051 * @param[in]
2052 * @return int : Return 0 on Success
2053 * @author mdaftedar
2054 * @date 01 MAR 2012
2055 * @version 1.0
2056 */
2057static int WILC_WFI_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
2058 struct cfg80211_pmksa *pmksa)
2059{
2060 WILC_Uint32 i;
2061 WILC_Sint32 s32Error = WILC_SUCCESS;
2062 WILC_Uint8 flag = 0;
2063
2064 struct WILC_WFI_priv *priv = wiphy_priv(wiphy);
2065
2066 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
2067
2068
2069 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
2070 if (!WILC_memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
2071 ETH_ALEN)) {
2072 /*If bssid already exists and pmkid value needs to reset*/
2073 flag = PMKID_FOUND;
2074 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
2075 break;
2076 }
2077 }
2078 if (i < WILC_MAX_NUM_PMKIDS) {
2079 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
2080 WILC_memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
2081 ETH_ALEN);
2082 WILC_memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
2083 PMKID_LEN);
2084 if (!(flag == PMKID_FOUND))
2085 priv->pmkid_list.numpmkid++;
2086 } else {
2087 PRINT_ER("Invalid PMKID index\n");
2088 s32Error = -EINVAL;
2089 }
2090
2091 if (!s32Error) {
2092 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
2093 s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
2094 }
2095 return s32Error;
2096}
2097
2098/**
2099 * @brief WILC_WFI_del_pmksa
2100 * @details Delete a cached PMKID.
2101 * @param[in]
2102 * @return int : Return 0 on Success
2103 * @author mdaftedar
2104 * @date 01 MAR 2012
2105 * @version 1.0
2106 */
2107static int WILC_WFI_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
2108 struct cfg80211_pmksa *pmksa)
2109{
2110
2111 WILC_Uint32 i;
2112 WILC_Uint8 flag = 0;
2113 WILC_Sint32 s32Error = WILC_SUCCESS;
2114
2115 struct WILC_WFI_priv *priv = wiphy_priv(wiphy);
2116 /* priv = netdev_priv(priv->wdev->netdev); */
2117
2118 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
2119
2120 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
2121 if (!WILC_memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
2122 ETH_ALEN)) {
2123 /*If bssid is found, reset the values*/
2124 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
2125 WILC_memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(tstrHostIFpmkid));
2126 flag = PMKID_FOUND;
2127 break;
2128 }
2129 }
2130
2131 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
2132 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
2133 WILC_memcpy(priv->pmkid_list.pmkidlist[i].bssid,
2134 priv->pmkid_list.pmkidlist[i + 1].bssid,
2135 ETH_ALEN);
2136 WILC_memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
2137 priv->pmkid_list.pmkidlist[i].pmkid,
2138 PMKID_LEN);
2139 }
2140 priv->pmkid_list.numpmkid--;
2141 } else {
2142 s32Error = -EINVAL;
2143 }
2144
2145 return s32Error;
2146}
2147
2148/**
2149 * @brief WILC_WFI_flush_pmksa
2150 * @details Flush all cached PMKIDs.
2151 * @param[in]
2152 * @return int : Return 0 on Success
2153 * @author mdaftedar
2154 * @date 01 MAR 2012
2155 * @version 1.0
2156 */
2157static int WILC_WFI_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
2158{
2159 struct WILC_WFI_priv *priv = wiphy_priv(wiphy);
2160 /* priv = netdev_priv(priv->wdev->netdev); */
2161
2162 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
2163
2164 /*Get cashed Pmkids and set all with zeros*/
2165 WILC_memset(&priv->pmkid_list, 0, sizeof(tstrHostIFpmkidAttr));
2166
2167 return 0;
2168}
2169#endif
2170
2171#ifdef WILC_P2P
2172
2173/**
2174 * @brief WILC_WFI_CfgParseRxAction
2175 * @details Function parses the received frames and modifies the following attributes:
2176 * -GO Intent
2177 * -Channel list
2178 * -Operating Channel
2179 *
2180 * @param[in] u8* Buffer, u32 length
2181 * @return NONE.
2182 * @author mdaftedar
2183 * @date 12 DEC 2012
2184 * @version
2185 */
2186
2187void WILC_WFI_CfgParseRxAction(WILC_Uint8 *buf, WILC_Uint32 len)
2188{
2189 WILC_Uint32 index = 0;
2190 WILC_Uint32 i = 0, j = 0;
2191
2192 /*BugID_5460*/
2193 #ifdef USE_SUPPLICANT_GO_INTENT
2194 WILC_Uint8 intent;
2195 WILC_Uint8 tie_breaker;
2196 WILC_Bool is_wilc_go = WILC_TRUE;
2197 #endif
2198 WILC_Uint8 op_channel_attr_index = 0;
2199 WILC_Uint8 channel_list_attr_index = 0;
2200
2201 while (index < len) {
2202 if (buf[index] == GO_INTENT_ATTR_ID) {
2203 #ifdef USE_SUPPLICANT_GO_INTENT
2204 /*BugID_5460*/
2205 /*Case 1: If we are going to be p2p client, no need to modify channels attributes*/
2206 /*In negotiation frames, go intent attr value determines who will be GO*/
2207 intent = GET_GO_INTENT(buf[index + 3]);
2208 tie_breaker = GET_TIE_BREAKER(buf[index + 3]);
2209 if (intent > SUPPLICANT_GO_INTENT
2210 || (intent == SUPPLICANT_GO_INTENT && tie_breaker == 1)) {
2211 PRINT_D(GENERIC_DBG, "WILC will be client (intent %d tie breaker %d)\n", intent, tie_breaker);
2212 is_wilc_go = WILC_FALSE;
2213 } else {
2214 PRINT_D(GENERIC_DBG, "WILC will be GO (intent %d tie breaker %d)\n", intent, tie_breaker);
2215 is_wilc_go = WILC_TRUE;
2216 }
2217
2218 #else /* USE_SUPPLICANT_GO_INTENT */
2219 #ifdef FORCE_P2P_CLIENT
2220 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
2221 #else
2222 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
2223 #endif
2224 #endif /* USE_SUPPLICANT_GO_INTENT */
2225 }
2226
2227 #ifdef USE_SUPPLICANT_GO_INTENT
2228 /*Case 2: If group bssid attribute is present, no need to modify channels attributes*/
2229 /*In invitation req and rsp, group bssid attr presence determines who will be GO*/
2230 if (buf[index] == GROUP_BSSID_ATTR_ID) {
2231 PRINT_D(GENERIC_DBG, "Group BSSID: %2x:%2x:%2x\n", buf[index + 3]
2232 , buf[index + 4]
2233 , buf[index + 5]);
2234 is_wilc_go = WILC_FALSE;
2235 }
2236 #endif /* USE_SUPPLICANT_GO_INTENT */
2237
2238 if (buf[index] == CHANLIST_ATTR_ID) {
2239 channel_list_attr_index = index;
2240 } else if (buf[index] == OPERCHAN_ATTR_ID) {
2241 op_channel_attr_index = index;
2242 }
2243 index += buf[index + 1] + 3; /* ID,Length byte */
2244 }
2245
2246 #ifdef USE_SUPPLICANT_GO_INTENT
2247 if (u8WLANChannel != INVALID_CHANNEL && is_wilc_go)
2248 #else
2249 if (u8WLANChannel != INVALID_CHANNEL)
2250 #endif
2251 {
2252 /*Modify channel list attribute*/
2253 if (channel_list_attr_index) {
2254 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
2255 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
2256 if (buf[i] == 0x51) {
2257 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
2258 buf[j] = u8WLANChannel;
2259 }
2260 break;
2261 }
2262 }
2263 }
2264 /*Modify operating channel attribute*/
2265 if (op_channel_attr_index) {
2266 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
2267 buf[op_channel_attr_index + 6] = 0x51;
2268 buf[op_channel_attr_index + 7] = u8WLANChannel;
2269 }
2270 }
2271}
2272
2273/**
2274 * @brief WILC_WFI_CfgParseTxAction
2275 * @details Function parses the transmitted action frames and modifies the
2276 * GO Intent attribute
2277 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
2278 * @return NONE.
2279 * @author mdaftedar
2280 * @date 12 DEC 2012
2281 * @version
2282 */
2283void WILC_WFI_CfgParseTxAction(WILC_Uint8 *buf, WILC_Uint32 len, WILC_Bool bOperChan, WILC_Uint8 iftype)
2284{
2285 WILC_Uint32 index = 0;
2286 WILC_Uint32 i = 0, j = 0;
2287
2288 WILC_Uint8 op_channel_attr_index = 0;
2289 WILC_Uint8 channel_list_attr_index = 0;
2290 #ifdef USE_SUPPLICANT_GO_INTENT
2291 WILC_Bool is_wilc_go = WILC_FALSE;
2292
2293 /*BugID_5460*/
2294 /*Case 1: If we are already p2p client, no need to modify channels attributes*/
2295 /*This to handle the case of inviting a p2p peer to join an existing group which we are a member in*/
2296 if (iftype == CLIENT_MODE)
2297 return;
2298 #endif
2299
2300 while (index < len) {
2301 #ifdef USE_SUPPLICANT_GO_INTENT
2302 /*Case 2: If group bssid attribute is present, no need to modify channels attributes*/
2303 /*In invitation req and rsp, group bssid attr presence determines who will be GO*/
2304 /*Note: If we are already p2p client, group bssid attr may also be present (handled in Case 1)*/
2305 if (buf[index] == GROUP_BSSID_ATTR_ID) {
2306 PRINT_D(GENERIC_DBG, "Group BSSID: %2x:%2x:%2x\n", buf[index + 3]
2307 , buf[index + 4]
2308 , buf[index + 5]);
2309 is_wilc_go = WILC_TRUE;
2310 }
2311
2312 #else /* USE_SUPPLICANT_GO_INTENT */
2313 if (buf[index] == GO_INTENT_ATTR_ID) {
2314 #ifdef FORCE_P2P_CLIENT
2315 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
2316 #else
2317 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
2318 #endif
2319
2320 break;
2321 }
2322 #endif
2323
2324 if (buf[index] == CHANLIST_ATTR_ID) {
2325 channel_list_attr_index = index;
2326 } else if (buf[index] == OPERCHAN_ATTR_ID) {
2327 op_channel_attr_index = index;
2328 }
2329 index += buf[index + 1] + 3; /* ID,Length byte */
2330 }
2331
2332 #ifdef USE_SUPPLICANT_GO_INTENT
2333 /*No need to check bOperChan since only transmitted invitation frames are parsed*/
2334 if (u8WLANChannel != INVALID_CHANNEL && is_wilc_go)
2335 #else
2336 if (u8WLANChannel != INVALID_CHANNEL && bOperChan)
2337 #endif
2338 {
2339 /*Modify channel list attribute*/
2340 if (channel_list_attr_index) {
2341 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
2342 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
2343 if (buf[i] == 0x51) {
2344 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
2345 buf[j] = u8WLANChannel;
2346 }
2347 break;
2348 }
2349 }
2350 }
2351 /*Modify operating channel attribute*/
2352 if (op_channel_attr_index) {
2353 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
2354 buf[op_channel_attr_index + 6] = 0x51;
2355 buf[op_channel_attr_index + 7] = u8WLANChannel;
2356 }
2357 }
2358}
2359
2360/* @brief WILC_WFI_p2p_rx
2361 * @details
2362 * @param[in]
2363 *
2364 * @return None
2365 * @author Mai Daftedar
2366 * @date 2 JUN 2013
2367 * @version 1.0
2368 */
2369
2370void WILC_WFI_p2p_rx (struct net_device *dev, uint8_t *buff, uint32_t size)
2371{
2372
2373 struct WILC_WFI_priv *priv;
2374 WILC_Uint32 header, pkt_offset;
2375 tstrWILC_WFIDrv *pstrWFIDrv;
2376 WILC_Uint32 i = 0;
2377 WILC_Sint32 s32Freq;
2378 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
2379 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2380
2381 /* Get WILC header */
2382 WILC_memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
2383
2384 /* The packet offset field conain info about what type of managment frame */
2385 /* we are dealing with and ack status */
2386 pkt_offset = GET_PKT_OFFSET(header);
2387
2388 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
2389 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
2390 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
2391 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
2392 cfg80211_mgmt_tx_status(dev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
2393 #else
2394 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
2395 #endif
2396 return;
2397 } else {
2398 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
2399 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],
2400 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
2401 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
2402 cfg80211_mgmt_tx_status(dev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
2403 #else
2404 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
2405 #endif
2406 } else {
2407 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],
2408 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
2409 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
2410 cfg80211_mgmt_tx_status(dev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
2411 #else
2412 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
2413 #endif
2414 }
2415 return;
2416 }
2417 } else {
2418
2419 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
2420
2421 /*BugID_5442*/
2422 /*Upper layer is informed that the frame is received on this freq*/
2423 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
2424 s32Freq = ieee80211_channel_to_frequency(u8CurrChannel, IEEE80211_BAND_2GHZ);
2425 #else
2426 s32Freq = ieee80211_channel_to_frequency(u8CurrChannel);
2427 #endif
2428
2429 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
2430 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
2431
2432 if (priv->bCfgScanning == WILC_TRUE && jiffies >= pstrWFIDrv->u64P2p_MgmtTimeout) {
2433 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
2434 return;
2435 }
2436 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2437
2438 switch (buff[ACTION_SUBTYPE_ID]) {
2439 case GAS_INTIAL_REQ:
2440 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
2441 break;
2442
2443 case GAS_INTIAL_RSP:
2444 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
2445 break;
2446
2447 case PUBLIC_ACT_VENDORSPEC:
2448 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2449 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
2450 if (!WILC_memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
2451 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2452 if (!bWilc_ie) {
2453 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
2454 if (!WILC_memcmp(u8P2P_vendorspec, &buff[i], 6)) {
2455 u8P2Precvrandom = buff[i + 6];
2456 bWilc_ie = WILC_TRUE;
2457 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
2458 break;
2459 }
2460 }
2461 }
2462 }
2463 if (u8P2Plocalrandom > u8P2Precvrandom) {
2464 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2465 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2466 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
2467 if (buff[i] == P2PELEM_ATTR_ID && !(WILC_memcmp(u8P2P_oui, &buff[i + 2], 4))) {
2468 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2469 break;
2470 }
2471 }
2472 }
2473 } else
2474 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2475 }
2476
2477
2478 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2479 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2480 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
2481 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2482 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
2483 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
2484 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0, GFP_ATOMIC);
2485 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2486 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, GFP_ATOMIC);
2487 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
2488 cfg80211_rx_mgmt(dev, s32Freq, 0, buff, size - 7, GFP_ATOMIC); /* rachel */
2489 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
2490 cfg80211_rx_mgmt(dev, s32Freq, buff, size - 7, GFP_ATOMIC);
2491 #endif
2492
2493 return;
2494 }
2495 break;
2496
2497 default:
2498 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2499 break;
2500 }
2501 }
2502 }
2503
2504 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2505 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
2506 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
2507 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0, GFP_ATOMIC);
2508 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2509 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, GFP_ATOMIC);
2510 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
2511 cfg80211_rx_mgmt(dev, s32Freq, 0, buff, size, GFP_ATOMIC);
2512 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
2513 cfg80211_rx_mgmt(dev, s32Freq, buff, size, GFP_ATOMIC);
2514 #endif
2515 }
2516}
2517
2518/**
2519 * @brief WILC_WFI_mgmt_tx_complete
2520 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2521 * @param[in] priv
2522 * transmitting status
2523 * @return None
2524 * @author Amr Abdelmoghny
2525 * @date 20 MAY 2013
2526 * @version 1.0
2527 */
2528static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2529{
2530 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2531
2532
2533 kfree(pv_data->buff);
2534 kfree(pv_data);
2535}
2536
2537/**
2538 * @brief WILC_WFI_RemainOnChannelReady
2539 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2540 * @param
2541 * @return none
2542 * @author Amr abdelmoghny
2543 * @date 9 JUNE 2013
2544 * @version
2545 */
2546
2547static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2548{
2549 struct WILC_WFI_priv *priv;
2550 priv = (struct WILC_WFI_priv *)pUserVoid;
2551
2552 PRINT_D(HOSTINF_DBG, "Remain on channel ready \n");
2553
2554 priv->bInP2PlistenState = WILC_TRUE;
2555
2556#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
2557 cfg80211_ready_on_channel(priv->wdev,
2558 priv->strRemainOnChanParams.u64ListenCookie,
2559 priv->strRemainOnChanParams.pstrListenChan,
2560 priv->strRemainOnChanParams.u32ListenDuration,
2561 GFP_KERNEL);
2562#else
2563 cfg80211_ready_on_channel(priv->dev,
2564 priv->strRemainOnChanParams.u64ListenCookie,
2565 priv->strRemainOnChanParams.pstrListenChan,
2566 priv->strRemainOnChanParams.tenuChannelType,
2567 priv->strRemainOnChanParams.u32ListenDuration,
2568 GFP_KERNEL);
2569#endif
2570}
2571
2572/**
2573 * @brief WILC_WFI_RemainOnChannelExpired
2574 * @details Callback function, called on expiration of remain-on-channel duration
2575 * @param
2576 * @return none
2577 * @author Amr abdelmoghny
2578 * @date 15 MAY 2013
2579 * @version
2580 */
2581
2582static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, WILC_Uint32 u32SessionID)
2583{
2584 struct WILC_WFI_priv *priv;
2585 priv = (struct WILC_WFI_priv *)pUserVoid;
2586
2587 /*BugID_5477*/
2588 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
2589 PRINT_D(GENERIC_DBG, "Remain on channel expired \n");
2590
2591 priv->bInP2PlistenState = WILC_FALSE;
2592
2593 /*Inform wpas of remain-on-channel expiration*/
2594 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
2595 cfg80211_remain_on_channel_expired(priv->wdev,
2596 priv->strRemainOnChanParams.u64ListenCookie,
2597 priv->strRemainOnChanParams.pstrListenChan,
2598 GFP_KERNEL);
2599 #else
2600 cfg80211_remain_on_channel_expired(priv->dev,
2601 priv->strRemainOnChanParams.u64ListenCookie,
2602 priv->strRemainOnChanParams.pstrListenChan,
2603 priv->strRemainOnChanParams.tenuChannelType,
2604 GFP_KERNEL);
2605 #endif
2606 } else {
2607 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2608 , priv->strRemainOnChanParams.u32ListenSessionID);
2609 }
2610}
2611
2612
2613/**
2614 * @brief WILC_WFI_remain_on_channel
2615 * @details Request the driver to remain awake on the specified
2616 * channel for the specified duration to complete an off-channel
2617 * operation (e.g., public action frame exchange). When the driver is
2618 * ready on the requested channel, it must indicate this with an event
2619 * notification by calling cfg80211_ready_on_channel().
2620 * @param[in]
2621 * @return int : Return 0 on Success
2622 * @author mdaftedar
2623 * @date 01 MAR 2012
2624 * @version 1.0
2625 */
2626static int WILC_WFI_remain_on_channel(struct wiphy *wiphy,
2627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2628 struct wireless_dev *wdev,
2629#else
2630 struct net_device *dev,
2631#endif
2632 struct ieee80211_channel *chan,
2633#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
2634 enum nl80211_channel_type channel_type,
2635#endif
2636 unsigned int duration, u64 *cookie)
2637{
2638 WILC_Sint32 s32Error = WILC_SUCCESS;
2639 struct WILC_WFI_priv *priv;
2640 priv = wiphy_priv(wiphy);
2641
2642 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2643
2644 /*BugID_4800: if in AP mode, return.*/
2645 /*This check is to handle the situation when user*/
2646 /*requests "create group" during a running scan*/
2647
2648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2649 if (wdev->iftype == NL80211_IFTYPE_AP) {
2650 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2651 return s32Error;
2652 }
2653#else
2654 if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) {
2655 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2656 return s32Error;
2657 }
2658#endif
2659
2660 u8CurrChannel = chan->hw_value;
2661
2662 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2663 priv->strRemainOnChanParams.pstrListenChan = chan;
2664 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
2665 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
2666 priv->strRemainOnChanParams.tenuChannelType = channel_type;
2667 #endif
2668 priv->strRemainOnChanParams.u32ListenDuration = duration;
2669 priv->strRemainOnChanParams.u32ListenSessionID++;
2670
2671 s32Error = host_int_remain_on_channel(priv->hWILCWFIDrv
2672 , priv->strRemainOnChanParams.u32ListenSessionID
2673 , duration
2674 , chan->hw_value
2675 , WILC_WFI_RemainOnChannelExpired
2676 , WILC_WFI_RemainOnChannelReady
2677 , (void *)priv);
2678
2679 return s32Error;
2680}
2681
2682/**
2683 * @brief WILC_WFI_cancel_remain_on_channel
2684 * @details Cancel an on-going remain-on-channel operation.
2685 * This allows the operation to be terminated prior to timeout based on
2686 * the duration value.
2687 * @param[in] struct wiphy *wiphy,
2688 * @param[in] struct net_device *dev
2689 * @param[in] u64 cookie,
2690 * @return int : Return 0 on Success
2691 * @author mdaftedar
2692 * @date 01 MAR 2012
2693 * @version 1.0
2694 */
2695static int WILC_WFI_cancel_remain_on_channel(struct wiphy *wiphy,
2696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2697 struct wireless_dev *wdev,
2698#else
2699 struct net_device *dev,
2700#endif
2701 u64 cookie)
2702{
2703 WILC_Sint32 s32Error = WILC_SUCCESS;
2704 struct WILC_WFI_priv *priv;
2705 priv = wiphy_priv(wiphy);
2706
2707 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2708
2709 s32Error = host_int_ListenStateExpired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
2710 return s32Error;
2711}
2712/**
2713 * @brief WILC_WFI_add_wilcvendorspec
2714 * @details Adding WILC information elemet to allow two WILC devices to
2715 * identify each other and connect
2716 * @param[in] WILC_Uint8 * buf
2717 * @return void
2718 * @author mdaftedar
2719 * @date 01 JAN 2014
2720 * @version 1.0
2721 */
2722void WILC_WFI_add_wilcvendorspec(WILC_Uint8 *buff)
2723{
2724 WILC_memcpy(buff, u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
2725}
2726/**
2727 * @brief WILC_WFI_mgmt_tx_frame
2728 * @details
2729 *
2730 * @param[in]
2731 * @return NONE.
2732 * @author mdaftedar
2733 * @date 01 JUL 2012
2734 * @version
2735 */
2736extern linux_wlan_t *g_linux_wlan;
2737extern WILC_Bool bEnablePS;
2738int WILC_WFI_mgmt_tx(struct wiphy *wiphy,
2739#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2740 struct wireless_dev *wdev,
2741 struct cfg80211_mgmt_tx_params *params,
2742 u64 *cookie)
2743#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
2744 struct wireless_dev *wdev,
2745 struct ieee80211_channel *chan,
2746 bool offchan,
2747 unsigned int wait,
2748 const u8 *buf,
2749 size_t len,
2750 bool no_cck,
2751 bool dont_wait_for_ack, u64 *cookie)
2752#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2753 struct wireless_dev *wdev,
2754 struct ieee80211_channel *chan, bool offchan,
2755 enum nl80211_channel_type channel_type,
2756 bool channel_type valid,
2757 unsigned int wait, const u8 *buf,
2758 size_t len, bool no_cck,
2759 bool dont_wait_for_ack, u64 *cookie)
2760#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
2761 struct net_device *dev,
2762 struct ieee80211_channel *chan, bool offchan,
2763 enum nl80211_channel_type channel_type,
2764 bool channel_type_valid,
2765 unsigned int wait, const u8 *buf,
2766 size_t len, bool no_cck,
2767 bool dont_wait_for_ack, u64 *cookie)
2768#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
2769 struct net_device *dev,
2770 struct ieee80211_channel *chan, bool offchan,
2771 enum nl80211_channel_type channel_type,
2772 bool channel_type_valid,
2773 unsigned int wait, const u8 *buf,
2774 size_t len, bool no_cck, u64 *cookie)
2775#else
2776 struct net_device *dev,
2777 struct ieee80211_channel *chan, bool offchan,
2778 enum nl80211_channel_type channel_type,
2779 bool channel_type_valid,
2780 unsigned int wait, const u8 *buf,
2781 size_t len, u64 *cookie)
2782#endif
2783{
2784 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2785 struct ieee80211_channel *chan = params->chan;
2786 unsigned int wait = params->wait;
2787 const u8 *buf = params->buf;
2788 size_t len = params->len;
2789 #endif
2790 const struct ieee80211_mgmt *mgmt;
2791 struct p2p_mgmt_data *mgmt_tx;
2792 struct WILC_WFI_priv *priv;
2793 WILC_Sint32 s32Error = WILC_SUCCESS;
2794 tstrWILC_WFIDrv *pstrWFIDrv;
2795 WILC_Uint32 i;
2796 perInterface_wlan_t *nic;
2797 WILC_Uint32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
2798
2799#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2800 nic = netdev_priv(wdev->netdev);
2801#else
2802 nic = netdev_priv(dev);
2803#endif
2804 priv = wiphy_priv(wiphy);
2805 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2806
2807 *cookie = (unsigned long)buf;
2808 priv->u64tx_cookie = *cookie;
2809 mgmt = (const struct ieee80211_mgmt *) buf;
2810
2811 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2812
2813 /*mgmt frame allocation*/
2814 mgmt_tx = (struct p2p_mgmt_data *)WILC_MALLOC(sizeof(struct p2p_mgmt_data));
2815 if (mgmt_tx == NULL) {
2816 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
2817 return WILC_FAIL;
2818 }
2819 mgmt_tx->buff = (char *)WILC_MALLOC(buf_len);
2820 if (mgmt_tx->buff == NULL) {
2821 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
2822 return WILC_FAIL;
2823 }
2824 WILC_memcpy(mgmt_tx->buff, buf, len);
2825 mgmt_tx->size = len;
2826
2827
2828 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2829 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2830 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
2831 host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
2832 /*Save the current channel after we tune to it*/
2833 u8CurrChannel = chan->hw_value;
2834 } else if (ieee80211_is_action(mgmt->frame_control)) {
2835 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (WILC_Uint16)mgmt->frame_control);
2836
2837
2838 /*BugID_4847*/
2839 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2840 /*BugID_4847*/
2841 /*Only set the channel, if not a negotiation confirmation frame
2842 * (If Negotiation confirmation frame, force it
2843 * to be transmitted on the same negotiation channel)*/
2844
2845 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2846 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2847 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
2848 host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
2849 /*Save the current channel after we tune to it*/
2850 u8CurrChannel = chan->hw_value;
2851 }
2852 switch (buf[ACTION_SUBTYPE_ID]) {
2853 case GAS_INTIAL_REQ:
2854 {
2855 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2856 break;
2857 }
2858
2859 case GAS_INTIAL_RSP:
2860 {
2861 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2862 break;
2863 }
2864
2865 case PUBLIC_ACT_VENDORSPEC:
2866 {
2867 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2868 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
2869 if (!WILC_memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
2870 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2871 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2872 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2873 get_random_bytes(&u8P2Plocalrandom, 1);
2874 /*Increment the number to prevent if its 0*/
2875 u8P2Plocalrandom++;
2876 }
2877 }
2878
2879 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2880 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2881 if (u8P2Plocalrandom > u8P2Precvrandom) {
2882 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2883
2884 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2885 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
2886 if (buf[i] == P2PELEM_ATTR_ID && !(WILC_memcmp(u8P2P_oui, &buf[i + 2], 4))) {
2887 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
2888 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), WILC_TRUE, nic->iftype);
2889
2890 /*BugID_5460*/
2891 /*If using supplicant go intent, no need at all*/
2892 /*to parse transmitted negotiation frames*/
2893 #ifndef USE_SUPPLICANT_GO_INTENT
2894 else
2895 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), WILC_FALSE, nic->iftype);
2896 #endif
2897 break;
2898 }
2899 }
2900
2901 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
2902 WILC_WFI_add_wilcvendorspec(&mgmt_tx->buff[len]);
2903 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2904 mgmt_tx->size = buf_len;
2905 }
2906 } else
2907 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2908 }
2909
2910 } else {
2911 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2912 }
2913
2914 break;
2915 }
2916
2917 default:
2918 {
2919 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2920 break;
2921 }
2922 }
2923
2924 }
2925
2926 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
2927 pstrWFIDrv->u64P2p_MgmtTimeout = (jiffies + msecs_to_jiffies(wait));
2928
2929 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", jiffies, pstrWFIDrv->u64P2p_MgmtTimeout);
2930
2931 }
2932
2933 g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, WILC_WFI_mgmt_tx_complete);
2934 } else {
2935 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2936 }
2937 return s32Error;
2938}
2939
2940int WILC_WFI_mgmt_tx_cancel_wait(struct wiphy *wiphy,
2941#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
2942 struct wireless_dev *wdev,
2943#else
2944 struct net_device *dev,
2945#endif
2946 u64 cookie)
2947{
2948 struct WILC_WFI_priv *priv;
2949 tstrWILC_WFIDrv *pstrWFIDrv;
2950 priv = wiphy_priv(wiphy);
2951 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2952
2953
2954 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
2955 pstrWFIDrv->u64P2p_MgmtTimeout = jiffies;
2956
2957 if (priv->bInP2PlistenState == WILC_FALSE) {
2958 /* Bug 5504: This is just to avoid connection failure when getting stuck when the supplicant
2959 * considers the driver falsely that it is in Listen state */
2960 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
2961 cfg80211_remain_on_channel_expired(priv->wdev,
2962 priv->strRemainOnChanParams.u64ListenCookie,
2963 priv->strRemainOnChanParams.pstrListenChan,
2964 GFP_KERNEL);
2965 #else
2966 cfg80211_remain_on_channel_expired(priv->dev,
2967 priv->strRemainOnChanParams.u64ListenCookie,
2968 priv->strRemainOnChanParams.pstrListenChan,
2969 priv->strRemainOnChanParams.tenuChannelType,
2970 GFP_KERNEL);
2971 #endif
2972
2973 }
2974
2975 return 0;
2976}
2977
2978/**
2979 * @brief WILC_WFI_action
2980 * @details Transmit an action frame
2981 * @param[in]
2982 * @return int : Return 0 on Success.
2983 * @author mdaftedar
2984 * @date 01 JUL 2012
2985 * @version 1.0
2986 * */
2987#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
2988#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
2989int WILC_WFI_action(struct wiphy *wiphy, struct net_device *dev,
2990 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type,
2991 const u8 *buf, size_t len, u64 *cookie)
2992{
2993 PRINT_D(HOSTAPD_DBG, "In action function\n");
2994 return WILC_SUCCESS;
2995}
2996#endif
2997#else
2998
2999/**
3000 * @brief WILC_WFI_frame_register
3001 * @details Notify driver that a management frame type was
3002 * registered. Note that this callback may not sleep, and cannot run
3003 * concurrently with itself.
3004 * @param[in]
3005 * @return NONE.
3006 * @author mdaftedar
3007 * @date 01 JUL 2012
3008 * @version
3009 */
3010void WILC_WFI_frame_register(struct wiphy *wiphy,
3011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3012 struct wireless_dev *wdev,
3013#else
3014 struct net_device *dev,
3015#endif
3016 u16 frame_type, bool reg)
3017{
3018
3019 struct WILC_WFI_priv *priv;
3020 perInterface_wlan_t *nic;
3021
3022
3023 priv = wiphy_priv(wiphy);
3024 nic = netdev_priv(priv->wdev->netdev);
3025
3026
3027
3028 /*BugID_5137*/
3029 if (!frame_type)
3030 return;
3031
3032 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
3033 switch (frame_type) {
3034 case PROBE_REQ:
3035 {
3036 nic->g_struct_frame_reg[0].frame_type = frame_type;
3037 nic->g_struct_frame_reg[0].reg = reg;
3038 }
3039 break;
3040
3041 case ACTION:
3042 {
3043 nic->g_struct_frame_reg[1].frame_type = frame_type;
3044 nic->g_struct_frame_reg[1].reg = reg;
3045 }
3046 break;
3047
3048 default:
3049 {
3050 break;
3051 }
3052
3053 }
3054 /*If mac is closed, then return*/
3055 if (!g_linux_wlan->wilc1000_initialized) {
3056 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
3057 return;
3058 }
3059 host_int_frame_register(priv->hWILCWFIDrv, frame_type, reg);
3060
3061
3062}
3063#endif
3064#endif /*WILC_P2P*/
3065
3066/**
3067 * @brief WILC_WFI_set_cqm_rssi_config
3068 * @details Configure connection quality monitor RSSI threshold.
3069 * @param[in] struct wiphy *wiphy:
3070 * @param[in] struct net_device *dev:
3071 * @param[in] s32 rssi_thold:
3072 * @param[in] u32 rssi_hyst:
3073 * @return int : Return 0 on Success
3074 * @author mdaftedar
3075 * @date 01 MAR 2012
3076 * @version 1.0
3077 */
3078static int WILC_WFI_set_cqm_rssi_config(struct wiphy *wiphy,
3079 struct net_device *dev, s32 rssi_thold, u32 rssi_hyst)
3080{
3081 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
3082 return 0;
3083
3084}
3085/**
3086 * @brief WILC_WFI_dump_station
3087 * @details Configure connection quality monitor RSSI threshold.
3088 * @param[in] struct wiphy *wiphy:
3089 * @param[in] struct net_device *dev
3090 * @param[in] int idx
3091 * @param[in] u8 *mac
3092 * @param[in] struct station_info *sinfo
3093 * @return int : Return 0 on Success
3094 * @author mdaftedar
3095 * @date 01 MAR 2012
3096 * @version 1.0
3097 */
3098static int WILC_WFI_dump_station(struct wiphy *wiphy, struct net_device *dev,
3099 int idx, u8 *mac, struct station_info *sinfo)
3100{
3101 struct WILC_WFI_priv *priv;
3102 PRINT_D(CFG80211_DBG, "Dumping station information\n");
3103
3104 if (idx != 0)
3105 return -ENOENT;
3106
3107 priv = wiphy_priv(wiphy);
3108 /* priv = netdev_priv(priv->wdev->netdev); */
3109
3110#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) //0421
3111 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
3112#else
3113 sinfo->filled |= STATION_INFO_SIGNAL;
3114#endif
3115
3116 host_int_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
3117
3118#if 0
3119 sinfo->filled |= STATION_INFO_TX_BYTES |
3120 STATION_INFO_TX_PACKETS |
3121 STATION_INFO_RX_BYTES |
3122 STATION_INFO_RX_PACKETS | STATION_INFO_SIGNAL | STATION_INFO_INACTIVE_TIME;
3123
3124 WILC_SemaphoreAcquire(&SemHandleUpdateStats, NULL);
3125 sinfo->inactive_time = priv->netstats.rx_time > priv->netstats.tx_time ? jiffies_to_msecs(jiffies - priv->netstats.tx_time) : jiffies_to_msecs(jiffies - priv->netstats.rx_time);
3126 sinfo->rx_bytes = priv->netstats.rx_bytes;
3127 sinfo->tx_bytes = priv->netstats.tx_bytes;
3128 sinfo->rx_packets = priv->netstats.rx_packets;
3129 sinfo->tx_packets = priv->netstats.tx_packets;
3130 WILC_SemaphoreRelease(&SemHandleUpdateStats, NULL);
3131#endif
3132 return 0;
3133
3134}
3135
3136
3137/**
3138 * @brief WILC_WFI_set_power_mgmt
3139 * @details
3140 * @param[in]
3141 * @return int : Return 0 on Success.
3142 * @author mdaftedar
3143 * @date 01 JUL 2012
3144 * @version 1.0WILC_WFI_set_cqmWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_config_rssi_config
3145 */
3146int WILC_WFI_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
3147 bool enabled, int timeout)
3148{
3149 struct WILC_WFI_priv *priv;
3150 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
3151
3152 if (wiphy == WILC_NULL)
3153 return -ENOENT;
3154
3155 priv = wiphy_priv(wiphy);
3156 if (priv->hWILCWFIDrv == WILC_NULL) {
3157 PRINT_ER("Driver is NULL\n");
3158 return -EIO;
3159 }
3160
3161 if (bEnablePS == WILC_TRUE)
3162 host_int_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
3163
3164
3165 return WILC_SUCCESS;
3166
3167}
3168#ifdef WILC_AP_EXTERNAL_MLME
3169/**
3170 * @brief WILC_WFI_change_virt_intf
3171 * @details Change type/configuration of virtual interface,
3172 * keep the struct wireless_dev's iftype updated.
3173 * @param[in] NONE
3174 * @return int : Return 0 on Success.
3175 * @author mdaftedar
3176 * @date 01 MAR 2012
3177 * @version 1.0
3178 */
3179void wilc1000_wlan_deinit(linux_wlan_t *nic);
3180int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic);
3181
3182static int WILC_WFI_change_virt_intf(struct wiphy *wiphy, struct net_device *dev,
3183 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
3184{
3185 WILC_Sint32 s32Error = WILC_SUCCESS;
3186 struct WILC_WFI_priv *priv;
3187 /* struct WILC_WFI_mon_priv* mon_priv; */
3188 perInterface_wlan_t *nic;
3189 WILC_Uint8 interface_type;
3190 WILC_Uint16 TID = 0;
3191 #ifdef WILC_P2P
3192 WILC_Uint8 i;
3193 #endif
3194
3195 nic = netdev_priv(dev);
3196 priv = wiphy_priv(wiphy);
3197
3198 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
3199 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
3200 u8P2Plocalrandom = 0x01;
3201 u8P2Precvrandom = 0x00;
3202
3203 bWilc_ie = WILC_FALSE;
3204
3205 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
3206 g_obtainingIP = WILC_FALSE;
3207 WILC_TimerStop(&hDuringIpTimer, WILC_NULL);
3208 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
3209 #endif
3210 /*BugID_5137*/
3211 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
3212 if (g_ptk_keys_saved && g_gtk_keys_saved) {
3213 Set_machw_change_vir_if(WILC_TRUE);
3214 }
3215
3216 switch (type) {
3217 case NL80211_IFTYPE_STATION:
3218 connecting = 0;
3219 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
3220 /* linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress); */
3221
3222 /* send delba over wlan interface */
3223
3224
3225 dev->ieee80211_ptr->iftype = type;
3226 priv->wdev->iftype = type;
3227 nic->monitor_flag = 0;
3228 nic->iftype = STATION_MODE;
3229
3230 /*Remove the enteries of the previously connected clients*/
3231 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
3232 #ifndef SIMULATION
3233 #ifdef WILC_P2P
3234 interface_type = nic->iftype;
3235 nic->iftype = STATION_MODE;
3236
3237 if (g_linux_wlan->wilc1000_initialized) {
3238 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
3239 /* ensure that the message Q is empty */
3240 host_int_wait_msg_queue_idle();
3241
3242 /*BugID_5213*/
3243 /*Eliminate host interface blocking state*/
3244 linux_wlan_unlock((void *)&g_linux_wlan->cfg_event);
3245
3246 wilc1000_wlan_deinit(g_linux_wlan);
3247 wilc1000_wlan_init(dev, nic);
3248 g_wilc_initialized = 1;
3249 nic->iftype = interface_type;
3250
3251 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
3252 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
3253 host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3254 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3255 host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
3256
3257 /*Add saved WEP keys, if any*/
3258 if (g_wep_keys_saved) {
3259 host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3260 g_key_wep_params.key_idx);
3261 host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3262 g_key_wep_params.key,
3263 g_key_wep_params.key_len,
3264 g_key_wep_params.key_idx);
3265 }
3266
3267 /*No matter the driver handler passed here, it will be overwriiten*/
3268 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
3269 host_int_flush_join_req(priv->hWILCWFIDrv);
3270
3271 /*Add saved PTK and GTK keys, if any*/
3272 if (g_ptk_keys_saved && g_gtk_keys_saved) {
3273 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
3274 g_key_ptk_params.key[1],
3275 g_key_ptk_params.key[2]);
3276 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
3277 g_key_gtk_params.key[1],
3278 g_key_gtk_params.key[2]);
3279 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3280 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3281 g_add_ptk_key_params.key_idx,
3282 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
3283 g_add_ptk_key_params.pairwise,
3284 #endif
3285 g_add_ptk_key_params.mac_addr,
3286 (struct key_params *)(&g_key_ptk_params));
3287
3288 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3289 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3290 g_add_gtk_key_params.key_idx,
3291 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
3292 g_add_gtk_key_params.pairwise,
3293 #endif
3294 g_add_gtk_key_params.mac_addr,
3295 (struct key_params *)(&g_key_gtk_params));
3296 }
3297
3298 /*BugID_4847: registered frames in firmware are now*/
3299 /*lost due to mac close. So re-register those frames*/
3300 if (g_linux_wlan->wilc1000_initialized) {
3301 for (i = 0; i < num_reg_frame; i++) {
3302 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3303 nic->g_struct_frame_reg[i].reg);
3304 host_int_frame_register(priv->hWILCWFIDrv,
3305 nic->g_struct_frame_reg[i].frame_type,
3306 nic->g_struct_frame_reg[i].reg);
3307 }
3308 }
3309
3310 bEnablePS = WILC_TRUE;
3311 host_int_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
3312 }
3313 #endif
3314 #endif
3315 break;
3316
3317 case NL80211_IFTYPE_P2P_CLIENT:
3318 bEnablePS = WILC_FALSE;
3319 host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
3320 connecting = 0;
3321 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
3322 /* linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress); */
3323
3324 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
3325
3326 dev->ieee80211_ptr->iftype = type;
3327 priv->wdev->iftype = type;
3328 nic->monitor_flag = 0;
3329
3330 #ifndef SIMULATION
3331 #ifdef WILC_P2P
3332
3333 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
3334 nic->iftype = CLIENT_MODE;
3335
3336
3337 if (g_linux_wlan->wilc1000_initialized) {
3338 /* ensure that the message Q is empty */
3339 host_int_wait_msg_queue_idle();
3340
3341 wilc1000_wlan_deinit(g_linux_wlan);
3342 wilc1000_wlan_init(dev, nic);
3343 g_wilc_initialized = 1;
3344
3345 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
3346 host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3347 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3348 host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
3349
3350 /*Add saved WEP keys, if any*/
3351 if (g_wep_keys_saved) {
3352 host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3353 g_key_wep_params.key_idx);
3354 host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3355 g_key_wep_params.key,
3356 g_key_wep_params.key_len,
3357 g_key_wep_params.key_idx);
3358 }
3359
3360 /*No matter the driver handler passed here, it will be overwriiten*/
3361 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
3362 host_int_flush_join_req(priv->hWILCWFIDrv);
3363
3364 /*Add saved PTK and GTK keys, if any*/
3365 if (g_ptk_keys_saved && g_gtk_keys_saved) {
3366 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
3367 g_key_ptk_params.key[1],
3368 g_key_ptk_params.key[2]);
3369 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
3370 g_key_gtk_params.key[1],
3371 g_key_gtk_params.key[2]);
3372 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3373 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3374 g_add_ptk_key_params.key_idx,
3375 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
3376 g_add_ptk_key_params.pairwise,
3377 #endif
3378 g_add_ptk_key_params.mac_addr,
3379 (struct key_params *)(&g_key_ptk_params));
3380
3381 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3382 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3383 g_add_gtk_key_params.key_idx,
3384 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
3385 g_add_gtk_key_params.pairwise,
3386 #endif
3387 g_add_gtk_key_params.mac_addr,
3388 (struct key_params *)(&g_key_gtk_params));
3389 }
3390
3391 /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/
3392 refresh_scan(priv, 1, WILC_TRUE);
3393 Set_machw_change_vir_if(WILC_FALSE);
3394
3395 /*BugID_4847: registered frames in firmware are now lost
3396 * due to mac close. So re-register those frames */
3397 if (g_linux_wlan->wilc1000_initialized) {
3398 for (i = 0; i < num_reg_frame; i++) {
3399 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3400 nic->g_struct_frame_reg[i].reg);
3401 host_int_frame_register(priv->hWILCWFIDrv,
3402 nic->g_struct_frame_reg[i].frame_type,
3403 nic->g_struct_frame_reg[i].reg);
3404 }
3405 }
3406 }
3407 #endif
3408 #endif
3409 break;
3410
3411 case NL80211_IFTYPE_AP:
3412 /* connecting = 1; */
3413 bEnablePS = WILC_FALSE;
3414 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
3415 /* linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress); */
3416 /* mon_priv = netdev_priv(dev); */
3417 /* mon_priv->real_ndev = dev; */
3418 dev->ieee80211_ptr->iftype = type;
3419 priv->wdev->iftype = type;
3420 nic->iftype = AP_MODE;
3421 PRINT_D(CORECONFIG_DBG, "(WILC_Uint32)priv->hWILCWFIDrv[%x]\n", (WILC_Uint32)priv->hWILCWFIDrv);
3422
3423 #ifndef SIMULATION
3424 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
3425 linux_wlan_get_firmware(nic);
3426 #ifdef WILC_P2P
3427 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
3428 if (g_linux_wlan->wilc1000_initialized) {
3429 nic->iftype = AP_MODE;
3430 g_linux_wlan->wilc1000_initialized = 1;
3431 mac_close(dev);
3432 mac_open(dev);
3433
3434 /* wilc1000_wlan_deinit(g_linux_wlan); */
3435 /* wilc1000_wlan_init(dev,nic); */
3436 /* repeat_power_cycle(nic); */
3437 /* nic->iftype = STATION_MODE; */
3438
3439 /*BugID_4847: registered frames in firmware are now lost
3440 * due to mac close. So re-register those frames */
3441 for (i = 0; i < num_reg_frame; i++) {
3442 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3443 nic->g_struct_frame_reg[i].reg);
3444 host_int_frame_register(priv->hWILCWFIDrv,
3445 nic->g_struct_frame_reg[i].frame_type,
3446 nic->g_struct_frame_reg[i].reg);
3447 }
3448 }
3449 #endif
3450 #endif
3451 break;
3452
3453 case NL80211_IFTYPE_P2P_GO:
3454 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
3455
3456 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
3457 g_obtainingIP = WILC_TRUE;
3458 WILC_TimerStart(&hDuringIpTimer, duringIP_TIME, WILC_NULL, WILC_NULL);
3459 #endif
3460 host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
3461 /*BugID_5222*/
3462 /*Delete block ack has to be the latest config packet*/
3463 /*sent before downloading new FW. This is because it blocks on*/
3464 /*hWaitResponse semaphore, which allows previous config*/
3465 /*packets to actually take action on old FW*/
3466 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
3467 bEnablePS = WILC_FALSE;
3468 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
3469 /* linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress); */
3470 /* mon_priv = netdev_priv(dev); */
3471 /* mon_priv->real_ndev = dev; */
3472 dev->ieee80211_ptr->iftype = type;
3473 priv->wdev->iftype = type;
3474
3475 PRINT_D(CORECONFIG_DBG, "(WILC_Uint32)priv->hWILCWFIDrv[%x]\n", (WILC_Uint32)priv->hWILCWFIDrv);
3476 /* host_int_set_operation_mode((WILC_Uint32)priv->hWILCWFIDrv,AP_MODE); */
3477
3478 #ifndef SIMULATION
3479 #ifdef WILC_P2P
3480 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
3481
3482
3483 #if 1
3484 nic->iftype = GO_MODE;
3485
3486 /* ensure that the message Q is empty */
3487 host_int_wait_msg_queue_idle();
3488
3489 /*while(!g_hif_thread_idle)
3490 * {
3491 * PRINT_D(GENERIC_DBG, "Wait for host IF idle\n");
3492 * WILC_Sleep(10);
3493 * }*/
3494 wilc1000_wlan_deinit(g_linux_wlan);
3495 /* repeat_power_cycle_partially(g_linux_wlan); */
3496 wilc1000_wlan_init(dev, nic);
3497 g_wilc_initialized = 1;
3498
3499
3500 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
3501 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
3502 host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3503 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3504 host_int_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
3505
3506 /*Add saved WEP keys, if any*/
3507 if (g_wep_keys_saved) {
3508 host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3509 g_key_wep_params.key_idx);
3510 host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3511 g_key_wep_params.key,
3512 g_key_wep_params.key_len,
3513 g_key_wep_params.key_idx);
3514 }
3515
3516 /*No matter the driver handler passed here, it will be overwriiten*/
3517 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
3518 host_int_flush_join_req(priv->hWILCWFIDrv);
3519
3520 /*Add saved PTK and GTK keys, if any*/
3521 if (g_ptk_keys_saved && g_gtk_keys_saved) {
3522 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
3523 g_key_ptk_params.key[1],
3524 g_key_ptk_params.key[2],
3525 g_key_ptk_params.cipher);
3526 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
3527 g_key_gtk_params.key[1],
3528 g_key_gtk_params.key[2],
3529 g_key_gtk_params.cipher);
3530 #if 1
3531 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3532 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3533 g_add_ptk_key_params.key_idx,
3534 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
3535 g_add_ptk_key_params.pairwise,
3536 #endif
3537 g_add_ptk_key_params.mac_addr,
3538 (struct key_params *)(&g_key_ptk_params));
3539
3540 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3541 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3542 g_add_gtk_key_params.key_idx,
3543 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)
3544 g_add_gtk_key_params.pairwise,
3545 #endif
3546 g_add_gtk_key_params.mac_addr,
3547 (struct key_params *)(&g_key_gtk_params));
3548 #endif
3549 }
3550 #endif
3551
3552 /*BugID_4847: registered frames in firmware are now*/
3553 /*lost due to mac close. So re-register those frames*/
3554 if (g_linux_wlan->wilc1000_initialized) {
3555 for (i = 0; i < num_reg_frame; i++) {
3556 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3557 nic->g_struct_frame_reg[i].reg);
3558 host_int_frame_register(priv->hWILCWFIDrv,
3559 nic->g_struct_frame_reg[i].frame_type,
3560 nic->g_struct_frame_reg[i].reg);
3561 }
3562 }
3563 #endif
3564 #endif
3565 break;
3566
3567 default:
3568 PRINT_ER("Unknown interface type= %d\n", type);
3569 s32Error = -EINVAL;
3570 return s32Error;
3571 break;
3572 }
3573
3574 return s32Error;
3575}
3576
3577#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
3578/* (austin.2013-07-23)
3579 *
3580 * To support revised cfg80211_ops
3581 *
3582 * add_beacon --> start_ap
3583 * set_beacon --> change_beacon
3584 * del_beacon --> stop_ap
3585 *
3586 * beacon_parameters --> cfg80211_ap_settings
3587 * cfg80211_beacon_data
3588 *
3589 * applicable for linux kernel 3.4+
3590 */
3591
3592/**
3593 * @brief WILC_WFI_start_ap
3594 * @details Add a beacon with given parameters, @head, @interval
3595 * and @dtim_period will be valid, @tail is optional.
3596 * @param[in] wiphy
3597 * @param[in] dev The net device structure
3598 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
3599 * @return int : Return 0 on Success.
3600 * @author austin
3601 * @date 23 JUL 2013
3602 * @version 1.0
3603 */
3604static int WILC_WFI_start_ap(struct wiphy *wiphy, struct net_device *dev,
3605 struct cfg80211_ap_settings *settings)
3606{
3607 struct cfg80211_beacon_data *beacon = &(settings->beacon);
3608 struct WILC_WFI_priv *priv;
3609 WILC_Sint32 s32Error = WILC_SUCCESS;
3610
3611 priv = wiphy_priv(wiphy);
3612 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
3613
3614 PRINT_D(HOSTAPD_DBG, "Interval = %d \n DTIM period = %d\n Head length = %d Tail length = %d\n",
3615 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
3616
3617#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
3618 s32Error = WILC_WFI_CfgSetChannel(wiphy, &settings->chandef);
3619
3620 if (s32Error != WILC_SUCCESS)
3621 PRINT_ER("Error in setting channel\n");
3622#endif
3623
3624 linux_wlan_set_bssid(dev, g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3625
3626 #ifndef WILC_FULLY_HOSTING_AP
3627 s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
3628 settings->beacon_interval,
3629 settings->dtim_period,
3630 beacon->head_len, (WILC_Uint8 *)beacon->head,
3631 beacon->tail_len, (WILC_Uint8 *)beacon->tail);
3632 #else
3633 s32Error = host_add_beacon(priv->hWILCWFIDrv,
3634 settings->beacon_interval,
3635 settings->dtim_period,
3636 beacon->head_len, (WILC_Uint8 *)beacon->head,
3637 beacon->tail_len, (WILC_Uint8 *)beacon->tail);
3638 #endif
3639
3640 return s32Error;
3641}
3642
3643/**
3644 * @brief WILC_WFI_change_beacon
3645 * @details Add a beacon with given parameters, @head, @interval
3646 * and @dtim_period will be valid, @tail is optional.
3647 * @param[in] wiphy
3648 * @param[in] dev The net device structure
3649 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
3650 * @return int : Return 0 on Success.
3651 * @author austin
3652 * @date 23 JUL 2013
3653 * @version 1.0
3654 */
3655static int WILC_WFI_change_beacon(struct wiphy *wiphy, struct net_device *dev,
3656 struct cfg80211_beacon_data *beacon)
3657{
3658 struct WILC_WFI_priv *priv;
3659 WILC_Sint32 s32Error = WILC_SUCCESS;
3660
3661 priv = wiphy_priv(wiphy);
3662 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
3663
3664
3665#ifndef WILC_FULLY_HOSTING_AP
3666 s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
3667 0,
3668 0,
3669 beacon->head_len, (WILC_Uint8 *)beacon->head,
3670 beacon->tail_len, (WILC_Uint8 *)beacon->tail);
3671#else
3672 s32Error = host_add_beacon(priv->hWILCWFIDrv,
3673 0,
3674 0,
3675 beacon->head_len, (WILC_Uint8 *)beacon->head,
3676 beacon->tail_len, (WILC_Uint8 *)beacon->tail);
3677#endif
3678
3679 return s32Error;
3680}
3681
3682/**
3683 * @brief WILC_WFI_stop_ap
3684 * @details Remove beacon configuration and stop sending the beacon.
3685 * @param[in]
3686 * @return int : Return 0 on Success.
3687 * @author austin
3688 * @date 23 JUL 2013
3689 * @version 1.0
3690 */
3691static int WILC_WFI_stop_ap(struct wiphy *wiphy, struct net_device *dev)
3692{
3693 WILC_Sint32 s32Error = WILC_SUCCESS;
3694 struct WILC_WFI_priv *priv;
3695 WILC_Uint8 NullBssid[ETH_ALEN] = {0};
3696
3697
3698 WILC_NULLCHECK(s32Error, wiphy);
3699
3700 priv = wiphy_priv(wiphy);
3701
3702 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
3703
3704 /*BugID_5188*/
3705 linux_wlan_set_bssid(dev, NullBssid);
3706
3707 #ifndef WILC_FULLY_HOSTING_AP
3708 s32Error = host_int_del_beacon(priv->hWILCWFIDrv);
3709 #else
3710 s32Error = host_del_beacon(priv->hWILCWFIDrv);
3711 #endif
3712
3713 WILC_ERRORCHECK(s32Error);
3714
3715 WILC_CATCH(s32Error)
3716 {
3717 }
3718 return s32Error;
3719}
3720
3721#else /* here belows are original for < kernel 3.3 (austin.2013-07-23) */
3722
3723/**
3724 * @brief WILC_WFI_add_beacon
3725 * @details Add a beacon with given parameters, @head, @interval
3726 * and @dtim_period will be valid, @tail is optional.
3727 * @param[in] wiphy
3728 * @param[in] dev The net device structure
3729 * @param[in] info Parameters for the beacon to be added
3730 * @return int : Return 0 on Success.
3731 * @author mdaftedar
3732 * @date 01 MAR 2012
3733 * @version 1.0
3734 */
3735static int WILC_WFI_add_beacon(struct wiphy *wiphy, struct net_device *dev,
3736 struct beacon_parameters *info)
3737{
3738 WILC_Sint32 s32Error = WILC_SUCCESS;
3739 struct WILC_WFI_priv *priv;
3740
3741
3742
3743 priv = wiphy_priv(wiphy);
3744 PRINT_D(HOSTAPD_DBG, "Adding Beacon\n");
3745
3746 PRINT_D(HOSTAPD_DBG, "Interval = %d \n DTIM period = %d\n Head length = %d Tail length = %d\n", info->interval, info->dtim_period, info->head_len, info->tail_len);
3747
3748 linux_wlan_set_bssid(dev, g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3749
3750 #ifndef WILC_FULLY_HOSTING_AP
3751 s32Error = host_int_add_beacon(priv->hWILCWFIDrv, info->interval,
3752 info->dtim_period,
3753 info->head_len, info->head,
3754 info->tail_len, info->tail);
3755
3756 #else
3757 s32Error = host_add_beacon(priv->hWILCWFIDrv, info->interval,
3758 info->dtim_period,
3759 info->head_len, info->head,
3760 info->tail_len, info->tail);
3761 #endif
3762
3763 return s32Error;
3764}
3765
3766/**
3767 * @brief WILC_WFI_set_beacon
3768 * @details Change the beacon parameters for an access point mode
3769 * interface. This should reject the call when no beacon has been
3770 * configured.
3771 * @param[in]
3772 * @return int : Return 0 on Success.
3773 * @author mdaftedar
3774 * @date 01 MAR 2012
3775 * @version 1.0
3776 */
3777static int WILC_WFI_set_beacon(struct wiphy *wiphy, struct net_device *dev,
3778 struct beacon_parameters *info)
3779{
3780 WILC_Sint32 s32Error = WILC_SUCCESS;
3781
3782
3783 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
3784
3785 s32Error = WILC_WFI_add_beacon(wiphy, dev, info);
3786
3787 return s32Error;
3788}
3789
3790/**
3791 * @brief WILC_WFI_del_beacon
3792 * @details Remove beacon configuration and stop sending the beacon.
3793 * @param[in]
3794 * @return int : Return 0 on Success.
3795 * @author mdaftedar
3796 * @date 01 MAR 2012
3797 * @version 1.0
3798 */
3799static int WILC_WFI_del_beacon(struct wiphy *wiphy, struct net_device *dev)
3800{
3801 WILC_Sint32 s32Error = WILC_SUCCESS;
3802 struct WILC_WFI_priv *priv;
3803 WILC_Uint8 NullBssid[ETH_ALEN] = {0};
3804
3805
3806 WILC_NULLCHECK(s32Error, wiphy);
3807
3808 priv = wiphy_priv(wiphy);
3809
3810 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
3811
3812 /*BugID_5188*/
3813 linux_wlan_set_bssid(dev, NullBssid);
3814
3815 #ifndef WILC_FULLY_HOSTING_AP
3816 s32Error = host_int_del_beacon(priv->hWILCWFIDrv);
3817 #else
3818 s32Error = host_del_beacon(priv->hWILCWFIDrv);
3819 #endif
3820
3821 WILC_ERRORCHECK(s32Error);
3822
3823 WILC_CATCH(s32Error)
3824 {
3825 }
3826 return s32Error;
3827}
3828
3829#endif /* linux kernel 3.4+ (austin.2013-07-23) */
3830
3831/**
3832 * @brief WILC_WFI_add_station
3833 * @details Add a new station.
3834 * @param[in]
3835 * @return int : Return 0 on Success.
3836 * @author mdaftedar
3837 * @date 01 MAR 2012
3838 * @version 1.0
3839 */
3840static int WILC_WFI_add_station(struct wiphy *wiphy, struct net_device *dev,
3841 u8 *mac, struct station_parameters *params)
3842{
3843 WILC_Sint32 s32Error = WILC_SUCCESS;
3844 struct WILC_WFI_priv *priv;
3845 tstrWILC_AddStaParam strStaParams = {{0}};
3846 perInterface_wlan_t *nic;
3847
3848
3849 WILC_NULLCHECK(s32Error, wiphy);
3850
3851 priv = wiphy_priv(wiphy);
3852 nic = netdev_priv(dev);
3853
3854 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3855 #ifndef WILC_FULLY_HOSTING_AP
3856
3857 WILC_memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
3858 WILC_memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
3859 strStaParams.u16AssocID = params->aid;
3860 strStaParams.u8NumRates = params->supported_rates_len;
3861 strStaParams.pu8Rates = params->supported_rates;
3862
3863 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3864
3865 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],
3866 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
3867 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID);
3868 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates);
3869
3870 if (params->ht_capa == WILC_NULL) {
3871 strStaParams.bIsHTSupported = WILC_FALSE;
3872 } else {
3873 strStaParams.bIsHTSupported = WILC_TRUE;
3874 strStaParams.u16HTCapInfo = params->ht_capa->cap_info;
3875 strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info;
3876 WILC_memcpy(strStaParams.au8SuppMCsSet, &params->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE);
3877 strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info;
3878 strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info;
3879 strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info;
3880 }
3881
3882 strStaParams.u16FlagsMask = params->sta_flags_mask;
3883 strStaParams.u16FlagsSet = params->sta_flags_set;
3884
3885 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported);
3886 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo);
3887 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams);
3888 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams);
3889 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap);
3890 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap);
3891 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask);
3892 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet);
3893
3894 s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams);
3895 WILC_ERRORCHECK(s32Error);
3896
3897 #else
3898 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3899 WILC_memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
3900
3901 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],
3902 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
3903
3904 WILC_AP_AddSta(mac, params);
3905 WILC_ERRORCHECK(s32Error);
3906 #endif /* WILC_FULLY_HOSTING_AP */
3907
3908 }
3909
3910 WILC_CATCH(s32Error)
3911 {
3912 }
3913 return s32Error;
3914}
3915
3916/**
3917 * @brief WILC_WFI_del_station
3918 * @details Remove a station; @mac may be NULL to remove all stations.
3919 * @param[in]
3920 * @return int : Return 0 on Success.
3921 * @author mdaftedar
3922 * @date 01 MAR 2012
3923 * @version 1.0
3924 */
3925static int WILC_WFI_del_station(struct wiphy *wiphy, struct net_device *dev,
3926#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
3927 struct station_del_parameters *params)
3928#else
3929 u8 *mac)
3930#endif
3931{
3932 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
3933 u8 *mac = params->mac;
3934 #endif
3935 WILC_Sint32 s32Error = WILC_SUCCESS;
3936 struct WILC_WFI_priv *priv;
3937 perInterface_wlan_t *nic;
3938 WILC_NULLCHECK(s32Error, wiphy);
3939 /*BugID_4795: mac may be null pointer to indicate deleting all stations, so avoid null check*/
3940 /* WILC_NULLCHECK(s32Error, mac); */
3941
3942 priv = wiphy_priv(wiphy);
3943 nic = netdev_priv(dev);
3944
3945 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3946 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3947
3948
3949 if (mac == WILC_NULL) {
3950 PRINT_D(HOSTAPD_DBG, "All associated stations \n");
3951 s32Error = host_int_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
3952 } else {
3953 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]);
3954 }
3955
3956 #ifndef WILC_FULLY_HOSTING_AP
3957 s32Error = host_int_del_station(priv->hWILCWFIDrv, mac);
3958 #else
3959 WILC_AP_RemoveSta(mac);
3960 #endif /* WILC_FULLY_HOSTING_AP */
3961
3962 WILC_ERRORCHECK(s32Error);
3963 }
3964 WILC_CATCH(s32Error)
3965 {
3966 }
3967 return s32Error;
3968}
3969
3970/**
3971 * @brief WILC_WFI_change_station
3972 * @details Modify a given station.
3973 * @param[in]
3974 * @return int : Return 0 on Success.
3975 * @author mdaftedar
3976 * @date 01 MAR 2012
3977 * @version 1.0
3978 */
3979static int WILC_WFI_change_station(struct wiphy *wiphy, struct net_device *dev,
3980 u8 *mac, struct station_parameters *params)
3981{
3982 WILC_Sint32 s32Error = WILC_SUCCESS;
3983 struct WILC_WFI_priv *priv;
3984 tstrWILC_AddStaParam strStaParams = {{0}};
3985 perInterface_wlan_t *nic;
3986
3987
3988 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3989
3990 WILC_NULLCHECK(s32Error, wiphy);
3991
3992 priv = wiphy_priv(wiphy);
3993 nic = netdev_priv(dev);
3994
3995 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3996 #ifndef WILC_FULLY_HOSTING_AP
3997
3998 WILC_memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
3999 strStaParams.u16AssocID = params->aid;
4000 strStaParams.u8NumRates = params->supported_rates_len;
4001 strStaParams.pu8Rates = params->supported_rates;
4002
4003 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n", strStaParams.au8BSSID[0], strStaParams.au8BSSID[1], strStaParams.au8BSSID[2], strStaParams.au8BSSID[3], strStaParams.au8BSSID[4],
4004 strStaParams.au8BSSID[5]);
4005 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID);
4006 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates);
4007
4008 if (params->ht_capa == WILC_NULL) {
4009 strStaParams.bIsHTSupported = WILC_FALSE;
4010 } else {
4011 strStaParams.bIsHTSupported = WILC_TRUE;
4012 strStaParams.u16HTCapInfo = params->ht_capa->cap_info;
4013 strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info;
4014 WILC_memcpy(strStaParams.au8SuppMCsSet, &params->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE);
4015 strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info;
4016 strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info;
4017 strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info;
4018
4019 }
4020
4021 strStaParams.u16FlagsMask = params->sta_flags_mask;
4022 strStaParams.u16FlagsSet = params->sta_flags_set;
4023
4024 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported);
4025 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo);
4026 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams);
4027 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams);
4028 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap);
4029 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap);
4030 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask);
4031 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet);
4032
4033 s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams);
4034 WILC_ERRORCHECK(s32Error);
4035
4036 #else
4037 WILC_AP_EditSta(mac, params);
4038 WILC_ERRORCHECK(s32Error);
4039 #endif /* WILC_FULLY_HOSTING_AP */
4040
4041 }
4042 WILC_CATCH(s32Error)
4043 {
4044 }
4045 return s32Error;
4046}
4047
4048
4049/**
4050 * @brief WILC_WFI_add_virt_intf
4051 * @details
4052 * @param[in]
4053 * @return int : Return 0 on Success.
4054 * @author mdaftedar
4055 * @date 01 JUL 2012
4056 * @version 1.0
4057 */
4058#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
4059struct wireless_dev *WILC_WFI_add_virt_intf(struct wiphy *wiphy, const char *name,
4060 unsigned char name_assign_type,
4061 enum nl80211_iftype type, u32 *flags,
4062 struct vif_params *params)
4063#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) /* tony for v3.8 support */
4064struct wireless_dev *WILC_WFI_add_virt_intf(struct wiphy *wiphy, const char *name,
4065 enum nl80211_iftype type, u32 *flags,
4066 struct vif_params *params)
4067#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) /* tony for v3.6 support */
4068struct wireless_dev *WILC_WFI_add_virt_intf(struct wiphy *wiphy, char *name,
4069 enum nl80211_iftype type, u32 *flags,
4070 struct vif_params *params)
4071#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
4072int WILC_WFI_add_virt_intf(struct wiphy *wiphy, char *name,
4073 enum nl80211_iftype type, u32 *flags,
4074 struct vif_params *params)
4075#else
4076struct net_device *WILC_WFI_add_virt_intf(struct wiphy *wiphy, char *name,
4077 enum nl80211_iftype type, u32 *flags,
4078 struct vif_params *params)
4079#endif
4080{
4081 perInterface_wlan_t *nic;
4082 struct WILC_WFI_priv *priv;
4083 /* struct WILC_WFI_mon_priv* mon_priv; */
4084 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
4085 WILC_Sint32 s32Error = WILC_SUCCESS;
4086 #endif
4087 struct net_device *new_ifc = NULL;
4088 priv = wiphy_priv(wiphy);
4089
4090
4091
4092 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
4093
4094 nic = netdev_priv(priv->wdev->netdev);
4095
4096
4097 if (type == NL80211_IFTYPE_MONITOR) {
4098 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
4099 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
4100 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
4101 if (new_ifc != NULL) {
4102 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
4103 #ifdef SIMULATION
4104 priv = netdev_priv(priv->wdev->netdev);
4105 priv->monitor_flag = 1;
4106 #else
4107 nic = netdev_priv(priv->wdev->netdev);
4108 nic->monitor_flag = 1;
4109 #endif
4110 } else
4111 PRINT_ER("Error in initializing monitor interface\n ");
4112 }
4113#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) /* tony for v3.8 support */
4114 return priv->wdev;
4115#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
4116 return s32Error;
4117#else
4118 /* return priv->wdev->netdev; */
4119 PRINT_D(HOSTAPD_DBG, "IFC[%p] created\n", new_ifc);
4120 return new_ifc;
4121#endif
4122
4123}
4124
4125/**
4126 * @brief WILC_WFI_del_virt_intf
4127 * @details
4128 * @param[in]
4129 * @return int : Return 0 on Success.
4130 * @author mdaftedar
4131 * @date 01 JUL 2012
4132 * @version 1.0
4133 */
4134#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
4135int WILC_WFI_del_virt_intf(struct wiphy *wiphy, struct wireless_dev *wdev) /* tony for v3.8 support */
4136#else
4137int WILC_WFI_del_virt_intf(struct wiphy *wiphy, struct net_device *dev)
4138#endif
4139{
4140 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
4141 return WILC_SUCCESS;
4142}
4143
4144
4145
4146#endif /*WILC_AP_EXTERNAL_MLME*/
4147static struct cfg80211_ops WILC_WFI_cfg80211_ops = {
4148
4149#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
4150 /*
4151 * replaced set_channel by set_monitor_channel
4152 * from v3.6
4153 * tony, 2013-10-29
4154 */
4155 .set_monitor_channel = WILC_WFI_CfgSetChannel,
4156#else
4157 .set_channel = WILC_WFI_CfgSetChannel,
4158#endif
4159 .scan = WILC_WFI_CfgScan,
4160 .connect = WILC_WFI_CfgConnect,
4161 .disconnect = WILC_WFI_disconnect,
4162 .add_key = WILC_WFI_add_key,
4163 .del_key = WILC_WFI_del_key,
4164 .get_key = WILC_WFI_get_key,
4165 .set_default_key = WILC_WFI_set_default_key,
4166#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32)
4167 /* .dump_survey = WILC_WFI_dump_survey, */
4168#endif
4169 #ifdef WILC_AP_EXTERNAL_MLME
4170 .add_virtual_intf = WILC_WFI_add_virt_intf,
4171 .del_virtual_intf = WILC_WFI_del_virt_intf,
4172 .change_virtual_intf = WILC_WFI_change_virt_intf,
4173
4174#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
4175 .add_beacon = WILC_WFI_add_beacon,
4176 .set_beacon = WILC_WFI_set_beacon,
4177 .del_beacon = WILC_WFI_del_beacon,
4178#else
4179 /* supports kernel 3.4+ change. austin.2013-07-23 */
4180 .start_ap = WILC_WFI_start_ap,
4181 .change_beacon = WILC_WFI_change_beacon,
4182 .stop_ap = WILC_WFI_stop_ap,
4183#endif
4184 .add_station = WILC_WFI_add_station,
4185 .del_station = WILC_WFI_del_station,
4186 .change_station = WILC_WFI_change_station,
4187 #endif /* WILC_AP_EXTERNAL_MLME*/
4188 #ifndef WILC_FULLY_HOSTING_AP
4189 .get_station = WILC_WFI_get_station,
4190 #endif
4191 .dump_station = WILC_WFI_dump_station,
4192 .change_bss = WILC_WFI_change_bss,
4193 /* .auth = WILC_WFI_auth, */
4194 /* .assoc = WILC_WFI_assoc, */
4195 /* .deauth = WILC_WFI_deauth, */
4196 /* .disassoc = WILC_WFI_disassoc, */
4197 .set_wiphy_params = WILC_WFI_set_wiphy_params,
4198
4199#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32)
4200 /* .set_bitrate_mask = WILC_WFI_set_bitrate_mask, */
4201 .set_pmksa = WILC_WFI_set_pmksa,
4202 .del_pmksa = WILC_WFI_del_pmksa,
4203 .flush_pmksa = WILC_WFI_flush_pmksa,
4204#ifdef WILC_P2P
4205 .remain_on_channel = WILC_WFI_remain_on_channel,
4206 .cancel_remain_on_channel = WILC_WFI_cancel_remain_on_channel,
4207 .mgmt_tx_cancel_wait = WILC_WFI_mgmt_tx_cancel_wait,
4208 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
4209 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
4210 .action = WILC_WFI_action,
4211 #endif
4212 #else
4213 .mgmt_tx = WILC_WFI_mgmt_tx,
4214 .mgmt_frame_register = WILC_WFI_frame_register,
4215 #endif
4216#endif
4217 /* .mgmt_tx_cancel_wait = WILC_WFI_mgmt_tx_cancel_wait, */
4218 .set_power_mgmt = WILC_WFI_set_power_mgmt,
4219 .set_cqm_rssi_config = WILC_WFI_set_cqm_rssi_config,
4220#endif
4221
4222};
4223
4224
4225
4226
4227
4228/**
4229 * @brief WILC_WFI_update_stats
4230 * @details Modify parameters for a given BSS.
4231 * @param[in]
4232 * @return int : Return 0 on Success.
4233 * @author mdaftedar
4234 * @date 01 MAR 2012
4235 * @version 1.0WILC_WFI_set_cqmWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_config_rssi_config
4236 */
4237int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
4238{
4239
4240 struct WILC_WFI_priv *priv;
4241
4242 priv = wiphy_priv(wiphy);
4243 /* WILC_SemaphoreAcquire(&SemHandleUpdateStats,NULL); */
4244#if 1
4245 switch (changed) {
4246
4247 case WILC_WFI_RX_PKT:
4248 {
4249 /* MI_PRINTF("In Rx Receive Packet\n"); */
4250 priv->netstats.rx_packets++;
4251 priv->netstats.rx_bytes += pktlen;
4252 priv->netstats.rx_time = get_jiffies_64();
4253 }
4254 break;
4255
4256 case WILC_WFI_TX_PKT:
4257 {
4258 priv->netstats.tx_packets++;
4259 priv->netstats.tx_bytes += pktlen;
4260 priv->netstats.tx_time = get_jiffies_64();
4261
4262 }
4263 break;
4264
4265 default:
4266 break;
4267 }
4268 /* WILC_SemaphoreRelease(&SemHandleUpdateStats,NULL); */
4269#endif
4270 return 0;
4271}
4272/**
4273 * @brief WILC_WFI_InitPriv
4274 * @details Initialization of the net device, private data
4275 * @param[in] NONE
4276 * @return NONE
4277 * @author mdaftedar
4278 * @date 01 MAR 2012
4279 * @version 1.0
4280 */
4281void WILC_WFI_InitPriv(struct net_device *dev)
4282{
4283
4284 struct WILC_WFI_priv *priv;
4285 priv = netdev_priv(dev);
4286
4287 priv->netstats.rx_packets = 0;
4288 priv->netstats.tx_packets = 0;
4289 priv->netstats.rx_bytes = 0;
4290 priv->netstats.rx_bytes = 0;
4291 priv->netstats.rx_time = 0;
4292 priv->netstats.tx_time = 0;
4293
4294
4295}
4296/**
4297 * @brief WILC_WFI_CfgAlloc
4298 * @details Allocation of the wireless device structure and assigning it
4299 * to the cfg80211 operations structure.
4300 * @param[in] NONE
4301 * @return wireless_dev : Returns pointer to wireless_dev structure.
4302 * @author mdaftedar
4303 * @date 01 MAR 2012
4304 * @version 1.0
4305 */
4306struct wireless_dev *WILC_WFI_CfgAlloc(void)
4307{
4308
4309 struct wireless_dev *wdev;
4310
4311
4312 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
4313 /*Allocating the wireless device structure*/
4314 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
4315 if (!wdev) {
4316 PRINT_ER("Cannot allocate wireless device\n");
4317 goto _fail_;
4318 }
4319
4320 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
4321 wdev->wiphy = wiphy_new(&WILC_WFI_cfg80211_ops, sizeof(struct WILC_WFI_priv));
4322 if (!wdev->wiphy) {
4323 PRINT_ER("Cannot allocate wiphy\n");
4324 goto _fail_mem_;
4325
4326 }
4327
4328 #ifdef WILC_AP_EXTERNAL_MLME
4329 /* enable 802.11n HT */
4330 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
4331 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
4332 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
4333 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
4334 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
4335 #endif
4336
4337 /*wiphy bands*/
4338 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
4339
4340 return wdev;
4341
4342_fail_mem_:
4343 kfree(wdev);
4344_fail_:
4345 return NULL;
4346
4347}
4348/**
4349 * @brief WILC_WFI_WiphyRegister
4350 * @details Registering of the wiphy structure and interface modes
4351 * @param[in] NONE
4352 * @return NONE
4353 * @author mdaftedar
4354 * @date 01 MAR 2012
4355 * @version 1.0
4356 */
4357struct wireless_dev *WILC_WFI_WiphyRegister(struct net_device *net)
4358{
4359 struct WILC_WFI_priv *priv;
4360 struct wireless_dev *wdev;
4361 WILC_Sint32 s32Error = WILC_SUCCESS;
4362
4363 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
4364
4365 wdev = WILC_WFI_CfgAlloc();
4366 if (wdev == NULL) {
4367 PRINT_ER("CfgAlloc Failed\n");
4368 return NULL;
4369 }
4370
4371
4372 /*Return hardware description structure (wiphy)'s priv*/
4373 priv = wdev_priv(wdev);
4374 WILC_SemaphoreCreate(&(priv->SemHandleUpdateStats), NULL);
4375
4376 /*Link the wiphy with wireless structure*/
4377 priv->wdev = wdev;
4378
4379 /*Maximum number of probed ssid to be added by user for the scan request*/
4380 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
4381 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32)
4382 /*Maximum number of pmkids to be cashed*/
4383 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
4384 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
4385 #endif
4386
4387 wdev->wiphy->max_scan_ie_len = 1000;
4388
4389 /*signal strength in mBm (100*dBm) */
4390 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4391
4392 /*Set the availaible cipher suites*/
4393 wdev->wiphy->cipher_suites = cipher_suites;
4394 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
4395#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
4396 /*Setting default managment types: for register action frame: */
4397 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
4398#endif
4399
4400#ifdef WILC_P2P
4401 wdev->wiphy->max_remain_on_channel_duration = 500;
4402 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
4403 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
4404 BIT(NL80211_IFTYPE_P2P_CLIENT);
4405#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
4406
4407 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4408#endif
4409#else
4410 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
4411#endif
4412 wdev->iftype = NL80211_IFTYPE_STATION;
4413
4414
4415
4416 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
4417 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
4418 wdev->wiphy->interface_modes, wdev->iftype);
4419
4420 #ifdef WILC_SDIO
4421 set_wiphy_dev(wdev->wiphy, &local_sdio_func->dev); /* tony */
4422 #endif
4423
4424 /*Register wiphy structure*/
4425 s32Error = wiphy_register(wdev->wiphy);
4426 if (s32Error) {
4427 PRINT_ER("Cannot register wiphy device\n");
4428 /*should define what action to be taken in such failure*/
4429 } else {
4430 PRINT_D(CFG80211_DBG, "Successful Registering\n");
4431 }
4432
4433#if 0
4434 /*wdev[i]->wiphy->interface_modes =
4435 * BIT(NL80211_IFTYPE_AP);
4436 * wdev[i]->iftype = NL80211_IFTYPE_AP;
4437 */
4438
4439 /*Pointing the priv structure the netdev*/
4440 priv = netdev_priv(net);
4441
4442 /*linking the wireless_dev structure with the netdevice*/
4443 priv->dev->ieee80211_ptr = wdev;
4444 priv->dev->ml_priv = priv;
4445 wdev->netdev = priv->dev;
4446#endif
4447 priv->dev = net;
4448#if 0
4449 ret = host_int_init(&priv->hWILCWFIDrv);
4450 if (ret) {
4451 PRINT_ER("Error Init Driver\n");
4452 }
4453#endif
4454 return wdev;
4455
4456
4457}
4458/**
4459 * @brief WILC_WFI_WiphyFree
4460 * @details Freeing allocation of the wireless device structure
4461 * @param[in] NONE
4462 * @return NONE
4463 * @author mdaftedar
4464 * @date 01 MAR 2012
4465 * @version 1.0
4466 */
4467int WILC_WFI_InitHostInt(struct net_device *net)
4468{
4469
4470 WILC_Sint32 s32Error = WILC_SUCCESS;
4471
4472 struct WILC_WFI_priv *priv;
4473
4474 tstrWILC_SemaphoreAttrs strSemaphoreAttrs;
4475
4476 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
4477 priv = wdev_priv(net->ieee80211_ptr);
4478 if (op_ifcs == 0) {
4479 s32Error = WILC_TimerCreate(&(hAgingTimer), remove_network_from_shadow, WILC_NULL);
4480 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
4481 s32Error = WILC_TimerCreate(&(hDuringIpTimer), clear_duringIP, WILC_NULL);
4482 #endif
4483 }
4484 op_ifcs++;
4485 if (s32Error < 0) {
4486 PRINT_ER("Failed to creat refresh Timer\n");
4487 return s32Error;
4488 }
4489
4490 WILC_SemaphoreFillDefault(&strSemaphoreAttrs);
4491
4492 /* /////////////////////////////////////// */
4493 /* strSemaphoreAttrs.u32InitCount = 0; */
4494
4495
4496 priv->gbAutoRateAdjusted = WILC_FALSE;
4497
4498 priv->bInP2PlistenState = WILC_FALSE;
4499
4500 WILC_SemaphoreCreate(&(priv->hSemScanReq), &strSemaphoreAttrs);
4501 s32Error = host_int_init(&priv->hWILCWFIDrv);
4502 /* s32Error = host_int_init(&priv->hWILCWFIDrv_2); */
4503 if (s32Error) {
4504 PRINT_ER("Error while initializing hostinterface\n");
4505 }
4506 return s32Error;
4507}
4508
4509/**
4510 * @brief WILC_WFI_WiphyFree
4511 * @details Freeing allocation of the wireless device structure
4512 * @param[in] NONE
4513 * @return NONE
4514 * @author mdaftedar
4515 * @date 01 MAR 2012
4516 * @version 1.0
4517 */
4518int WILC_WFI_DeInitHostInt(struct net_device *net)
4519{
4520 WILC_Sint32 s32Error = WILC_SUCCESS;
4521
4522 struct WILC_WFI_priv *priv;
4523 priv = wdev_priv(net->ieee80211_ptr);
4524
4525
4526
4527
4528
4529
4530 WILC_SemaphoreDestroy(&(priv->hSemScanReq), NULL);
4531
4532 priv->gbAutoRateAdjusted = WILC_FALSE;
4533
4534 priv->bInP2PlistenState = WILC_FALSE;
4535
4536 op_ifcs--;
4537
4538 s32Error = host_int_deinit(priv->hWILCWFIDrv);
4539 /* s32Error = host_int_deinit(priv->hWILCWFIDrv_2); */
4540
4541 /* Clear the Shadow scan */
4542 clear_shadow_scan(priv);
4543 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
4544 if (op_ifcs == 0) {
4545 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
4546 WILC_TimerDestroy(&hDuringIpTimer, WILC_NULL);
4547 }
4548 #endif
4549
4550 if (s32Error) {
4551 PRINT_ER("Error while deintializing host interface\n");
4552 }
4553 return s32Error;
4554}
4555
4556
4557/**
4558 * @brief WILC_WFI_WiphyFree
4559 * @details Freeing allocation of the wireless device structure
4560 * @param[in] NONE
4561 * @return NONE
4562 * @author mdaftedar
4563 * @date 01 MAR 2012
4564 * @version 1.0
4565 */
4566void WILC_WFI_WiphyFree(struct net_device *net)
4567{
4568
4569 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
4570
4571 if (net == NULL) {
4572 PRINT_D(INIT_DBG, "net_device is NULL\n");
4573 return;
4574 }
4575
4576 if (net->ieee80211_ptr == NULL) {
4577 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
4578 return;
4579 }
4580
4581 if (net->ieee80211_ptr->wiphy == NULL) {
4582 PRINT_D(INIT_DBG, "wiphy is NULL\n");
4583 return;
4584 }
4585
4586 wiphy_unregister(net->ieee80211_ptr->wiphy);
4587
4588 PRINT_D(INIT_DBG, "Freeing wiphy\n");
4589 wiphy_free(net->ieee80211_ptr->wiphy);
4590 kfree(net->ieee80211_ptr);
4591
4592}