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