2 * @file wilc_wfi_cfgopertaions.c
3 * @brief CFG80211 Function Implementation functionality
8 * @sa wilc_wfi_cfgopertaions.h top level OS wrapper file
13 #include "wilc_wfi_cfgoperations.h"
14 #include "wilc_wlan.c"
16 #include "linux_wlan_sdio.h" /* tony : for set_wiphy_dev() */
18 #include <linux/errno.h>
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)
25 extern int linux_wlan_get_firmware(perInterface_wlan_t
*p_nic
);
26 extern u16
Set_machw_change_vir_if(bool bValue
);
28 extern int mac_open(struct net_device
*ndev
);
29 extern int mac_close(struct net_device
*ndev
);
31 tstrNetworkInfo astrLastScannedNtwrksShadow
[MAX_NUM_SCANNED_NETWORKS_SHADOW
];
32 u32 u32LastScannedNtwrksCountShadow
;
33 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
34 struct timer_list hDuringIpTimer
;
36 struct timer_list hAgingTimer
;
38 extern u8 u8ConnectedSSID
[6];
41 u8 g_wilc_initialized
= 1;
42 extern linux_wlan_t
*g_linux_wlan
;
43 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
44 extern bool g_obtainingIP
;
47 #define CHAN2G(_channel, _freq, _flags) { \
48 .band = IEEE80211_BAND_2GHZ, \
49 .center_freq = (_freq), \
50 .hw_value = (_channel), \
52 .max_antenna_gain = 0, \
56 /*Frequency range for channels*/
57 static struct ieee80211_channel WILC_WFI_2ghz_channels
[] = {
74 #define RATETAB_ENT(_rate, _hw_value, _flags) { \
76 .hw_value = (_hw_value), \
81 /* Table 6 in section 3.2.1.1 */
82 static struct ieee80211_rate WILC_WFI_rates
[] = {
83 RATETAB_ENT(10, 0, 0),
84 RATETAB_ENT(20, 1, 0),
85 RATETAB_ENT(55, 2, 0),
86 RATETAB_ENT(110, 3, 0),
87 RATETAB_ENT(60, 9, 0),
88 RATETAB_ENT(90, 6, 0),
89 RATETAB_ENT(120, 7, 0),
90 RATETAB_ENT(180, 8, 0),
91 RATETAB_ENT(240, 9, 0),
92 RATETAB_ENT(360, 10, 0),
93 RATETAB_ENT(480, 11, 0),
94 RATETAB_ENT(540, 12, 0),
98 struct p2p_mgmt_data
{
103 /*Global variable used to state the current connected STA channel*/
104 u8 u8WLANChannel
= INVALID_CHANNEL
;
109 u8 u8P2P_oui
[] = {0x50, 0x6f, 0x9A, 0x09};
110 u8 u8P2Plocalrandom
= 0x01;
111 u8 u8P2Precvrandom
= 0x00;
112 u8 u8P2P_vendorspec
[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
116 static struct ieee80211_supported_band WILC_WFI_band_2ghz
= {
117 .channels
= WILC_WFI_2ghz_channels
,
118 .n_channels
= ARRAY_SIZE(WILC_WFI_2ghz_channels
),
119 .bitrates
= WILC_WFI_rates
,
120 .n_bitrates
= ARRAY_SIZE(WILC_WFI_rates
),
125 struct add_key_params
{
130 struct add_key_params g_add_gtk_key_params
;
131 struct wilc_wfi_key g_key_gtk_params
;
132 struct add_key_params g_add_ptk_key_params
;
133 struct wilc_wfi_key g_key_ptk_params
;
134 struct wilc_wfi_wep_key g_key_wep_params
;
135 bool g_ptk_keys_saved
;
136 bool g_gtk_keys_saved
;
137 bool g_wep_keys_saved
;
139 #define AGING_TIME (9 * 1000)
140 #define duringIP_TIME 15000
142 void clear_shadow_scan(void *pUserVoid
)
147 del_timer_sync(&hAgingTimer
);
148 PRINT_INFO(CORECONFIG_DBG
, "destroy aging timer\n");
150 for (i
= 0; i
< u32LastScannedNtwrksCountShadow
; i
++) {
151 if (astrLastScannedNtwrksShadow
[u32LastScannedNtwrksCountShadow
].pu8IEs
!= NULL
) {
152 kfree(astrLastScannedNtwrksShadow
[i
].pu8IEs
);
153 astrLastScannedNtwrksShadow
[u32LastScannedNtwrksCountShadow
].pu8IEs
= NULL
;
156 host_int_freeJoinParams(astrLastScannedNtwrksShadow
[i
].pJoinParams
);
157 astrLastScannedNtwrksShadow
[i
].pJoinParams
= NULL
;
159 u32LastScannedNtwrksCountShadow
= 0;
164 u32
get_rssi_avg(tstrNetworkInfo
*pstrNetworkInfo
)
168 u8 num_rssi
= (pstrNetworkInfo
->strRssi
.u8Full
) ? NUM_RSSI
: (pstrNetworkInfo
->strRssi
.u8Index
);
170 for (i
= 0; i
< num_rssi
; i
++)
171 rssi_v
+= pstrNetworkInfo
->strRssi
.as8RSSI
[i
];
177 void refresh_scan(void *pUserVoid
, u8 all
, bool bDirectScan
)
179 struct wilc_priv
*priv
;
181 struct cfg80211_bss
*bss
= NULL
;
185 priv
= (struct wilc_priv
*)pUserVoid
;
186 wiphy
= priv
->dev
->ieee80211_ptr
->wiphy
;
188 for (i
= 0; i
< u32LastScannedNtwrksCountShadow
; i
++) {
189 tstrNetworkInfo
*pstrNetworkInfo
;
191 pstrNetworkInfo
= &(astrLastScannedNtwrksShadow
[i
]);
194 if ((!pstrNetworkInfo
->u8Found
) || all
) {
196 struct ieee80211_channel
*channel
;
198 if (pstrNetworkInfo
!= NULL
) {
200 s32Freq
= ieee80211_channel_to_frequency((s32
)pstrNetworkInfo
->u8channel
, IEEE80211_BAND_2GHZ
);
201 channel
= ieee80211_get_channel(wiphy
, s32Freq
);
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
);
217 void reset_shadow_found(void *pUserVoid
)
221 for (i
= 0; i
< u32LastScannedNtwrksCountShadow
; i
++) {
222 astrLastScannedNtwrksShadow
[i
].u8Found
= 0;
227 void update_scan_time(void *pUserVoid
)
231 for (i
= 0; i
< u32LastScannedNtwrksCountShadow
; i
++) {
232 astrLastScannedNtwrksShadow
[i
].u32TimeRcvdInScan
= jiffies
;
236 static void remove_network_from_shadow(unsigned long arg
)
238 unsigned long now
= jiffies
;
242 for (i
= 0; i
< u32LastScannedNtwrksCountShadow
; i
++) {
243 if (time_after(now
, astrLastScannedNtwrksShadow
[i
].u32TimeRcvdInScan
+ (unsigned long)(SCAN_RESULT_EXPIRE
))) {
244 PRINT_D(CFG80211_DBG
, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow
[i
].au8ssid
);
246 if (astrLastScannedNtwrksShadow
[i
].pu8IEs
!= NULL
) {
247 kfree(astrLastScannedNtwrksShadow
[i
].pu8IEs
);
248 astrLastScannedNtwrksShadow
[i
].pu8IEs
= NULL
;
251 host_int_freeJoinParams(astrLastScannedNtwrksShadow
[i
].pJoinParams
);
253 for (j
= i
; (j
< u32LastScannedNtwrksCountShadow
- 1); j
++) {
254 astrLastScannedNtwrksShadow
[j
] = astrLastScannedNtwrksShadow
[j
+ 1];
256 u32LastScannedNtwrksCountShadow
--;
260 PRINT_D(CFG80211_DBG
, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow
);
261 if (u32LastScannedNtwrksCountShadow
!= 0) {
262 hAgingTimer
.data
= arg
;
263 mod_timer(&hAgingTimer
, jiffies
+ msecs_to_jiffies(AGING_TIME
));
265 PRINT_D(CFG80211_DBG
, "No need to restart Aging timer\n");
269 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
270 static void clear_duringIP(unsigned long arg
)
272 PRINT_D(GENERIC_DBG
, "GO:IP Obtained , enable scan\n");
273 g_obtainingIP
= false;
277 int8_t is_network_in_shadow(tstrNetworkInfo
*pstrNetworkInfo
, void *pUserVoid
)
282 if (u32LastScannedNtwrksCountShadow
== 0) {
283 PRINT_D(CFG80211_DBG
, "Starting Aging timer\n");
284 hAgingTimer
.data
= (unsigned long)pUserVoid
;
285 mod_timer(&hAgingTimer
, jiffies
+ msecs_to_jiffies(AGING_TIME
));
288 /* Linear search for now */
289 for (i
= 0; i
< u32LastScannedNtwrksCountShadow
; i
++) {
290 if (memcmp(astrLastScannedNtwrksShadow
[i
].au8bssid
,
291 pstrNetworkInfo
->au8bssid
, 6) == 0) {
300 void add_network_to_shadow(tstrNetworkInfo
*pstrNetworkInfo
, void *pUserVoid
, void *pJoinParams
)
302 int8_t ap_found
= is_network_in_shadow(pstrNetworkInfo
, pUserVoid
);
306 if (u32LastScannedNtwrksCountShadow
>= MAX_NUM_SCANNED_NETWORKS_SHADOW
) {
307 PRINT_D(CFG80211_DBG
, "Shadow network reached its maximum limit\n");
310 if (ap_found
== -1) {
311 ap_index
= u32LastScannedNtwrksCountShadow
;
312 u32LastScannedNtwrksCountShadow
++;
317 rssi_index
= astrLastScannedNtwrksShadow
[ap_index
].strRssi
.u8Index
;
318 astrLastScannedNtwrksShadow
[ap_index
].strRssi
.as8RSSI
[rssi_index
++] = pstrNetworkInfo
->s8rssi
;
319 if (rssi_index
== NUM_RSSI
) {
321 astrLastScannedNtwrksShadow
[ap_index
].strRssi
.u8Full
= 1;
323 astrLastScannedNtwrksShadow
[ap_index
].strRssi
.u8Index
= rssi_index
;
325 astrLastScannedNtwrksShadow
[ap_index
].s8rssi
= pstrNetworkInfo
->s8rssi
;
326 astrLastScannedNtwrksShadow
[ap_index
].u16CapInfo
= pstrNetworkInfo
->u16CapInfo
;
328 astrLastScannedNtwrksShadow
[ap_index
].u8SsidLen
= pstrNetworkInfo
->u8SsidLen
;
329 memcpy(astrLastScannedNtwrksShadow
[ap_index
].au8ssid
,
330 pstrNetworkInfo
->au8ssid
, pstrNetworkInfo
->u8SsidLen
);
332 memcpy(astrLastScannedNtwrksShadow
[ap_index
].au8bssid
,
333 pstrNetworkInfo
->au8bssid
, ETH_ALEN
);
335 astrLastScannedNtwrksShadow
[ap_index
].u16BeaconPeriod
= pstrNetworkInfo
->u16BeaconPeriod
;
336 astrLastScannedNtwrksShadow
[ap_index
].u8DtimPeriod
= pstrNetworkInfo
->u8DtimPeriod
;
337 astrLastScannedNtwrksShadow
[ap_index
].u8channel
= pstrNetworkInfo
->u8channel
;
339 astrLastScannedNtwrksShadow
[ap_index
].u16IEsLen
= pstrNetworkInfo
->u16IEsLen
;
340 astrLastScannedNtwrksShadow
[ap_index
].u64Tsf
= pstrNetworkInfo
->u64Tsf
;
342 kfree(astrLastScannedNtwrksShadow
[ap_index
].pu8IEs
);
343 astrLastScannedNtwrksShadow
[ap_index
].pu8IEs
=
344 kmalloc(pstrNetworkInfo
->u16IEsLen
, GFP_KERNEL
); /* will be deallocated by the WILC_WFI_CfgScan() function */
345 memcpy(astrLastScannedNtwrksShadow
[ap_index
].pu8IEs
,
346 pstrNetworkInfo
->pu8IEs
, pstrNetworkInfo
->u16IEsLen
);
348 astrLastScannedNtwrksShadow
[ap_index
].u32TimeRcvdInScan
= jiffies
;
349 astrLastScannedNtwrksShadow
[ap_index
].u32TimeRcvdInScanCached
= jiffies
;
350 astrLastScannedNtwrksShadow
[ap_index
].u8Found
= 1;
352 host_int_freeJoinParams(astrLastScannedNtwrksShadow
[ap_index
].pJoinParams
);
353 astrLastScannedNtwrksShadow
[ap_index
].pJoinParams
= pJoinParams
;
359 * @brief CfgScanResult
360 * @details Callback function which returns the scan results found
362 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
363 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
364 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
365 * void* pUserVoid: Private structure associated with the wireless interface
371 static void CfgScanResult(tenuScanEvent enuScanEvent
, tstrNetworkInfo
*pstrNetworkInfo
, void *pUserVoid
, void *pJoinParams
)
373 struct wilc_priv
*priv
;
376 struct ieee80211_channel
*channel
;
377 struct cfg80211_bss
*bss
= NULL
;
379 priv
= (struct wilc_priv
*)pUserVoid
;
380 if (priv
->bCfgScanning
== true) {
381 if (enuScanEvent
== SCAN_EVENT_NETWORK_FOUND
) {
382 wiphy
= priv
->dev
->ieee80211_ptr
->wiphy
;
387 if (wiphy
->signal_type
== CFG80211_SIGNAL_TYPE_UNSPEC
389 ((((s32
)pstrNetworkInfo
->s8rssi
) * 100) < 0
391 (((s32
)pstrNetworkInfo
->s8rssi
) * 100) > 100)
393 PRINT_ER("wiphy signal type fial\n");
397 if (pstrNetworkInfo
!= NULL
) {
398 s32Freq
= ieee80211_channel_to_frequency((s32
)pstrNetworkInfo
->u8channel
, IEEE80211_BAND_2GHZ
);
399 channel
= ieee80211_get_channel(wiphy
, s32Freq
);
404 PRINT_INFO(CFG80211_DBG
, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
405 "BeaconPeriod: %d\n", channel
->center_freq
, (((s32
)pstrNetworkInfo
->s8rssi
) * 100),
406 pstrNetworkInfo
->u16CapInfo
, pstrNetworkInfo
->u16BeaconPeriod
);
408 if (pstrNetworkInfo
->bNewNetwork
== true) {
409 if (priv
->u32RcvdChCount
< MAX_NUM_SCANNED_NETWORKS
) { /* TODO: mostafa: to be replaced by */
411 PRINT_D(CFG80211_DBG
, "Network %s found\n", pstrNetworkInfo
->au8ssid
);
414 priv
->u32RcvdChCount
++;
418 if (pJoinParams
== NULL
) {
419 PRINT_INFO(CORECONFIG_DBG
, ">> Something really bad happened\n");
421 add_network_to_shadow(pstrNetworkInfo
, priv
, pJoinParams
);
423 /*P2P peers are sent to WPA supplicant and added to shadow table*/
425 if (!(memcmp("DIRECT-", pstrNetworkInfo
->au8ssid
, 7))) {
426 bss
= cfg80211_inform_bss(wiphy
, channel
, CFG80211_BSS_FTYPE_UNKNOWN
, pstrNetworkInfo
->au8bssid
, pstrNetworkInfo
->u64Tsf
, pstrNetworkInfo
->u16CapInfo
,
427 pstrNetworkInfo
->u16BeaconPeriod
, (const u8
*)pstrNetworkInfo
->pu8IEs
,
428 (size_t)pstrNetworkInfo
->u16IEsLen
, (((s32
)pstrNetworkInfo
->s8rssi
) * 100), GFP_KERNEL
);
429 cfg80211_put_bss(wiphy
, bss
);
434 PRINT_ER("Discovered networks exceeded the max limit\n");
438 /* So this network is discovered before, we'll just update its RSSI */
439 for (i
= 0; i
< priv
->u32RcvdChCount
; i
++) {
440 if (memcmp(astrLastScannedNtwrksShadow
[i
].au8bssid
, pstrNetworkInfo
->au8bssid
, 6) == 0) {
441 PRINT_D(CFG80211_DBG
, "Update RSSI of %s\n", astrLastScannedNtwrksShadow
[i
].au8ssid
);
443 astrLastScannedNtwrksShadow
[i
].s8rssi
= pstrNetworkInfo
->s8rssi
;
444 astrLastScannedNtwrksShadow
[i
].u32TimeRcvdInScan
= jiffies
;
450 } else if (enuScanEvent
== SCAN_EVENT_DONE
) {
451 PRINT_D(CFG80211_DBG
, "Scan Done[%p]\n", priv
->dev
);
452 PRINT_D(CFG80211_DBG
, "Refreshing Scan ...\n");
453 refresh_scan(priv
, 1, false);
455 if (priv
->u32RcvdChCount
> 0)
456 PRINT_D(CFG80211_DBG
, "%d Network(s) found\n", priv
->u32RcvdChCount
);
458 PRINT_D(CFG80211_DBG
, "No networks found\n");
460 down(&(priv
->hSemScanReq
));
462 if (priv
->pstrScanReq
!= NULL
) {
463 cfg80211_scan_done(priv
->pstrScanReq
, false);
464 priv
->u32RcvdChCount
= 0;
465 priv
->bCfgScanning
= false;
466 priv
->pstrScanReq
= NULL
;
468 up(&(priv
->hSemScanReq
));
471 /*Aborting any scan operation during mac close*/
472 else if (enuScanEvent
== SCAN_EVENT_ABORTED
) {
473 down(&(priv
->hSemScanReq
));
475 PRINT_D(CFG80211_DBG
, "Scan Aborted\n");
476 if (priv
->pstrScanReq
!= NULL
) {
478 update_scan_time(priv
);
479 refresh_scan(priv
, 1, false);
481 cfg80211_scan_done(priv
->pstrScanReq
, false);
482 priv
->bCfgScanning
= false;
483 priv
->pstrScanReq
= NULL
;
485 up(&(priv
->hSemScanReq
));
492 * @brief WILC_WFI_Set_PMKSA
493 * @details Check if pmksa is cached and set it.
495 * @return int : Return 0 on Success
500 int WILC_WFI_Set_PMKSA(u8
*bssid
, struct wilc_priv
*priv
)
506 for (i
= 0; i
< priv
->pmkid_list
.numpmkid
; i
++) {
508 if (!memcmp(bssid
, priv
->pmkid_list
.pmkidlist
[i
].bssid
,
510 PRINT_D(CFG80211_DBG
, "PMKID successful comparison");
512 /*If bssid is found, set the values*/
513 s32Error
= host_int_set_pmkid_info(priv
->hWILCWFIDrv
, &priv
->pmkid_list
);
516 PRINT_ER("Error in pmkid\n");
526 int linux_wlan_set_bssid(struct net_device
*wilc_netdev
, u8
*pBSSID
);
530 * @brief CfgConnectResult
532 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
533 * connection response or disconnection notification.
534 * tstrConnectInfo* pstrConnectInfo: COnnection information.
535 * u8 u8MacStatus: Mac Status from firmware
536 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
537 * void* pUserVoid: Private data associated with wireless interface
545 static void CfgConnectResult(tenuConnDisconnEvent enuConnDisconnEvent
,
546 tstrConnectInfo
*pstrConnectInfo
,
548 tstrDisconnectNotifInfo
*pstrDisconnectNotifInfo
,
551 struct wilc_priv
*priv
;
552 struct net_device
*dev
;
554 tstrWILC_WFIDrv
*pstrWFIDrv
;
556 u8 NullBssid
[ETH_ALEN
] = {0};
560 priv
= (struct wilc_priv
*)pUserVoid
;
563 pstrWFIDrv
= (tstrWILC_WFIDrv
*)priv
->hWILCWFIDrv
;
566 if (enuConnDisconnEvent
== CONN_DISCONN_EVENT_CONN_RESP
) {
568 u16 u16ConnectStatus
= WLAN_STATUS_SUCCESS
;
570 u16ConnectStatus
= pstrConnectInfo
->u16ConnectStatus
;
572 PRINT_D(CFG80211_DBG
, " Connection response received = %d\n", u8MacStatus
);
574 if ((u8MacStatus
== MAC_DISCONNECTED
) &&
575 (pstrConnectInfo
->u16ConnectStatus
== SUCCESSFUL_STATUSCODE
)) {
576 /* The case here is that our station was waiting for association response frame and has just received it containing status code
577 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
578 u16ConnectStatus
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
579 linux_wlan_set_bssid(priv
->dev
, NullBssid
);
580 memset(u8ConnectedSSID
, 0, ETH_ALEN
);
583 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
585 if (!pstrWFIDrv
->u8P2PConnect
)
586 u8WLANChannel
= INVALID_CHANNEL
;
589 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus
, u8MacStatus
);
592 if (u16ConnectStatus
== WLAN_STATUS_SUCCESS
) {
593 bool bNeedScanRefresh
= false;
596 PRINT_INFO(CFG80211_DBG
, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo
->au8bssid
[0],
597 pstrConnectInfo
->au8bssid
[1], pstrConnectInfo
->au8bssid
[2], pstrConnectInfo
->au8bssid
[3], pstrConnectInfo
->au8bssid
[4], pstrConnectInfo
->au8bssid
[5]);
598 memcpy(priv
->au8AssociatedBss
, pstrConnectInfo
->au8bssid
, ETH_ALEN
);
600 /* BugID_4209: if this network has expired in the scan results in the above nl80211 layer, refresh them here by calling
601 * cfg80211_inform_bss() with the last Scan results before calling cfg80211_connect_result() to avoid
602 * Linux kernel warning generated at the nl80211 layer */
604 for (i
= 0; i
< u32LastScannedNtwrksCountShadow
; i
++) {
605 if (memcmp(astrLastScannedNtwrksShadow
[i
].au8bssid
,
606 pstrConnectInfo
->au8bssid
, ETH_ALEN
) == 0) {
607 unsigned long now
= jiffies
;
610 astrLastScannedNtwrksShadow
[i
].u32TimeRcvdInScanCached
+ (unsigned long)(nl80211_SCAN_RESULT_EXPIRE
- (1 * HZ
)))) {
611 bNeedScanRefresh
= true;
618 if (bNeedScanRefresh
) {
620 /*Also, refrsh DIRECT- results if */
621 refresh_scan(priv
, 1, true);
628 PRINT_D(CFG80211_DBG
, "Association request info elements length = %zu\n", pstrConnectInfo
->ReqIEsLen
);
630 PRINT_D(CFG80211_DBG
, "Association response info elements length = %d\n", pstrConnectInfo
->u16RespIEsLen
);
632 cfg80211_connect_result(dev
, pstrConnectInfo
->au8bssid
,
633 pstrConnectInfo
->pu8ReqIEs
, pstrConnectInfo
->ReqIEsLen
,
634 pstrConnectInfo
->pu8RespIEs
, pstrConnectInfo
->u16RespIEsLen
,
635 u16ConnectStatus
, GFP_KERNEL
); /* TODO: mostafa: u16ConnectStatus to */
636 /* be replaced by pstrConnectInfo->u16ConnectStatus */
637 } else if (enuConnDisconnEvent
== CONN_DISCONN_EVENT_DISCONN_NOTIF
) {
638 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
639 g_obtainingIP
= false;
641 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
642 pstrDisconnectNotifInfo
->u16reason
, priv
->dev
);
643 u8P2Plocalrandom
= 0x01;
644 u8P2Precvrandom
= 0x00;
646 memset(priv
->au8AssociatedBss
, 0, ETH_ALEN
);
647 linux_wlan_set_bssid(priv
->dev
, NullBssid
);
648 memset(u8ConnectedSSID
, 0, ETH_ALEN
);
651 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
653 if (!pstrWFIDrv
->u8P2PConnect
)
654 u8WLANChannel
= INVALID_CHANNEL
;
657 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
658 * virtual interface to station*/
659 if ((pstrWFIDrv
->IFC_UP
) && (dev
== g_linux_wlan
->strInterfaceInfo
[1].wilc_netdev
)) {
660 pstrDisconnectNotifInfo
->u16reason
= 3;
663 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
664 * to scan again and retry the connection*/
665 else if ((!pstrWFIDrv
->IFC_UP
) && (dev
== g_linux_wlan
->strInterfaceInfo
[1].wilc_netdev
)) {
666 pstrDisconnectNotifInfo
->u16reason
= 1;
668 cfg80211_disconnected(dev
, pstrDisconnectNotifInfo
->u16reason
, pstrDisconnectNotifInfo
->ie
,
669 pstrDisconnectNotifInfo
->ie_len
, false,
679 * @details Set channel for a given wireless interface. Some devices
680 * may support multi-channel operation (by channel hopping) so cfg80211
681 * doesn't verify much. Note, however, that the passed netdev may be
682 * %NULL as well if the user requested changing the channel for the
683 * device itself, or for a monitor interface.
685 * @return int : Return 0 on Success
690 static int set_channel(struct wiphy
*wiphy
,
691 struct cfg80211_chan_def
*chandef
)
695 struct wilc_priv
*priv
;
698 priv
= wiphy_priv(wiphy
);
700 channelnum
= ieee80211_frequency_to_channel(chandef
->chan
->center_freq
);
701 PRINT_D(CFG80211_DBG
, "Setting channel %d with frequency %d\n", channelnum
, chandef
->chan
->center_freq
);
703 u8CurrChannel
= channelnum
;
704 s32Error
= host_int_set_mac_chnl_num(priv
->hWILCWFIDrv
, channelnum
);
707 PRINT_ER("Error in setting channel %d\n", channelnum
);
714 * @details Request to do a scan. If returning zero, the scan request is given
715 * the driver, and will be valid until passed to cfg80211_scan_done().
716 * For scan results, call cfg80211_inform_bss(); you can call this outside
717 * the scan/scan_done bracket too.
719 * @return int : Return 0 on Success
726 * kernel version 3.8.8 supported
727 * tony, sswd, WILC-KR, 2013-10-29
729 static int scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
731 struct wilc_priv
*priv
;
734 u8 au8ScanChanList
[MAX_NUM_SCANNED_NETWORKS
];
735 tstrHiddenNetwork strHiddenNetwork
;
737 priv
= wiphy_priv(wiphy
);
739 priv
->pstrScanReq
= request
;
741 priv
->u32RcvdChCount
= 0;
743 host_int_set_wfi_drv_handler(priv
->hWILCWFIDrv
);
746 reset_shadow_found(priv
);
748 priv
->bCfgScanning
= true;
749 if (request
->n_channels
<= MAX_NUM_SCANNED_NETWORKS
) { /* TODO: mostafa: to be replaced by */
751 for (i
= 0; i
< request
->n_channels
; i
++) {
752 au8ScanChanList
[i
] = (u8
)ieee80211_frequency_to_channel(request
->channels
[i
]->center_freq
);
753 PRINT_INFO(CFG80211_DBG
, "ScanChannel List[%d] = %d,", i
, au8ScanChanList
[i
]);
756 PRINT_D(CFG80211_DBG
, "Requested num of scan channel %d\n", request
->n_channels
);
757 PRINT_D(CFG80211_DBG
, "Scan Request IE len = %zu\n", request
->ie_len
);
759 PRINT_D(CFG80211_DBG
, "Number of SSIDs %d\n", request
->n_ssids
);
761 if (request
->n_ssids
>= 1) {
764 strHiddenNetwork
.pstrHiddenNetworkInfo
= kmalloc(request
->n_ssids
* sizeof(tstrHiddenNetwork
), GFP_KERNEL
);
765 strHiddenNetwork
.u8ssidnum
= request
->n_ssids
;
769 for (i
= 0; i
< request
->n_ssids
; i
++) {
771 if (request
->ssids
[i
].ssid
!= NULL
&& request
->ssids
[i
].ssid_len
!= 0) {
772 strHiddenNetwork
.pstrHiddenNetworkInfo
[i
].pu8ssid
= kmalloc(request
->ssids
[i
].ssid_len
, GFP_KERNEL
);
773 memcpy(strHiddenNetwork
.pstrHiddenNetworkInfo
[i
].pu8ssid
, request
->ssids
[i
].ssid
, request
->ssids
[i
].ssid_len
);
774 strHiddenNetwork
.pstrHiddenNetworkInfo
[i
].u8ssidlen
= request
->ssids
[i
].ssid_len
;
776 PRINT_D(CFG80211_DBG
, "Received one NULL SSID\n");
777 strHiddenNetwork
.u8ssidnum
-= 1;
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
, &strHiddenNetwork
);
786 PRINT_D(CFG80211_DBG
, "Trigger Scan Request\n");
787 s32Error
= host_int_scan(priv
->hWILCWFIDrv
, USER_SCAN
, ACTIVE_SCAN
,
788 au8ScanChanList
, request
->n_channels
,
789 (const u8
*)request
->ie
, request
->ie_len
,
790 CfgScanResult
, (void *)priv
, NULL
);
794 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
800 PRINT_WRN(CFG80211_DBG
, "Device is busy: Error(%d)\n", s32Error
);
808 * @details Connect to the ESS with the specified parameters. When connected,
809 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
810 * If the connection fails for some reason, call cfg80211_connect_result()
811 * with the status from the AP.
813 * @return int : Return 0 on Success
818 static int connect(struct wiphy
*wiphy
, struct net_device
*dev
,
819 struct cfg80211_connect_params
*sme
)
823 u8 u8security
= NO_ENCRYPT
;
824 AUTHTYPE_T tenuAuth_type
= ANY
;
825 char *pcgroup_encrypt_val
= NULL
;
826 char *pccipher_group
= NULL
;
827 char *pcwpa_version
= NULL
;
829 struct wilc_priv
*priv
;
830 tstrWILC_WFIDrv
*pstrWFIDrv
;
831 tstrNetworkInfo
*pstrNetworkInfo
= NULL
;
835 priv
= wiphy_priv(wiphy
);
836 pstrWFIDrv
= (tstrWILC_WFIDrv
*)(priv
->hWILCWFIDrv
);
838 host_int_set_wfi_drv_handler(priv
->hWILCWFIDrv
);
840 PRINT_D(CFG80211_DBG
, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme
->ssid
, dev
, priv
->hWILCWFIDrv
);
842 if (!(strncmp(sme
->ssid
, "DIRECT-", 7))) {
843 PRINT_D(CFG80211_DBG
, "Connected to Direct network,OBSS disabled\n");
844 pstrWFIDrv
->u8P2PConnect
= 1;
846 pstrWFIDrv
->u8P2PConnect
= 0;
848 PRINT_INFO(CFG80211_DBG
, "Required SSID = %s\n , AuthType = %d\n", sme
->ssid
, sme
->auth_type
);
850 for (i
= 0; i
< u32LastScannedNtwrksCountShadow
; i
++) {
851 if ((sme
->ssid_len
== astrLastScannedNtwrksShadow
[i
].u8SsidLen
) &&
852 memcmp(astrLastScannedNtwrksShadow
[i
].au8ssid
,
854 sme
->ssid_len
) == 0) {
855 PRINT_INFO(CFG80211_DBG
, "Network with required SSID is found %s\n", sme
->ssid
);
856 if (sme
->bssid
== NULL
) {
857 /* BSSID is not passed from the user, so decision of matching
858 * is done by SSID only */
859 PRINT_INFO(CFG80211_DBG
, "BSSID is not passed from the user\n");
862 /* BSSID is also passed from the user, so decision of matching
863 * should consider also this passed BSSID */
864 if (memcmp(astrLastScannedNtwrksShadow
[i
].au8bssid
,
867 PRINT_INFO(CFG80211_DBG
, "BSSID is passed from the user and matched\n");
874 if (i
< u32LastScannedNtwrksCountShadow
) {
875 PRINT_D(CFG80211_DBG
, "Required bss is in scan results\n");
877 pstrNetworkInfo
= &(astrLastScannedNtwrksShadow
[i
]);
879 PRINT_INFO(CFG80211_DBG
, "network BSSID to be associated: %x%x%x%x%x%x\n",
880 pstrNetworkInfo
->au8bssid
[0], pstrNetworkInfo
->au8bssid
[1],
881 pstrNetworkInfo
->au8bssid
[2], pstrNetworkInfo
->au8bssid
[3],
882 pstrNetworkInfo
->au8bssid
[4], pstrNetworkInfo
->au8bssid
[5]);
885 if (u32LastScannedNtwrksCountShadow
== 0)
886 PRINT_D(CFG80211_DBG
, "No Scan results yet\n");
888 PRINT_D(CFG80211_DBG
, "Required bss not in scan results: Error(%d)\n", s32Error
);
893 priv
->WILC_WFI_wep_default
= 0;
894 memset(priv
->WILC_WFI_wep_key
, 0, sizeof(priv
->WILC_WFI_wep_key
));
895 memset(priv
->WILC_WFI_wep_key_len
, 0, sizeof(priv
->WILC_WFI_wep_key_len
));
897 PRINT_INFO(CFG80211_DBG
, "sme->crypto.wpa_versions=%x\n", sme
->crypto
.wpa_versions
);
898 PRINT_INFO(CFG80211_DBG
, "sme->crypto.cipher_group=%x\n", sme
->crypto
.cipher_group
);
900 PRINT_INFO(CFG80211_DBG
, "sme->crypto.n_ciphers_pairwise=%d\n", sme
->crypto
.n_ciphers_pairwise
);
903 for (i
= 0; i
< sme
->crypto
.n_ciphers_pairwise
; i
++)
904 PRINT_D(CORECONFIG_DBG
, "sme->crypto.ciphers_pairwise[%d]=%x\n", i
, sme
->crypto
.ciphers_pairwise
[i
]);
907 if (sme
->crypto
.cipher_group
!= NO_ENCRYPT
) {
908 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
909 * we will add to it the pairwise cipher suite(s) */
910 pcwpa_version
= "Default";
911 PRINT_D(CORECONFIG_DBG
, ">> sme->crypto.wpa_versions: %x\n", sme
->crypto
.wpa_versions
);
912 if (sme
->crypto
.cipher_group
== WLAN_CIPHER_SUITE_WEP40
) {
913 u8security
= ENCRYPT_ENABLED
| WEP
;
914 pcgroup_encrypt_val
= "WEP40";
915 pccipher_group
= "WLAN_CIPHER_SUITE_WEP40";
916 PRINT_INFO(CFG80211_DBG
, "WEP Default Key Idx = %d\n", sme
->key_idx
);
919 for (i
= 0; i
< sme
->key_len
; i
++)
920 PRINT_D(CORECONFIG_DBG
, "WEP Key Value[%d] = %d\n", i
, sme
->key
[i
]);
922 priv
->WILC_WFI_wep_default
= sme
->key_idx
;
923 priv
->WILC_WFI_wep_key_len
[sme
->key_idx
] = sme
->key_len
;
924 memcpy(priv
->WILC_WFI_wep_key
[sme
->key_idx
], sme
->key
, sme
->key_len
);
927 g_key_wep_params
.key_len
= sme
->key_len
;
928 g_key_wep_params
.key
= kmalloc(sme
->key_len
, GFP_KERNEL
);
929 memcpy(g_key_wep_params
.key
, sme
->key
, sme
->key_len
);
930 g_key_wep_params
.key_idx
= sme
->key_idx
;
931 g_wep_keys_saved
= true;
933 host_int_set_WEPDefaultKeyID(priv
->hWILCWFIDrv
, sme
->key_idx
);
934 host_int_add_wep_key_bss_sta(priv
->hWILCWFIDrv
, sme
->key
, sme
->key_len
, sme
->key_idx
);
935 } else if (sme
->crypto
.cipher_group
== WLAN_CIPHER_SUITE_WEP104
) {
936 u8security
= ENCRYPT_ENABLED
| WEP
| WEP_EXTENDED
;
937 pcgroup_encrypt_val
= "WEP104";
938 pccipher_group
= "WLAN_CIPHER_SUITE_WEP104";
940 priv
->WILC_WFI_wep_default
= sme
->key_idx
;
941 priv
->WILC_WFI_wep_key_len
[sme
->key_idx
] = sme
->key_len
;
942 memcpy(priv
->WILC_WFI_wep_key
[sme
->key_idx
], sme
->key
, sme
->key_len
);
945 g_key_wep_params
.key_len
= sme
->key_len
;
946 g_key_wep_params
.key
= kmalloc(sme
->key_len
, GFP_KERNEL
);
947 memcpy(g_key_wep_params
.key
, sme
->key
, sme
->key_len
);
948 g_key_wep_params
.key_idx
= sme
->key_idx
;
949 g_wep_keys_saved
= true;
951 host_int_set_WEPDefaultKeyID(priv
->hWILCWFIDrv
, sme
->key_idx
);
952 host_int_add_wep_key_bss_sta(priv
->hWILCWFIDrv
, sme
->key
, sme
->key_len
, sme
->key_idx
);
953 } else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
) {
954 if (sme
->crypto
.cipher_group
== WLAN_CIPHER_SUITE_TKIP
) {
955 u8security
= ENCRYPT_ENABLED
| WPA2
| TKIP
;
956 pcgroup_encrypt_val
= "WPA2_TKIP";
957 pccipher_group
= "TKIP";
958 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
959 /* tenuSecurity_t = WPA2_AES; */
960 u8security
= ENCRYPT_ENABLED
| WPA2
| AES
;
961 pcgroup_encrypt_val
= "WPA2_AES";
962 pccipher_group
= "AES";
964 pcwpa_version
= "WPA_VERSION_2";
965 } else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
) {
966 if (sme
->crypto
.cipher_group
== WLAN_CIPHER_SUITE_TKIP
) {
967 u8security
= ENCRYPT_ENABLED
| WPA
| TKIP
;
968 pcgroup_encrypt_val
= "WPA_TKIP";
969 pccipher_group
= "TKIP";
970 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
971 /* tenuSecurity_t = WPA_AES; */
972 u8security
= ENCRYPT_ENABLED
| WPA
| AES
;
973 pcgroup_encrypt_val
= "WPA_AES";
974 pccipher_group
= "AES";
977 pcwpa_version
= "WPA_VERSION_1";
980 s32Error
= -ENOTSUPP
;
981 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error
);
988 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
989 * add to it the pairwise cipher suite(s) */
990 if ((sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
991 || (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)) {
992 for (i
= 0; i
< sme
->crypto
.n_ciphers_pairwise
; i
++) {
993 if (sme
->crypto
.ciphers_pairwise
[i
] == WLAN_CIPHER_SUITE_TKIP
) {
994 u8security
= u8security
| TKIP
;
995 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
996 u8security
= u8security
| AES
;
1001 PRINT_D(CFG80211_DBG
, "Adding key with cipher group = %x\n", sme
->crypto
.cipher_group
);
1003 PRINT_D(CFG80211_DBG
, "Authentication Type = %d\n", sme
->auth_type
);
1004 switch (sme
->auth_type
) {
1005 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1006 PRINT_D(CFG80211_DBG
, "In OPEN SYSTEM\n");
1007 tenuAuth_type
= OPEN_SYSTEM
;
1010 case NL80211_AUTHTYPE_SHARED_KEY
:
1011 tenuAuth_type
= SHARED_KEY
;
1012 PRINT_D(CFG80211_DBG
, "In SHARED KEY\n");
1016 PRINT_D(CFG80211_DBG
, "Automatic Authentation type = %d\n", sme
->auth_type
);
1020 /* ai: key_mgmt: enterprise case */
1021 if (sme
->crypto
.n_akm_suites
) {
1022 switch (sme
->crypto
.akm_suites
[0]) {
1023 case WLAN_AKM_SUITE_8021X
:
1024 tenuAuth_type
= IEEE8021
;
1033 PRINT_INFO(CFG80211_DBG
, "Required Channel = %d\n", pstrNetworkInfo
->u8channel
);
1035 PRINT_INFO(CFG80211_DBG
, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1036 pcgroup_encrypt_val
, pccipher_group
, pcwpa_version
);
1039 u8CurrChannel
= pstrNetworkInfo
->u8channel
;
1041 if (!pstrWFIDrv
->u8P2PConnect
) {
1042 u8WLANChannel
= pstrNetworkInfo
->u8channel
;
1045 linux_wlan_set_bssid(dev
, pstrNetworkInfo
->au8bssid
);
1047 s32Error
= host_int_set_join_req(priv
->hWILCWFIDrv
, pstrNetworkInfo
->au8bssid
, sme
->ssid
,
1048 sme
->ssid_len
, sme
->ie
, sme
->ie_len
,
1049 CfgConnectResult
, (void *)priv
, u8security
,
1050 tenuAuth_type
, pstrNetworkInfo
->u8channel
,
1051 pstrNetworkInfo
->pJoinParams
);
1052 if (s32Error
!= 0) {
1053 PRINT_ER("host_int_set_join_req(): Error(%d)\n", s32Error
);
1066 * @details Disconnect from the BSS/ESS.
1068 * @return int : Return 0 on Success
1073 static int disconnect(struct wiphy
*wiphy
, struct net_device
*dev
, u16 reason_code
)
1076 struct wilc_priv
*priv
;
1078 tstrWILC_WFIDrv
*pstrWFIDrv
;
1080 u8 NullBssid
[ETH_ALEN
] = {0};
1083 priv
= wiphy_priv(wiphy
);
1086 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
1088 pstrWFIDrv
= (tstrWILC_WFIDrv
*)priv
->hWILCWFIDrv
;
1089 if (!pstrWFIDrv
->u8P2PConnect
)
1090 u8WLANChannel
= INVALID_CHANNEL
;
1092 linux_wlan_set_bssid(priv
->dev
, NullBssid
);
1094 PRINT_D(CFG80211_DBG
, "Disconnecting with reason code(%d)\n", reason_code
);
1096 u8P2Plocalrandom
= 0x01;
1097 u8P2Precvrandom
= 0x00;
1100 pstrWFIDrv
->u64P2p_MgmtTimeout
= 0;
1103 s32Error
= host_int_disconnect(priv
->hWILCWFIDrv
, reason_code
);
1104 if (s32Error
!= 0) {
1105 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error
);
1114 * @details Add a key with the given parameters. @mac_addr will be %NULL
1115 * when adding a group key.
1116 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1117 * @return int : Return 0 on Success
1122 static int add_key(struct wiphy
*wiphy
, struct net_device
*netdev
, u8 key_index
,
1124 const u8
*mac_addr
, struct key_params
*params
)
1127 s32 s32Error
= 0, KeyLen
= params
->key_len
;
1129 struct wilc_priv
*priv
;
1130 const u8
*pu8RxMic
= NULL
;
1131 const u8
*pu8TxMic
= NULL
;
1132 u8 u8mode
= NO_ENCRYPT
;
1133 #ifdef WILC_AP_EXTERNAL_MLME
1134 u8 u8gmode
= NO_ENCRYPT
;
1135 u8 u8pmode
= NO_ENCRYPT
;
1136 AUTHTYPE_T tenuAuth_type
= ANY
;
1139 priv
= wiphy_priv(wiphy
);
1141 PRINT_D(CFG80211_DBG
, "Adding key with cipher suite = %x\n", params
->cipher
);
1144 PRINT_D(CFG80211_DBG
, "%p %p %d\n", wiphy
, netdev
, key_index
);
1146 PRINT_D(CFG80211_DBG
, "key %x %x %x\n", params
->key
[0],
1151 switch (params
->cipher
) {
1152 case WLAN_CIPHER_SUITE_WEP40
:
1153 case WLAN_CIPHER_SUITE_WEP104
:
1154 #ifdef WILC_AP_EXTERNAL_MLME
1155 if (priv
->wdev
->iftype
== NL80211_IFTYPE_AP
) {
1157 priv
->WILC_WFI_wep_default
= key_index
;
1158 priv
->WILC_WFI_wep_key_len
[key_index
] = params
->key_len
;
1159 memcpy(priv
->WILC_WFI_wep_key
[key_index
], params
->key
, params
->key_len
);
1161 PRINT_D(CFG80211_DBG
, "Adding AP WEP Default key Idx = %d\n", key_index
);
1162 PRINT_D(CFG80211_DBG
, "Adding AP WEP Key len= %d\n", params
->key_len
);
1164 for (i
= 0; i
< params
->key_len
; i
++)
1165 PRINT_D(CFG80211_DBG
, "WEP AP key val[%d] = %x\n", i
, params
->key
[i
]);
1167 tenuAuth_type
= OPEN_SYSTEM
;
1169 if (params
->cipher
== WLAN_CIPHER_SUITE_WEP40
)
1170 u8mode
= ENCRYPT_ENABLED
| WEP
;
1172 u8mode
= ENCRYPT_ENABLED
| WEP
| WEP_EXTENDED
;
1174 host_int_add_wep_key_bss_ap(priv
->hWILCWFIDrv
, params
->key
, params
->key_len
, key_index
, u8mode
, tenuAuth_type
);
1178 if (memcmp(params
->key
, priv
->WILC_WFI_wep_key
[key_index
], params
->key_len
)) {
1179 priv
->WILC_WFI_wep_default
= key_index
;
1180 priv
->WILC_WFI_wep_key_len
[key_index
] = params
->key_len
;
1181 memcpy(priv
->WILC_WFI_wep_key
[key_index
], params
->key
, params
->key_len
);
1183 PRINT_D(CFG80211_DBG
, "Adding WEP Default key Idx = %d\n", key_index
);
1184 PRINT_D(CFG80211_DBG
, "Adding WEP Key length = %d\n", params
->key_len
);
1186 for (i
= 0; i
< params
->key_len
; i
++)
1187 PRINT_INFO(CFG80211_DBG
, "WEP key value[%d] = %d\n", i
, params
->key
[i
]);
1189 host_int_add_wep_key_bss_sta(priv
->hWILCWFIDrv
, params
->key
, params
->key_len
, key_index
);
1194 case WLAN_CIPHER_SUITE_TKIP
:
1195 case WLAN_CIPHER_SUITE_CCMP
:
1196 #ifdef WILC_AP_EXTERNAL_MLME
1197 if (priv
->wdev
->iftype
== NL80211_IFTYPE_AP
|| priv
->wdev
->iftype
== NL80211_IFTYPE_P2P_GO
) {
1199 if (priv
->wilc_gtk
[key_index
] == NULL
) {
1200 priv
->wilc_gtk
[key_index
] = kmalloc(sizeof(struct wilc_wfi_key
), GFP_KERNEL
);
1201 priv
->wilc_gtk
[key_index
]->key
= NULL
;
1202 priv
->wilc_gtk
[key_index
]->seq
= NULL
;
1205 if (priv
->wilc_ptk
[key_index
] == NULL
) {
1206 priv
->wilc_ptk
[key_index
] = kmalloc(sizeof(struct wilc_wfi_key
), GFP_KERNEL
);
1207 priv
->wilc_ptk
[key_index
]->key
= NULL
;
1208 priv
->wilc_ptk
[key_index
]->seq
= NULL
;
1214 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
)
1215 u8gmode
= ENCRYPT_ENABLED
| WPA
| TKIP
;
1217 u8gmode
= ENCRYPT_ENABLED
| WPA2
| AES
;
1219 priv
->wilc_groupkey
= u8gmode
;
1221 if (params
->key_len
> 16 && params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1223 pu8TxMic
= params
->key
+ 24;
1224 pu8RxMic
= params
->key
+ 16;
1225 KeyLen
= params
->key_len
- 16;
1227 /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
1228 if (priv
->wilc_gtk
[key_index
]->key
)
1229 kfree(priv
->wilc_gtk
[key_index
]->key
);
1231 priv
->wilc_gtk
[key_index
]->key
= kmalloc(params
->key_len
, GFP_KERNEL
);
1232 memcpy(priv
->wilc_gtk
[key_index
]->key
, params
->key
, params
->key_len
);
1234 /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
1235 if (priv
->wilc_gtk
[key_index
]->seq
)
1236 kfree(priv
->wilc_gtk
[key_index
]->seq
);
1238 if ((params
->seq_len
) > 0) {
1239 priv
->wilc_gtk
[key_index
]->seq
= kmalloc(params
->seq_len
, GFP_KERNEL
);
1240 memcpy(priv
->wilc_gtk
[key_index
]->seq
, params
->seq
, params
->seq_len
);
1243 priv
->wilc_gtk
[key_index
]->cipher
= params
->cipher
;
1244 priv
->wilc_gtk
[key_index
]->key_len
= params
->key_len
;
1245 priv
->wilc_gtk
[key_index
]->seq_len
= params
->seq_len
;
1248 for (i
= 0; i
< params
->key_len
; i
++)
1249 PRINT_INFO(CFG80211_DBG
, "Adding group key value[%d] = %x\n", i
, params
->key
[i
]);
1250 for (i
= 0; i
< params
->seq_len
; i
++)
1251 PRINT_INFO(CFG80211_DBG
, "Adding group seq value[%d] = %x\n", i
, params
->seq
[i
]);
1255 host_int_add_rx_gtk(priv
->hWILCWFIDrv
, params
->key
, KeyLen
,
1256 key_index
, params
->seq_len
, params
->seq
, pu8RxMic
, pu8TxMic
, AP_MODE
, u8gmode
);
1259 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]);
1261 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
)
1262 u8pmode
= ENCRYPT_ENABLED
| WPA
| TKIP
;
1264 u8pmode
= priv
->wilc_groupkey
| AES
;
1267 if (params
->key_len
> 16 && params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1269 pu8TxMic
= params
->key
+ 24;
1270 pu8RxMic
= params
->key
+ 16;
1271 KeyLen
= params
->key_len
- 16;
1274 if (priv
->wilc_ptk
[key_index
]->key
)
1275 kfree(priv
->wilc_ptk
[key_index
]->key
);
1277 priv
->wilc_ptk
[key_index
]->key
= kmalloc(params
->key_len
, GFP_KERNEL
);
1279 if (priv
->wilc_ptk
[key_index
]->seq
)
1280 kfree(priv
->wilc_ptk
[key_index
]->seq
);
1282 if ((params
->seq_len
) > 0)
1283 priv
->wilc_ptk
[key_index
]->seq
= kmalloc(params
->seq_len
, GFP_KERNEL
);
1286 for (i
= 0; i
< params
->key_len
; i
++)
1287 PRINT_INFO(CFG80211_DBG
, "Adding pairwise key value[%d] = %x\n", i
, params
->key
[i
]);
1289 for (i
= 0; i
< params
->seq_len
; i
++)
1290 PRINT_INFO(CFG80211_DBG
, "Adding group seq value[%d] = %x\n", i
, params
->seq
[i
]);
1293 memcpy(priv
->wilc_ptk
[key_index
]->key
, params
->key
, params
->key_len
);
1295 if ((params
->seq_len
) > 0)
1296 memcpy(priv
->wilc_ptk
[key_index
]->seq
, params
->seq
, params
->seq_len
);
1298 priv
->wilc_ptk
[key_index
]->cipher
= params
->cipher
;
1299 priv
->wilc_ptk
[key_index
]->key_len
= params
->key_len
;
1300 priv
->wilc_ptk
[key_index
]->seq_len
= params
->seq_len
;
1302 host_int_add_ptk(priv
->hWILCWFIDrv
, params
->key
, KeyLen
, mac_addr
,
1303 pu8RxMic
, pu8TxMic
, AP_MODE
, u8pmode
, key_index
);
1312 if (params
->key_len
> 16 && params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1313 /* swap the tx mic by rx mic */
1314 pu8RxMic
= params
->key
+ 24;
1315 pu8TxMic
= params
->key
+ 16;
1316 KeyLen
= params
->key_len
- 16;
1320 /*save keys only on interface 0 (wifi interface)*/
1321 if (!g_gtk_keys_saved
&& netdev
== g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
) {
1322 g_add_gtk_key_params
.key_idx
= key_index
;
1323 g_add_gtk_key_params
.pairwise
= pairwise
;
1325 g_add_gtk_key_params
.mac_addr
= NULL
;
1327 g_add_gtk_key_params
.mac_addr
= kmalloc(ETH_ALEN
, GFP_KERNEL
);
1328 memcpy(g_add_gtk_key_params
.mac_addr
, mac_addr
, ETH_ALEN
);
1330 g_key_gtk_params
.key_len
= params
->key_len
;
1331 g_key_gtk_params
.seq_len
= params
->seq_len
;
1332 g_key_gtk_params
.key
= kmalloc(params
->key_len
, GFP_KERNEL
);
1333 memcpy(g_key_gtk_params
.key
, params
->key
, params
->key_len
);
1334 if (params
->seq_len
> 0) {
1335 g_key_gtk_params
.seq
= kmalloc(params
->seq_len
, GFP_KERNEL
);
1336 memcpy(g_key_gtk_params
.seq
, params
->seq
, params
->seq_len
);
1338 g_key_gtk_params
.cipher
= params
->cipher
;
1340 PRINT_D(CFG80211_DBG
, "key %x %x %x\n", g_key_gtk_params
.key
[0],
1341 g_key_gtk_params
.key
[1],
1342 g_key_gtk_params
.key
[2]);
1343 g_gtk_keys_saved
= true;
1346 host_int_add_rx_gtk(priv
->hWILCWFIDrv
, params
->key
, KeyLen
,
1347 key_index
, params
->seq_len
, params
->seq
, pu8RxMic
, pu8TxMic
, STATION_MODE
, u8mode
);
1349 if (params
->key_len
> 16 && params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1350 /* swap the tx mic by rx mic */
1351 pu8RxMic
= params
->key
+ 24;
1352 pu8TxMic
= params
->key
+ 16;
1353 KeyLen
= params
->key_len
- 16;
1357 /*save keys only on interface 0 (wifi interface)*/
1358 if (!g_ptk_keys_saved
&& netdev
== g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
) {
1359 g_add_ptk_key_params
.key_idx
= key_index
;
1360 g_add_ptk_key_params
.pairwise
= pairwise
;
1362 g_add_ptk_key_params
.mac_addr
= NULL
;
1364 g_add_ptk_key_params
.mac_addr
= kmalloc(ETH_ALEN
, GFP_KERNEL
);
1365 memcpy(g_add_ptk_key_params
.mac_addr
, mac_addr
, ETH_ALEN
);
1367 g_key_ptk_params
.key_len
= params
->key_len
;
1368 g_key_ptk_params
.seq_len
= params
->seq_len
;
1369 g_key_ptk_params
.key
= kmalloc(params
->key_len
, GFP_KERNEL
);
1370 memcpy(g_key_ptk_params
.key
, params
->key
, params
->key_len
);
1371 if (params
->seq_len
> 0) {
1372 g_key_ptk_params
.seq
= kmalloc(params
->seq_len
, GFP_KERNEL
);
1373 memcpy(g_key_ptk_params
.seq
, params
->seq
, params
->seq_len
);
1375 g_key_ptk_params
.cipher
= params
->cipher
;
1377 PRINT_D(CFG80211_DBG
, "key %x %x %x\n", g_key_ptk_params
.key
[0],
1378 g_key_ptk_params
.key
[1],
1379 g_key_ptk_params
.key
[2]);
1380 g_ptk_keys_saved
= true;
1383 host_int_add_ptk(priv
->hWILCWFIDrv
, params
->key
, KeyLen
, mac_addr
,
1384 pu8RxMic
, pu8TxMic
, STATION_MODE
, u8mode
, key_index
);
1385 PRINT_D(CFG80211_DBG
, "Adding pairwise key\n");
1387 for (i
= 0; i
< params
->key_len
; i
++)
1388 PRINT_INFO(CFG80211_DBG
, "Adding pairwise key value[%d] = %d\n", i
, params
->key
[i
]);
1395 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error
);
1396 s32Error
= -ENOTSUPP
;
1405 * @details Remove a key given the @mac_addr (%NULL for a group key)
1406 * and @key_index, return -ENOENT if the key doesn't exist.
1408 * @return int : Return 0 on Success
1413 static int del_key(struct wiphy
*wiphy
, struct net_device
*netdev
,
1418 struct wilc_priv
*priv
;
1421 priv
= wiphy_priv(wiphy
);
1424 /*delete saved keys, if any*/
1425 if (netdev
== g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
) {
1426 g_ptk_keys_saved
= false;
1427 g_gtk_keys_saved
= false;
1428 g_wep_keys_saved
= false;
1430 /*Delete saved WEP keys params, if any*/
1431 if (g_key_wep_params
.key
!= NULL
) {
1432 kfree(g_key_wep_params
.key
);
1433 g_key_wep_params
.key
= NULL
;
1436 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1438 #ifdef WILC_AP_EXTERNAL_MLME
1439 if ((priv
->wilc_gtk
[key_index
]) != NULL
) {
1441 if (priv
->wilc_gtk
[key_index
]->key
!= NULL
) {
1443 kfree(priv
->wilc_gtk
[key_index
]->key
);
1444 priv
->wilc_gtk
[key_index
]->key
= NULL
;
1446 if (priv
->wilc_gtk
[key_index
]->seq
) {
1448 kfree(priv
->wilc_gtk
[key_index
]->seq
);
1449 priv
->wilc_gtk
[key_index
]->seq
= NULL
;
1452 kfree(priv
->wilc_gtk
[key_index
]);
1453 priv
->wilc_gtk
[key_index
] = NULL
;
1457 if ((priv
->wilc_ptk
[key_index
]) != NULL
) {
1459 if (priv
->wilc_ptk
[key_index
]->key
) {
1461 kfree(priv
->wilc_ptk
[key_index
]->key
);
1462 priv
->wilc_ptk
[key_index
]->key
= NULL
;
1464 if (priv
->wilc_ptk
[key_index
]->seq
) {
1466 kfree(priv
->wilc_ptk
[key_index
]->seq
);
1467 priv
->wilc_ptk
[key_index
]->seq
= NULL
;
1469 kfree(priv
->wilc_ptk
[key_index
]);
1470 priv
->wilc_ptk
[key_index
] = NULL
;
1474 /*Delete saved PTK and GTK keys params, if any*/
1475 if (g_key_ptk_params
.key
!= NULL
) {
1476 kfree(g_key_ptk_params
.key
);
1477 g_key_ptk_params
.key
= NULL
;
1479 if (g_key_ptk_params
.seq
!= NULL
) {
1480 kfree(g_key_ptk_params
.seq
);
1481 g_key_ptk_params
.seq
= NULL
;
1484 if (g_key_gtk_params
.key
!= NULL
) {
1485 kfree(g_key_gtk_params
.key
);
1486 g_key_gtk_params
.key
= NULL
;
1488 if (g_key_gtk_params
.seq
!= NULL
) {
1489 kfree(g_key_gtk_params
.seq
);
1490 g_key_gtk_params
.seq
= NULL
;
1493 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
1494 Set_machw_change_vir_if(false);
1497 if (key_index
>= 0 && key_index
<= 3) {
1498 memset(priv
->WILC_WFI_wep_key
[key_index
], 0, priv
->WILC_WFI_wep_key_len
[key_index
]);
1499 priv
->WILC_WFI_wep_key_len
[key_index
] = 0;
1501 PRINT_D(CFG80211_DBG
, "Removing WEP key with index = %d\n", key_index
);
1502 host_int_remove_wep_key(priv
->hWILCWFIDrv
, key_index
);
1504 PRINT_D(CFG80211_DBG
, "Removing all installed keys\n");
1505 host_int_remove_key(priv
->hWILCWFIDrv
, mac_addr
);
1513 * @details Get information about the key with the given parameters.
1514 * @mac_addr will be %NULL when requesting information for a group
1515 * key. All pointers given to the @callback function need not be valid
1516 * after it returns. This function should return an error if it is
1517 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1519 * @return int : Return 0 on Success
1524 static int get_key(struct wiphy
*wiphy
, struct net_device
*netdev
, u8 key_index
,
1526 const u8
*mac_addr
, void *cookie
, void (*callback
)(void *cookie
, struct key_params
*))
1531 struct wilc_priv
*priv
;
1532 struct key_params key_params
;
1535 priv
= wiphy_priv(wiphy
);
1540 PRINT_D(CFG80211_DBG
, "Getting group key idx: %x\n", key_index
);
1542 key_params
.key
= priv
->wilc_gtk
[key_index
]->key
;
1543 key_params
.cipher
= priv
->wilc_gtk
[key_index
]->cipher
;
1544 key_params
.key_len
= priv
->wilc_gtk
[key_index
]->key_len
;
1545 key_params
.seq
= priv
->wilc_gtk
[key_index
]->seq
;
1546 key_params
.seq_len
= priv
->wilc_gtk
[key_index
]->seq_len
;
1548 for (i
= 0; i
< key_params
.key_len
; i
++)
1549 PRINT_INFO(CFG80211_DBG
, "Retrieved key value %x\n", key_params
.key
[i
]);
1552 PRINT_D(CFG80211_DBG
, "Getting pairwise key\n");
1554 key_params
.key
= priv
->wilc_ptk
[key_index
]->key
;
1555 key_params
.cipher
= priv
->wilc_ptk
[key_index
]->cipher
;
1556 key_params
.key_len
= priv
->wilc_ptk
[key_index
]->key_len
;
1557 key_params
.seq
= priv
->wilc_ptk
[key_index
]->seq
;
1558 key_params
.seq_len
= priv
->wilc_ptk
[key_index
]->seq_len
;
1561 callback(cookie
, &key_params
);
1563 return s32Error
; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
1567 * @brief set_default_key
1568 * @details Set the default management frame key on an interface
1570 * @return int : Return 0 on Success.
1575 static int set_default_key(struct wiphy
*wiphy
, struct net_device
*netdev
, u8 key_index
,
1576 bool unicast
, bool multicast
)
1579 struct wilc_priv
*priv
;
1582 priv
= wiphy_priv(wiphy
);
1584 PRINT_D(CFG80211_DBG
, "Setting default key with idx = %d\n", key_index
);
1586 if (key_index
!= priv
->WILC_WFI_wep_default
) {
1588 host_int_set_WEPDefaultKeyID(priv
->hWILCWFIDrv
, key_index
);
1595 * @brief WILC_WFI_dump_survey
1596 * @details Get site survey information
1598 * @return int : Return 0 on Success.
1603 static int WILC_WFI_dump_survey(struct wiphy
*wiphy
, struct net_device
*netdev
,
1604 int idx
, struct survey_info
*info
)
1611 PRINT_ER("Error Idx value doesn't equal zero: Error(%d)\n", s32Error
);
1620 * @brief get_station
1621 * @details Get station information for the station identified by @mac
1623 * @return int : Return 0 on Success.
1629 static int get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1630 const u8
*mac
, struct station_info
*sinfo
)
1633 struct wilc_priv
*priv
;
1634 perInterface_wlan_t
*nic
;
1635 #ifdef WILC_AP_EXTERNAL_MLME
1637 u32 associatedsta
= 0;
1638 u32 inactive_time
= 0;
1640 priv
= wiphy_priv(wiphy
);
1641 nic
= netdev_priv(dev
);
1643 #ifdef WILC_AP_EXTERNAL_MLME
1644 if (nic
->iftype
== AP_MODE
|| nic
->iftype
== GO_MODE
) {
1645 PRINT_D(HOSTAPD_DBG
, "Getting station parameters\n");
1647 PRINT_INFO(HOSTAPD_DBG
, ": %x%x%x%x%x\n", mac
[0], mac
[1], mac
[2], mac
[3], mac
[4]);
1649 for (i
= 0; i
< NUM_STA_ASSOCIATED
; i
++) {
1651 if (!(memcmp(mac
, priv
->assoc_stainfo
.au8Sta_AssociatedBss
[i
], ETH_ALEN
))) {
1658 if (associatedsta
== -1) {
1660 PRINT_ER("Station required is not associated : Error(%d)\n", s32Error
);
1665 sinfo
->filled
|= BIT(NL80211_STA_INFO_INACTIVE_TIME
);
1667 host_int_get_inactive_time(priv
->hWILCWFIDrv
, mac
, &(inactive_time
));
1668 sinfo
->inactive_time
= 1000 * inactive_time
;
1669 PRINT_D(CFG80211_DBG
, "Inactive time %d\n", sinfo
->inactive_time
);
1674 if (nic
->iftype
== STATION_MODE
) {
1675 tstrStatistics strStatistics
;
1677 host_int_get_statistics(priv
->hWILCWFIDrv
, &strStatistics
);
1681 * tx_failed introduced more than
1682 * kernel version 3.0.0
1684 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
) |
1685 BIT(NL80211_STA_INFO_RX_PACKETS
) |
1686 BIT(NL80211_STA_INFO_TX_PACKETS
) |
1687 BIT(NL80211_STA_INFO_TX_FAILED
) |
1688 BIT(NL80211_STA_INFO_TX_BITRATE
);
1690 sinfo
->signal
= strStatistics
.s8RSSI
;
1691 sinfo
->rx_packets
= strStatistics
.u32RxCount
;
1692 sinfo
->tx_packets
= strStatistics
.u32TxCount
+ strStatistics
.u32TxFailureCount
;
1693 sinfo
->tx_failed
= strStatistics
.u32TxFailureCount
;
1694 sinfo
->txrate
.legacy
= strStatistics
.u8LinkSpeed
* 10;
1696 #ifdef TCP_ENHANCEMENTS
1697 if ((strStatistics
.u8LinkSpeed
> TCP_ACK_FILTER_LINK_SPEED_THRESH
) && (strStatistics
.u8LinkSpeed
!= DEFAULT_LINK_SPEED
))
1698 Enable_TCP_ACK_Filter(true);
1699 else if (strStatistics
.u8LinkSpeed
!= DEFAULT_LINK_SPEED
)
1700 Enable_TCP_ACK_Filter(false);
1703 PRINT_D(CORECONFIG_DBG
, "*** stats[%d][%d][%d][%d][%d]\n", sinfo
->signal
, sinfo
->rx_packets
, sinfo
->tx_packets
,
1704 sinfo
->tx_failed
, sinfo
->txrate
.legacy
);
1712 * @details Modify parameters for a given BSS.
1714 * -use_cts_prot: Whether to use CTS protection
1715 * (0 = no, 1 = yes, -1 = do not change)
1716 * -use_short_preamble: Whether the use of short preambles is allowed
1717 * (0 = no, 1 = yes, -1 = do not change)
1718 * -use_short_slot_time: Whether the use of short slot time is allowed
1719 * (0 = no, 1 = yes, -1 = do not change)
1720 * -basic_rates: basic rates in IEEE 802.11 format
1721 * (or NULL for no change)
1722 * -basic_rates_len: number of basic rates
1723 * -ap_isolate: do not forward packets between connected stations
1724 * -ht_opmode: HT Operation mode
1725 * (u16 = opmode, -1 = do not change)
1726 * @return int : Return 0 on Success.
1731 static int change_bss(struct wiphy
*wiphy
, struct net_device
*dev
,
1732 struct bss_parameters
*params
)
1734 PRINT_D(CFG80211_DBG
, "Changing Bss parametrs\n");
1739 * @brief WILC_WFI_auth
1740 * @details Request to authenticate with the specified peer
1742 * @return int : Return 0 on Success.
1747 static int WILC_WFI_auth(struct wiphy
*wiphy
, struct net_device
*dev
,
1748 struct cfg80211_auth_request
*req
)
1750 PRINT_D(CFG80211_DBG
, "In Authentication Function\n");
1755 * @brief WILC_WFI_assoc
1756 * @details Request to (re)associate with the specified peer
1758 * @return int : Return 0 on Success.
1763 static int WILC_WFI_assoc(struct wiphy
*wiphy
, struct net_device
*dev
,
1764 struct cfg80211_assoc_request
*req
)
1766 PRINT_D(CFG80211_DBG
, "In Association Function\n");
1771 * @brief WILC_WFI_deauth
1772 * @details Request to deauthenticate from the specified peer
1774 * @return int : Return 0 on Success.
1779 static int WILC_WFI_deauth(struct wiphy
*wiphy
, struct net_device
*dev
,
1780 struct cfg80211_deauth_request
*req
, void *cookie
)
1782 PRINT_D(CFG80211_DBG
, "In De-authentication Function\n");
1787 * @brief WILC_WFI_disassoc
1788 * @details Request to disassociate from the specified peer
1790 * @return int : Return 0 on Success
1795 static int WILC_WFI_disassoc(struct wiphy
*wiphy
, struct net_device
*dev
,
1796 struct cfg80211_disassoc_request
*req
, void *cookie
)
1798 PRINT_D(CFG80211_DBG
, "In Disassociation Function\n");
1803 * @brief set_wiphy_params
1804 * @details Notify that wiphy parameters have changed;
1805 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1807 * @return int : Return 0 on Success
1812 static int set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1815 tstrCfgParamVal pstrCfgParamVal
;
1816 struct wilc_priv
*priv
;
1818 priv
= wiphy_priv(wiphy
);
1820 pstrCfgParamVal
.u32SetCfgFlag
= 0;
1821 PRINT_D(CFG80211_DBG
, "Setting Wiphy params\n");
1823 if (changed
& WIPHY_PARAM_RETRY_SHORT
) {
1824 PRINT_D(CFG80211_DBG
, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1825 priv
->dev
->ieee80211_ptr
->wiphy
->retry_short
);
1826 pstrCfgParamVal
.u32SetCfgFlag
|= RETRY_SHORT
;
1827 pstrCfgParamVal
.short_retry_limit
= priv
->dev
->ieee80211_ptr
->wiphy
->retry_short
;
1829 if (changed
& WIPHY_PARAM_RETRY_LONG
) {
1831 PRINT_D(CFG80211_DBG
, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv
->dev
->ieee80211_ptr
->wiphy
->retry_long
);
1832 pstrCfgParamVal
.u32SetCfgFlag
|= RETRY_LONG
;
1833 pstrCfgParamVal
.long_retry_limit
= priv
->dev
->ieee80211_ptr
->wiphy
->retry_long
;
1836 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
) {
1837 PRINT_D(CFG80211_DBG
, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv
->dev
->ieee80211_ptr
->wiphy
->frag_threshold
);
1838 pstrCfgParamVal
.u32SetCfgFlag
|= FRAG_THRESHOLD
;
1839 pstrCfgParamVal
.frag_threshold
= priv
->dev
->ieee80211_ptr
->wiphy
->frag_threshold
;
1843 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
) {
1844 PRINT_D(CFG80211_DBG
, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv
->dev
->ieee80211_ptr
->wiphy
->rts_threshold
);
1846 pstrCfgParamVal
.u32SetCfgFlag
|= RTS_THRESHOLD
;
1847 pstrCfgParamVal
.rts_threshold
= priv
->dev
->ieee80211_ptr
->wiphy
->rts_threshold
;
1851 PRINT_D(CFG80211_DBG
, "Setting CFG params in the host interface\n");
1852 s32Error
= hif_set_cfg(priv
->hWILCWFIDrv
, &pstrCfgParamVal
);
1854 PRINT_ER("Error in setting WIPHY PARAMS\n");
1861 * @brief WILC_WFI_set_bitrate_mask
1862 * @details set the bitrate mask configuration
1864 * @return int : Return 0 on Success
1869 static int WILC_WFI_set_bitrate_mask(struct wiphy
*wiphy
,
1870 struct net_device
*dev
, const u8
*peer
,
1871 const struct cfg80211_bitrate_mask
*mask
)
1875 PRINT_D(CFG80211_DBG
, "Setting Bitrate mask function\n");
1882 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1883 * devices running firmwares capable of generating the (re) association
1884 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1886 * @return int : Return 0 on Success
1891 static int set_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
,
1892 struct cfg80211_pmksa
*pmksa
)
1898 struct wilc_priv
*priv
= wiphy_priv(wiphy
);
1900 PRINT_D(CFG80211_DBG
, "Setting PMKSA\n");
1903 for (i
= 0; i
< priv
->pmkid_list
.numpmkid
; i
++) {
1904 if (!memcmp(pmksa
->bssid
, priv
->pmkid_list
.pmkidlist
[i
].bssid
,
1906 /*If bssid already exists and pmkid value needs to reset*/
1908 PRINT_D(CFG80211_DBG
, "PMKID already exists\n");
1912 if (i
< WILC_MAX_NUM_PMKIDS
) {
1913 PRINT_D(CFG80211_DBG
, "Setting PMKID in private structure\n");
1914 memcpy(priv
->pmkid_list
.pmkidlist
[i
].bssid
, pmksa
->bssid
,
1916 memcpy(priv
->pmkid_list
.pmkidlist
[i
].pmkid
, pmksa
->pmkid
,
1918 if (!(flag
== PMKID_FOUND
))
1919 priv
->pmkid_list
.numpmkid
++;
1921 PRINT_ER("Invalid PMKID index\n");
1926 PRINT_D(CFG80211_DBG
, "Setting pmkid in the host interface\n");
1927 s32Error
= host_int_set_pmkid_info(priv
->hWILCWFIDrv
, &priv
->pmkid_list
);
1934 * @details Delete a cached PMKID.
1936 * @return int : Return 0 on Success
1941 static int del_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
,
1942 struct cfg80211_pmksa
*pmksa
)
1949 struct wilc_priv
*priv
= wiphy_priv(wiphy
);
1951 PRINT_D(CFG80211_DBG
, "Deleting PMKSA keys\n");
1953 for (i
= 0; i
< priv
->pmkid_list
.numpmkid
; i
++) {
1954 if (!memcmp(pmksa
->bssid
, priv
->pmkid_list
.pmkidlist
[i
].bssid
,
1956 /*If bssid is found, reset the values*/
1957 PRINT_D(CFG80211_DBG
, "Reseting PMKID values\n");
1958 memset(&priv
->pmkid_list
.pmkidlist
[i
], 0, sizeof(tstrHostIFpmkid
));
1964 if (i
< priv
->pmkid_list
.numpmkid
&& priv
->pmkid_list
.numpmkid
> 0) {
1965 for (; i
< (priv
->pmkid_list
.numpmkid
- 1); i
++) {
1966 memcpy(priv
->pmkid_list
.pmkidlist
[i
].bssid
,
1967 priv
->pmkid_list
.pmkidlist
[i
+ 1].bssid
,
1969 memcpy(priv
->pmkid_list
.pmkidlist
[i
].pmkid
,
1970 priv
->pmkid_list
.pmkidlist
[i
].pmkid
,
1973 priv
->pmkid_list
.numpmkid
--;
1982 * @brief flush_pmksa
1983 * @details Flush all cached PMKIDs.
1985 * @return int : Return 0 on Success
1990 static int flush_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
)
1992 struct wilc_priv
*priv
= wiphy_priv(wiphy
);
1994 PRINT_D(CFG80211_DBG
, "Flushing PMKID key values\n");
1996 /*Get cashed Pmkids and set all with zeros*/
1997 memset(&priv
->pmkid_list
, 0, sizeof(tstrHostIFpmkidAttr
));
2005 * @brief WILC_WFI_CfgParseRxAction
2006 * @details Function parses the received frames and modifies the following attributes:
2009 * -Operating Channel
2011 * @param[in] u8* Buffer, u32 length
2018 void WILC_WFI_CfgParseRxAction(u8
*buf
, u32 len
)
2024 u8 op_channel_attr_index
= 0;
2025 u8 channel_list_attr_index
= 0;
2027 while (index
< len
) {
2028 if (buf
[index
] == GO_INTENT_ATTR_ID
) {
2029 buf
[index
+ 3] = (buf
[index
+ 3] & 0x01) | (0x00 << 1);
2032 if (buf
[index
] == CHANLIST_ATTR_ID
)
2033 channel_list_attr_index
= index
;
2034 else if (buf
[index
] == OPERCHAN_ATTR_ID
)
2035 op_channel_attr_index
= index
;
2036 index
+= buf
[index
+ 1] + 3; /* ID,Length byte */
2039 if (u8WLANChannel
!= INVALID_CHANNEL
)
2041 /*Modify channel list attribute*/
2042 if (channel_list_attr_index
) {
2043 PRINT_D(GENERIC_DBG
, "Modify channel list attribute\n");
2044 for (i
= channel_list_attr_index
+ 3; i
< ((channel_list_attr_index
+ 3) + buf
[channel_list_attr_index
+ 1]); i
++) {
2045 if (buf
[i
] == 0x51) {
2046 for (j
= i
+ 2; j
< ((i
+ 2) + buf
[i
+ 1]); j
++) {
2047 buf
[j
] = u8WLANChannel
;
2053 /*Modify operating channel attribute*/
2054 if (op_channel_attr_index
) {
2055 PRINT_D(GENERIC_DBG
, "Modify operating channel attribute\n");
2056 buf
[op_channel_attr_index
+ 6] = 0x51;
2057 buf
[op_channel_attr_index
+ 7] = u8WLANChannel
;
2063 * @brief WILC_WFI_CfgParseTxAction
2064 * @details Function parses the transmitted action frames and modifies the
2065 * GO Intent attribute
2066 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
2072 void WILC_WFI_CfgParseTxAction(u8
*buf
, u32 len
, bool bOperChan
, u8 iftype
)
2077 u8 op_channel_attr_index
= 0;
2078 u8 channel_list_attr_index
= 0;
2080 while (index
< len
) {
2081 if (buf
[index
] == GO_INTENT_ATTR_ID
) {
2082 buf
[index
+ 3] = (buf
[index
+ 3] & 0x01) | (0x0f << 1);
2087 if (buf
[index
] == CHANLIST_ATTR_ID
)
2088 channel_list_attr_index
= index
;
2089 else if (buf
[index
] == OPERCHAN_ATTR_ID
)
2090 op_channel_attr_index
= index
;
2091 index
+= buf
[index
+ 1] + 3; /* ID,Length byte */
2094 if (u8WLANChannel
!= INVALID_CHANNEL
&& bOperChan
)
2096 /*Modify channel list attribute*/
2097 if (channel_list_attr_index
) {
2098 PRINT_D(GENERIC_DBG
, "Modify channel list attribute\n");
2099 for (i
= channel_list_attr_index
+ 3; i
< ((channel_list_attr_index
+ 3) + buf
[channel_list_attr_index
+ 1]); i
++) {
2100 if (buf
[i
] == 0x51) {
2101 for (j
= i
+ 2; j
< ((i
+ 2) + buf
[i
+ 1]); j
++) {
2102 buf
[j
] = u8WLANChannel
;
2108 /*Modify operating channel attribute*/
2109 if (op_channel_attr_index
) {
2110 PRINT_D(GENERIC_DBG
, "Modify operating channel attribute\n");
2111 buf
[op_channel_attr_index
+ 6] = 0x51;
2112 buf
[op_channel_attr_index
+ 7] = u8WLANChannel
;
2117 /* @brief WILC_WFI_p2p_rx
2122 * @author Mai Daftedar
2127 void WILC_WFI_p2p_rx (struct net_device
*dev
, u8
*buff
, u32 size
)
2130 struct wilc_priv
*priv
;
2131 u32 header
, pkt_offset
;
2132 tstrWILC_WFIDrv
*pstrWFIDrv
;
2136 priv
= wiphy_priv(dev
->ieee80211_ptr
->wiphy
);
2137 pstrWFIDrv
= (tstrWILC_WFIDrv
*)priv
->hWILCWFIDrv
;
2139 /* Get WILC header */
2140 memcpy(&header
, (buff
- HOST_HDR_OFFSET
), HOST_HDR_OFFSET
);
2142 /* The packet offset field conain info about what type of managment frame */
2143 /* we are dealing with and ack status */
2144 pkt_offset
= GET_PKT_OFFSET(header
);
2146 if (pkt_offset
& IS_MANAGMEMENT_CALLBACK
) {
2147 if (buff
[FRAME_TYPE_ID
] == IEEE80211_STYPE_PROBE_RESP
) {
2148 PRINT_D(GENERIC_DBG
, "Probe response ACK\n");
2149 cfg80211_mgmt_tx_status(priv
->wdev
, priv
->u64tx_cookie
, buff
, size
, true, GFP_KERNEL
);
2152 if (pkt_offset
& IS_MGMT_STATUS_SUCCES
) {
2153 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
],
2154 buff
[ACTION_SUBTYPE_ID
+ 1], buff
[P2P_PUB_ACTION_SUBTYPE
+ 1]);
2155 cfg80211_mgmt_tx_status(priv
->wdev
, priv
->u64tx_cookie
, buff
, size
, true, GFP_KERNEL
);
2157 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
],
2158 buff
[ACTION_SUBTYPE_ID
+ 1], buff
[P2P_PUB_ACTION_SUBTYPE
+ 1]);
2159 cfg80211_mgmt_tx_status(priv
->wdev
, priv
->u64tx_cookie
, buff
, size
, false, GFP_KERNEL
);
2165 PRINT_D(GENERIC_DBG
, "Rx Frame Type:%x\n", buff
[FRAME_TYPE_ID
]);
2168 /*Upper layer is informed that the frame is received on this freq*/
2169 s32Freq
= ieee80211_channel_to_frequency(u8CurrChannel
, IEEE80211_BAND_2GHZ
);
2171 if (ieee80211_is_action(buff
[FRAME_TYPE_ID
])) {
2172 PRINT_D(GENERIC_DBG
, "Rx Action Frame Type: %x %x\n", buff
[ACTION_SUBTYPE_ID
], buff
[P2P_PUB_ACTION_SUBTYPE
]);
2174 if (priv
->bCfgScanning
== true && time_after_eq(jiffies
, (unsigned long)pstrWFIDrv
->u64P2p_MgmtTimeout
)) {
2175 PRINT_D(GENERIC_DBG
, "Receiving action frames from wrong channels\n");
2178 if (buff
[ACTION_CAT_ID
] == PUB_ACTION_ATTR_ID
) {
2180 switch (buff
[ACTION_SUBTYPE_ID
]) {
2181 case GAS_INTIAL_REQ
:
2182 PRINT_D(GENERIC_DBG
, "GAS INITIAL REQ %x\n", buff
[ACTION_SUBTYPE_ID
]);
2185 case GAS_INTIAL_RSP
:
2186 PRINT_D(GENERIC_DBG
, "GAS INITIAL RSP %x\n", buff
[ACTION_SUBTYPE_ID
]);
2189 case PUBLIC_ACT_VENDORSPEC
:
2190 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2191 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
2192 if (!memcmp(u8P2P_oui
, &buff
[ACTION_SUBTYPE_ID
+ 1], 4)) {
2193 if ((buff
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_REQ
|| buff
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_RSP
)) {
2195 for (i
= P2P_PUB_ACTION_SUBTYPE
; i
< size
; i
++) {
2196 if (!memcmp(u8P2P_vendorspec
, &buff
[i
], 6)) {
2197 u8P2Precvrandom
= buff
[i
+ 6];
2199 PRINT_D(GENERIC_DBG
, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom
);
2205 if (u8P2Plocalrandom
> u8P2Precvrandom
) {
2206 if ((buff
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_REQ
|| buff
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_RSP
2207 || buff
[P2P_PUB_ACTION_SUBTYPE
] == P2P_INV_REQ
|| buff
[P2P_PUB_ACTION_SUBTYPE
] == P2P_INV_RSP
)) {
2208 for (i
= P2P_PUB_ACTION_SUBTYPE
+ 2; i
< size
; i
++) {
2209 if (buff
[i
] == P2PELEM_ATTR_ID
&& !(memcmp(u8P2P_oui
, &buff
[i
+ 2], 4))) {
2210 WILC_WFI_CfgParseRxAction(&buff
[i
+ 6], size
- (i
+ 6));
2216 PRINT_D(GENERIC_DBG
, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom
, u8P2Precvrandom
);
2220 if ((buff
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_REQ
|| buff
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_RSP
) && (bWilc_ie
)) {
2221 PRINT_D(GENERIC_DBG
, "Sending P2P to host without extra elemnt\n");
2222 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
2223 cfg80211_rx_mgmt(priv
->wdev
, s32Freq
, 0, buff
, size
- 7, 0);
2229 PRINT_D(GENERIC_DBG
, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff
[ACTION_SUBTYPE_ID
]);
2235 cfg80211_rx_mgmt(priv
->wdev
, s32Freq
, 0, buff
, size
- 7, 0);
2240 * @brief WILC_WFI_mgmt_tx_complete
2241 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2243 * transmitting status
2245 * @author Amr Abdelmoghny
2249 static void WILC_WFI_mgmt_tx_complete(void *priv
, int status
)
2251 struct p2p_mgmt_data
*pv_data
= (struct p2p_mgmt_data
*)priv
;
2254 kfree(pv_data
->buff
);
2259 * @brief WILC_WFI_RemainOnChannelReady
2260 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2263 * @author Amr abdelmoghny
2268 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid
)
2270 struct wilc_priv
*priv
;
2272 priv
= (struct wilc_priv
*)pUserVoid
;
2274 PRINT_D(HOSTINF_DBG
, "Remain on channel ready\n");
2276 priv
->bInP2PlistenState
= true;
2278 cfg80211_ready_on_channel(priv
->wdev
,
2279 priv
->strRemainOnChanParams
.u64ListenCookie
,
2280 priv
->strRemainOnChanParams
.pstrListenChan
,
2281 priv
->strRemainOnChanParams
.u32ListenDuration
,
2286 * @brief WILC_WFI_RemainOnChannelExpired
2287 * @details Callback function, called on expiration of remain-on-channel duration
2290 * @author Amr abdelmoghny
2295 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid
, u32 u32SessionID
)
2297 struct wilc_priv
*priv
;
2299 priv
= (struct wilc_priv
*)pUserVoid
;
2302 if (u32SessionID
== priv
->strRemainOnChanParams
.u32ListenSessionID
) {
2303 PRINT_D(GENERIC_DBG
, "Remain on channel expired\n");
2305 priv
->bInP2PlistenState
= false;
2307 /*Inform wpas of remain-on-channel expiration*/
2308 cfg80211_remain_on_channel_expired(priv
->wdev
,
2309 priv
->strRemainOnChanParams
.u64ListenCookie
,
2310 priv
->strRemainOnChanParams
.pstrListenChan
,
2313 PRINT_D(GENERIC_DBG
, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2314 , priv
->strRemainOnChanParams
.u32ListenSessionID
);
2320 * @brief remain_on_channel
2321 * @details Request the driver to remain awake on the specified
2322 * channel for the specified duration to complete an off-channel
2323 * operation (e.g., public action frame exchange). When the driver is
2324 * ready on the requested channel, it must indicate this with an event
2325 * notification by calling cfg80211_ready_on_channel().
2327 * @return int : Return 0 on Success
2332 static int remain_on_channel(struct wiphy
*wiphy
,
2333 struct wireless_dev
*wdev
,
2334 struct ieee80211_channel
*chan
,
2335 unsigned int duration
, u64
*cookie
)
2338 struct wilc_priv
*priv
;
2340 priv
= wiphy_priv(wiphy
);
2342 PRINT_D(GENERIC_DBG
, "Remaining on channel %d\n", chan
->hw_value
);
2344 /*BugID_4800: if in AP mode, return.*/
2345 /*This check is to handle the situation when user*/
2346 /*requests "create group" during a running scan*/
2348 if (wdev
->iftype
== NL80211_IFTYPE_AP
) {
2349 PRINT_D(GENERIC_DBG
, "Required remain-on-channel while in AP mode");
2353 u8CurrChannel
= chan
->hw_value
;
2355 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2356 priv
->strRemainOnChanParams
.pstrListenChan
= chan
;
2357 priv
->strRemainOnChanParams
.u64ListenCookie
= *cookie
;
2358 priv
->strRemainOnChanParams
.u32ListenDuration
= duration
;
2359 priv
->strRemainOnChanParams
.u32ListenSessionID
++;
2361 s32Error
= host_int_remain_on_channel(priv
->hWILCWFIDrv
2362 , priv
->strRemainOnChanParams
.u32ListenSessionID
2365 , WILC_WFI_RemainOnChannelExpired
2366 , WILC_WFI_RemainOnChannelReady
2373 * @brief cancel_remain_on_channel
2374 * @details Cancel an on-going remain-on-channel operation.
2375 * This allows the operation to be terminated prior to timeout based on
2376 * the duration value.
2377 * @param[in] struct wiphy *wiphy,
2378 * @param[in] struct net_device *dev
2379 * @param[in] u64 cookie,
2380 * @return int : Return 0 on Success
2385 static int cancel_remain_on_channel(struct wiphy
*wiphy
,
2386 struct wireless_dev
*wdev
,
2390 struct wilc_priv
*priv
;
2392 priv
= wiphy_priv(wiphy
);
2394 PRINT_D(CFG80211_DBG
, "Cancel remain on channel\n");
2396 s32Error
= host_int_ListenStateExpired(priv
->hWILCWFIDrv
, priv
->strRemainOnChanParams
.u32ListenSessionID
);
2400 * @brief WILC_WFI_add_wilcvendorspec
2401 * @details Adding WILC information elemet to allow two WILC devices to
2402 * identify each other and connect
2403 * @param[in] u8 * buf
2409 void WILC_WFI_add_wilcvendorspec(u8
*buff
)
2411 memcpy(buff
, u8P2P_vendorspec
, sizeof(u8P2P_vendorspec
));
2414 * @brief WILC_WFI_mgmt_tx_frame
2423 extern linux_wlan_t
*g_linux_wlan
;
2424 extern bool bEnablePS
;
2425 int mgmt_tx(struct wiphy
*wiphy
,
2426 struct wireless_dev
*wdev
,
2427 struct cfg80211_mgmt_tx_params
*params
,
2430 struct ieee80211_channel
*chan
= params
->chan
;
2431 unsigned int wait
= params
->wait
;
2432 const u8
*buf
= params
->buf
;
2433 size_t len
= params
->len
;
2434 const struct ieee80211_mgmt
*mgmt
;
2435 struct p2p_mgmt_data
*mgmt_tx
;
2436 struct wilc_priv
*priv
;
2438 tstrWILC_WFIDrv
*pstrWFIDrv
;
2440 perInterface_wlan_t
*nic
;
2441 u32 buf_len
= len
+ sizeof(u8P2P_vendorspec
) + sizeof(u8P2Plocalrandom
);
2443 nic
= netdev_priv(wdev
->netdev
);
2444 priv
= wiphy_priv(wiphy
);
2445 pstrWFIDrv
= (tstrWILC_WFIDrv
*)priv
->hWILCWFIDrv
;
2447 *cookie
= (unsigned long)buf
;
2448 priv
->u64tx_cookie
= *cookie
;
2449 mgmt
= (const struct ieee80211_mgmt
*) buf
;
2451 if (ieee80211_is_mgmt(mgmt
->frame_control
)) {
2453 /*mgmt frame allocation*/
2454 mgmt_tx
= kmalloc(sizeof(struct p2p_mgmt_data
), GFP_KERNEL
);
2455 if (mgmt_tx
== NULL
) {
2456 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
2459 mgmt_tx
->buff
= kmalloc(buf_len
, GFP_KERNEL
);
2460 if (mgmt_tx
->buff
== NULL
) {
2461 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
2465 memcpy(mgmt_tx
->buff
, buf
, len
);
2466 mgmt_tx
->size
= len
;
2469 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
2470 PRINT_D(GENERIC_DBG
, "TX: Probe Response\n");
2471 PRINT_D(GENERIC_DBG
, "Setting channel: %d\n", chan
->hw_value
);
2472 host_int_set_mac_chnl_num(priv
->hWILCWFIDrv
, chan
->hw_value
);
2473 /*Save the current channel after we tune to it*/
2474 u8CurrChannel
= chan
->hw_value
;
2475 } else if (ieee80211_is_action(mgmt
->frame_control
)) {
2476 PRINT_D(GENERIC_DBG
, "ACTION FRAME:%x\n", (u16
)mgmt
->frame_control
);
2480 if (buf
[ACTION_CAT_ID
] == PUB_ACTION_ATTR_ID
) {
2482 /*Only set the channel, if not a negotiation confirmation frame
2483 * (If Negotiation confirmation frame, force it
2484 * to be transmitted on the same negotiation channel)*/
2486 if (buf
[ACTION_SUBTYPE_ID
] != PUBLIC_ACT_VENDORSPEC
||
2487 buf
[P2P_PUB_ACTION_SUBTYPE
] != GO_NEG_CONF
) {
2488 PRINT_D(GENERIC_DBG
, "Setting channel: %d\n", chan
->hw_value
);
2489 host_int_set_mac_chnl_num(priv
->hWILCWFIDrv
, chan
->hw_value
);
2490 /*Save the current channel after we tune to it*/
2491 u8CurrChannel
= chan
->hw_value
;
2493 switch (buf
[ACTION_SUBTYPE_ID
]) {
2494 case GAS_INTIAL_REQ
:
2496 PRINT_D(GENERIC_DBG
, "GAS INITIAL REQ %x\n", buf
[ACTION_SUBTYPE_ID
]);
2500 case GAS_INTIAL_RSP
:
2502 PRINT_D(GENERIC_DBG
, "GAS INITIAL RSP %x\n", buf
[ACTION_SUBTYPE_ID
]);
2506 case PUBLIC_ACT_VENDORSPEC
:
2508 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2509 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
2510 if (!memcmp(u8P2P_oui
, &buf
[ACTION_SUBTYPE_ID
+ 1], 4)) {
2511 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2512 if ((buf
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_REQ
|| buf
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_RSP
)) {
2513 if (u8P2Plocalrandom
== 1 && u8P2Precvrandom
< u8P2Plocalrandom
) {
2514 get_random_bytes(&u8P2Plocalrandom
, 1);
2515 /*Increment the number to prevent if its 0*/
2520 if ((buf
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_REQ
|| buf
[P2P_PUB_ACTION_SUBTYPE
] == GO_NEG_RSP
2521 || buf
[P2P_PUB_ACTION_SUBTYPE
] == P2P_INV_REQ
|| buf
[P2P_PUB_ACTION_SUBTYPE
] == P2P_INV_RSP
)) {
2522 if (u8P2Plocalrandom
> u8P2Precvrandom
) {
2523 PRINT_D(GENERIC_DBG
, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom
, u8P2Precvrandom
);
2525 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2526 for (i
= P2P_PUB_ACTION_SUBTYPE
+ 2; i
< len
; i
++) {
2527 if (buf
[i
] == P2PELEM_ATTR_ID
&& !(memcmp(u8P2P_oui
, &buf
[i
+ 2], 4))) {
2528 if (buf
[P2P_PUB_ACTION_SUBTYPE
] == P2P_INV_REQ
|| buf
[P2P_PUB_ACTION_SUBTYPE
] == P2P_INV_RSP
)
2529 WILC_WFI_CfgParseTxAction(&mgmt_tx
->buff
[i
+ 6], len
- (i
+ 6), true, nic
->iftype
);
2532 /*If using supplicant go intent, no need at all*/
2533 /*to parse transmitted negotiation frames*/
2535 WILC_WFI_CfgParseTxAction(&mgmt_tx
->buff
[i
+ 6], len
- (i
+ 6), false, nic
->iftype
);
2540 if (buf
[P2P_PUB_ACTION_SUBTYPE
] != P2P_INV_REQ
&& buf
[P2P_PUB_ACTION_SUBTYPE
] != P2P_INV_RSP
) {
2541 WILC_WFI_add_wilcvendorspec(&mgmt_tx
->buff
[len
]);
2542 mgmt_tx
->buff
[len
+ sizeof(u8P2P_vendorspec
)] = u8P2Plocalrandom
;
2543 mgmt_tx
->size
= buf_len
;
2546 PRINT_D(GENERIC_DBG
, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom
, u8P2Precvrandom
);
2550 PRINT_D(GENERIC_DBG
, "Not a P2P public action frame\n");
2558 PRINT_D(GENERIC_DBG
, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf
[ACTION_SUBTYPE_ID
]);
2565 PRINT_D(GENERIC_DBG
, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf
[ACTION_SUBTYPE_ID
], chan
->hw_value
);
2566 pstrWFIDrv
->u64P2p_MgmtTimeout
= (jiffies
+ msecs_to_jiffies(wait
));
2568 PRINT_D(GENERIC_DBG
, "Current Jiffies: %lu Timeout:%llu\n", jiffies
, pstrWFIDrv
->u64P2p_MgmtTimeout
);
2572 g_linux_wlan
->oup
.wlan_add_mgmt_to_tx_que(mgmt_tx
, mgmt_tx
->buff
, mgmt_tx
->size
, WILC_WFI_mgmt_tx_complete
);
2574 PRINT_D(GENERIC_DBG
, "This function transmits only management frames\n");
2579 int mgmt_tx_cancel_wait(struct wiphy
*wiphy
,
2580 struct wireless_dev
*wdev
,
2583 struct wilc_priv
*priv
;
2584 tstrWILC_WFIDrv
*pstrWFIDrv
;
2586 priv
= wiphy_priv(wiphy
);
2587 pstrWFIDrv
= (tstrWILC_WFIDrv
*)priv
->hWILCWFIDrv
;
2590 PRINT_D(GENERIC_DBG
, "Tx Cancel wait :%lu\n", jiffies
);
2591 pstrWFIDrv
->u64P2p_MgmtTimeout
= jiffies
;
2593 if (priv
->bInP2PlistenState
== false) {
2594 /* Bug 5504: This is just to avoid connection failure when getting stuck when the supplicant
2595 * considers the driver falsely that it is in Listen state */
2596 cfg80211_remain_on_channel_expired(priv
->wdev
,
2597 priv
->strRemainOnChanParams
.u64ListenCookie
,
2598 priv
->strRemainOnChanParams
.pstrListenChan
,
2606 * @brief WILC_WFI_frame_register
2607 * @details Notify driver that a management frame type was
2608 * registered. Note that this callback may not sleep, and cannot run
2609 * concurrently with itself.
2616 void WILC_WFI_frame_register(struct wiphy
*wiphy
,
2617 struct wireless_dev
*wdev
,
2618 u16 frame_type
, bool reg
)
2621 struct wilc_priv
*priv
;
2622 perInterface_wlan_t
*nic
;
2625 priv
= wiphy_priv(wiphy
);
2626 nic
= netdev_priv(priv
->wdev
->netdev
);
2634 PRINT_D(GENERIC_DBG
, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type
, reg
);
2635 switch (frame_type
) {
2638 nic
->g_struct_frame_reg
[0].frame_type
= frame_type
;
2639 nic
->g_struct_frame_reg
[0].reg
= reg
;
2645 nic
->g_struct_frame_reg
[1].frame_type
= frame_type
;
2646 nic
->g_struct_frame_reg
[1].reg
= reg
;
2656 /*If mac is closed, then return*/
2657 if (!g_linux_wlan
->wilc1000_initialized
) {
2658 PRINT_D(GENERIC_DBG
, "Return since mac is closed\n");
2661 host_int_frame_register(priv
->hWILCWFIDrv
, frame_type
, reg
);
2668 * @brief WILC_WFI_set_cqm_rssi_config
2669 * @details Configure connection quality monitor RSSI threshold.
2670 * @param[in] struct wiphy *wiphy:
2671 * @param[in] struct net_device *dev:
2672 * @param[in] s32 rssi_thold:
2673 * @param[in] u32 rssi_hyst:
2674 * @return int : Return 0 on Success
2679 static int WILC_WFI_set_cqm_rssi_config(struct wiphy
*wiphy
,
2680 struct net_device
*dev
, s32 rssi_thold
, u32 rssi_hyst
)
2682 PRINT_D(CFG80211_DBG
, "Setting CQM RSSi Function\n");
2687 * @brief dump_station
2688 * @details Configure connection quality monitor RSSI threshold.
2689 * @param[in] struct wiphy *wiphy:
2690 * @param[in] struct net_device *dev
2691 * @param[in] int idx
2692 * @param[in] u8 *mac
2693 * @param[in] struct station_info *sinfo
2694 * @return int : Return 0 on Success
2699 static int dump_station(struct wiphy
*wiphy
, struct net_device
*dev
,
2700 int idx
, u8
*mac
, struct station_info
*sinfo
)
2702 struct wilc_priv
*priv
;
2704 PRINT_D(CFG80211_DBG
, "Dumping station information\n");
2709 priv
= wiphy_priv(wiphy
);
2711 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
);
2713 host_int_get_rssi(priv
->hWILCWFIDrv
, &(sinfo
->signal
));
2721 * @brief WILC_WFI_set_power_mgmt
2724 * @return int : Return 0 on Success.
2727 * @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
2729 int WILC_WFI_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*dev
,
2730 bool enabled
, int timeout
)
2732 struct wilc_priv
*priv
;
2734 PRINT_D(CFG80211_DBG
, " Power save Enabled= %d , TimeOut = %d\n", enabled
, timeout
);
2739 priv
= wiphy_priv(wiphy
);
2740 if (priv
->hWILCWFIDrv
== NULL
) {
2741 PRINT_ER("Driver is NULL\n");
2746 host_int_set_power_mgmt(priv
->hWILCWFIDrv
, enabled
, timeout
);
2752 #ifdef WILC_AP_EXTERNAL_MLME
2754 * @brief change_virtual_intf
2755 * @details Change type/configuration of virtual interface,
2756 * keep the struct wireless_dev's iftype updated.
2758 * @return int : Return 0 on Success.
2763 void wilc1000_wlan_deinit(linux_wlan_t
*nic
);
2764 int wilc1000_wlan_init(struct net_device
*dev
, perInterface_wlan_t
*p_nic
);
2766 static int change_virtual_intf(struct wiphy
*wiphy
, struct net_device
*dev
,
2767 enum nl80211_iftype type
, u32
*flags
, struct vif_params
*params
)
2770 struct wilc_priv
*priv
;
2771 perInterface_wlan_t
*nic
;
2778 nic
= netdev_priv(dev
);
2779 priv
= wiphy_priv(wiphy
);
2781 PRINT_D(HOSTAPD_DBG
, "In Change virtual interface function\n");
2782 PRINT_D(HOSTAPD_DBG
, "Wireless interface name =%s\n", dev
->name
);
2783 u8P2Plocalrandom
= 0x01;
2784 u8P2Precvrandom
= 0x00;
2788 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
2789 g_obtainingIP
= false;
2790 del_timer(&hDuringIpTimer
);
2791 PRINT_D(GENERIC_DBG
, "Changing virtual interface, enable scan\n");
2794 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2795 if (g_ptk_keys_saved
&& g_gtk_keys_saved
) {
2796 Set_machw_change_vir_if(true);
2800 case NL80211_IFTYPE_STATION
:
2802 PRINT_D(HOSTAPD_DBG
, "Interface type = NL80211_IFTYPE_STATION\n");
2804 /* send delba over wlan interface */
2807 dev
->ieee80211_ptr
->iftype
= type
;
2808 priv
->wdev
->iftype
= type
;
2809 nic
->monitor_flag
= 0;
2810 nic
->iftype
= STATION_MODE
;
2812 /*Remove the enteries of the previously connected clients*/
2813 memset(priv
->assoc_stainfo
.au8Sta_AssociatedBss
, 0, MAX_NUM_STA
* ETH_ALEN
);
2815 interface_type
= nic
->iftype
;
2816 nic
->iftype
= STATION_MODE
;
2818 if (g_linux_wlan
->wilc1000_initialized
) {
2819 host_int_del_All_Rx_BASession(priv
->hWILCWFIDrv
, g_linux_wlan
->strInterfaceInfo
[0].aBSSID
, TID
);
2820 /* ensure that the message Q is empty */
2821 host_int_wait_msg_queue_idle();
2824 /*Eliminate host interface blocking state*/
2825 up(&g_linux_wlan
->cfg_event
);
2827 wilc1000_wlan_deinit(g_linux_wlan
);
2828 wilc1000_wlan_init(dev
, nic
);
2829 g_wilc_initialized
= 1;
2830 nic
->iftype
= interface_type
;
2832 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
2833 host_int_set_wfi_drv_handler(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
);
2834 host_int_set_MacAddress(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
2835 g_linux_wlan
->strInterfaceInfo
[0].aSrcAddress
);
2836 host_int_set_operation_mode(priv
->hWILCWFIDrv
, STATION_MODE
);
2838 /*Add saved WEP keys, if any*/
2839 if (g_wep_keys_saved
) {
2840 host_int_set_WEPDefaultKeyID(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
2841 g_key_wep_params
.key_idx
);
2842 host_int_add_wep_key_bss_sta(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
2843 g_key_wep_params
.key
,
2844 g_key_wep_params
.key_len
,
2845 g_key_wep_params
.key_idx
);
2848 /*No matter the driver handler passed here, it will be overwriiten*/
2849 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2850 host_int_flush_join_req(priv
->hWILCWFIDrv
);
2852 /*Add saved PTK and GTK keys, if any*/
2853 if (g_ptk_keys_saved
&& g_gtk_keys_saved
) {
2854 PRINT_D(CFG80211_DBG
, "ptk %x %x %x\n", g_key_ptk_params
.key
[0],
2855 g_key_ptk_params
.key
[1],
2856 g_key_ptk_params
.key
[2]);
2857 PRINT_D(CFG80211_DBG
, "gtk %x %x %x\n", g_key_gtk_params
.key
[0],
2858 g_key_gtk_params
.key
[1],
2859 g_key_gtk_params
.key
[2]);
2860 add_key(g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
->ieee80211_ptr
->wiphy
,
2861 g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
,
2862 g_add_ptk_key_params
.key_idx
,
2863 g_add_ptk_key_params
.pairwise
,
2864 g_add_ptk_key_params
.mac_addr
,
2865 (struct key_params
*)(&g_key_ptk_params
));
2867 add_key(g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
->ieee80211_ptr
->wiphy
,
2868 g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
,
2869 g_add_gtk_key_params
.key_idx
,
2870 g_add_gtk_key_params
.pairwise
,
2871 g_add_gtk_key_params
.mac_addr
,
2872 (struct key_params
*)(&g_key_gtk_params
));
2875 /*BugID_4847: registered frames in firmware are now*/
2876 /*lost due to mac close. So re-register those frames*/
2877 if (g_linux_wlan
->wilc1000_initialized
) {
2878 for (i
= 0; i
< num_reg_frame
; i
++) {
2879 PRINT_D(INIT_DBG
, "Frame registering Type: %x - Reg: %d\n", nic
->g_struct_frame_reg
[i
].frame_type
,
2880 nic
->g_struct_frame_reg
[i
].reg
);
2881 host_int_frame_register(priv
->hWILCWFIDrv
,
2882 nic
->g_struct_frame_reg
[i
].frame_type
,
2883 nic
->g_struct_frame_reg
[i
].reg
);
2888 host_int_set_power_mgmt(priv
->hWILCWFIDrv
, 1, 0);
2893 case NL80211_IFTYPE_P2P_CLIENT
:
2895 host_int_set_power_mgmt(priv
->hWILCWFIDrv
, 0, 0);
2897 PRINT_D(HOSTAPD_DBG
, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
2899 host_int_del_All_Rx_BASession(priv
->hWILCWFIDrv
, g_linux_wlan
->strInterfaceInfo
[0].aBSSID
, TID
);
2901 dev
->ieee80211_ptr
->iftype
= type
;
2902 priv
->wdev
->iftype
= type
;
2903 nic
->monitor_flag
= 0;
2907 PRINT_D(HOSTAPD_DBG
, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2908 nic
->iftype
= CLIENT_MODE
;
2911 if (g_linux_wlan
->wilc1000_initialized
) {
2912 /* ensure that the message Q is empty */
2913 host_int_wait_msg_queue_idle();
2915 wilc1000_wlan_deinit(g_linux_wlan
);
2916 wilc1000_wlan_init(dev
, nic
);
2917 g_wilc_initialized
= 1;
2919 host_int_set_wfi_drv_handler(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
);
2920 host_int_set_MacAddress(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
2921 g_linux_wlan
->strInterfaceInfo
[0].aSrcAddress
);
2922 host_int_set_operation_mode(priv
->hWILCWFIDrv
, STATION_MODE
);
2924 /*Add saved WEP keys, if any*/
2925 if (g_wep_keys_saved
) {
2926 host_int_set_WEPDefaultKeyID(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
2927 g_key_wep_params
.key_idx
);
2928 host_int_add_wep_key_bss_sta(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
2929 g_key_wep_params
.key
,
2930 g_key_wep_params
.key_len
,
2931 g_key_wep_params
.key_idx
);
2934 /*No matter the driver handler passed here, it will be overwriiten*/
2935 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2936 host_int_flush_join_req(priv
->hWILCWFIDrv
);
2938 /*Add saved PTK and GTK keys, if any*/
2939 if (g_ptk_keys_saved
&& g_gtk_keys_saved
) {
2940 PRINT_D(CFG80211_DBG
, "ptk %x %x %x\n", g_key_ptk_params
.key
[0],
2941 g_key_ptk_params
.key
[1],
2942 g_key_ptk_params
.key
[2]);
2943 PRINT_D(CFG80211_DBG
, "gtk %x %x %x\n", g_key_gtk_params
.key
[0],
2944 g_key_gtk_params
.key
[1],
2945 g_key_gtk_params
.key
[2]);
2946 add_key(g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
->ieee80211_ptr
->wiphy
,
2947 g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
,
2948 g_add_ptk_key_params
.key_idx
,
2949 g_add_ptk_key_params
.pairwise
,
2950 g_add_ptk_key_params
.mac_addr
,
2951 (struct key_params
*)(&g_key_ptk_params
));
2953 add_key(g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
->ieee80211_ptr
->wiphy
,
2954 g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
,
2955 g_add_gtk_key_params
.key_idx
,
2956 g_add_gtk_key_params
.pairwise
,
2957 g_add_gtk_key_params
.mac_addr
,
2958 (struct key_params
*)(&g_key_gtk_params
));
2961 /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/
2962 refresh_scan(priv
, 1, true);
2963 Set_machw_change_vir_if(false);
2965 /*BugID_4847: registered frames in firmware are now lost
2966 * due to mac close. So re-register those frames */
2967 if (g_linux_wlan
->wilc1000_initialized
) {
2968 for (i
= 0; i
< num_reg_frame
; i
++) {
2969 PRINT_D(INIT_DBG
, "Frame registering Type: %x - Reg: %d\n", nic
->g_struct_frame_reg
[i
].frame_type
,
2970 nic
->g_struct_frame_reg
[i
].reg
);
2971 host_int_frame_register(priv
->hWILCWFIDrv
,
2972 nic
->g_struct_frame_reg
[i
].frame_type
,
2973 nic
->g_struct_frame_reg
[i
].reg
);
2980 case NL80211_IFTYPE_AP
:
2982 PRINT_D(HOSTAPD_DBG
, "Interface type = NL80211_IFTYPE_AP %d\n", type
);
2983 dev
->ieee80211_ptr
->iftype
= type
;
2984 priv
->wdev
->iftype
= type
;
2985 nic
->iftype
= AP_MODE
;
2986 PRINT_D(CORECONFIG_DBG
, "priv->hWILCWFIDrv[%p]\n", priv
->hWILCWFIDrv
);
2988 PRINT_D(HOSTAPD_DBG
, "Downloading AP firmware\n");
2989 linux_wlan_get_firmware(nic
);
2991 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
2992 if (g_linux_wlan
->wilc1000_initialized
) {
2993 nic
->iftype
= AP_MODE
;
2994 g_linux_wlan
->wilc1000_initialized
= 1;
2998 /*BugID_4847: registered frames in firmware are now lost
2999 * due to mac close. So re-register those frames */
3000 for (i
= 0; i
< num_reg_frame
; i
++) {
3001 PRINT_D(INIT_DBG
, "Frame registering Type: %x - Reg: %d\n", nic
->g_struct_frame_reg
[i
].frame_type
,
3002 nic
->g_struct_frame_reg
[i
].reg
);
3003 host_int_frame_register(priv
->hWILCWFIDrv
,
3004 nic
->g_struct_frame_reg
[i
].frame_type
,
3005 nic
->g_struct_frame_reg
[i
].reg
);
3011 case NL80211_IFTYPE_P2P_GO
:
3012 PRINT_D(GENERIC_DBG
, "start duringIP timer\n");
3014 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
3015 g_obtainingIP
= true;
3016 mod_timer(&hDuringIpTimer
, jiffies
+ msecs_to_jiffies(duringIP_TIME
));
3018 host_int_set_power_mgmt(priv
->hWILCWFIDrv
, 0, 0);
3020 /*Delete block ack has to be the latest config packet*/
3021 /*sent before downloading new FW. This is because it blocks on*/
3022 /*hWaitResponse semaphore, which allows previous config*/
3023 /*packets to actually take action on old FW*/
3024 host_int_del_All_Rx_BASession(priv
->hWILCWFIDrv
, g_linux_wlan
->strInterfaceInfo
[0].aBSSID
, TID
);
3026 PRINT_D(HOSTAPD_DBG
, "Interface type = NL80211_IFTYPE_GO\n");
3027 dev
->ieee80211_ptr
->iftype
= type
;
3028 priv
->wdev
->iftype
= type
;
3030 PRINT_D(CORECONFIG_DBG
, "priv->hWILCWFIDrv[%p]\n", priv
->hWILCWFIDrv
);
3033 PRINT_D(HOSTAPD_DBG
, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
3037 nic
->iftype
= GO_MODE
;
3039 /* ensure that the message Q is empty */
3040 host_int_wait_msg_queue_idle();
3041 wilc1000_wlan_deinit(g_linux_wlan
);
3042 wilc1000_wlan_init(dev
, nic
);
3043 g_wilc_initialized
= 1;
3046 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
3047 host_int_set_wfi_drv_handler(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
);
3048 host_int_set_MacAddress(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
3049 g_linux_wlan
->strInterfaceInfo
[0].aSrcAddress
);
3050 host_int_set_operation_mode(priv
->hWILCWFIDrv
, AP_MODE
);
3052 /*Add saved WEP keys, if any*/
3053 if (g_wep_keys_saved
) {
3054 host_int_set_WEPDefaultKeyID(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
3055 g_key_wep_params
.key_idx
);
3056 host_int_add_wep_key_bss_sta(g_linux_wlan
->strInterfaceInfo
[0].drvHandler
,
3057 g_key_wep_params
.key
,
3058 g_key_wep_params
.key_len
,
3059 g_key_wep_params
.key_idx
);
3062 /*No matter the driver handler passed here, it will be overwriiten*/
3063 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
3064 host_int_flush_join_req(priv
->hWILCWFIDrv
);
3066 /*Add saved PTK and GTK keys, if any*/
3067 if (g_ptk_keys_saved
&& g_gtk_keys_saved
) {
3068 PRINT_D(CFG80211_DBG
, "ptk %x %x %x cipher %x\n", g_key_ptk_params
.key
[0],
3069 g_key_ptk_params
.key
[1],
3070 g_key_ptk_params
.key
[2],
3071 g_key_ptk_params
.cipher
);
3072 PRINT_D(CFG80211_DBG
, "gtk %x %x %x cipher %x\n", g_key_gtk_params
.key
[0],
3073 g_key_gtk_params
.key
[1],
3074 g_key_gtk_params
.key
[2],
3075 g_key_gtk_params
.cipher
);
3077 add_key(g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
->ieee80211_ptr
->wiphy
,
3078 g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
,
3079 g_add_ptk_key_params
.key_idx
,
3080 g_add_ptk_key_params
.pairwise
,
3081 g_add_ptk_key_params
.mac_addr
,
3082 (struct key_params
*)(&g_key_ptk_params
));
3084 add_key(g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
->ieee80211_ptr
->wiphy
,
3085 g_linux_wlan
->strInterfaceInfo
[0].wilc_netdev
,
3086 g_add_gtk_key_params
.key_idx
,
3087 g_add_gtk_key_params
.pairwise
,
3088 g_add_gtk_key_params
.mac_addr
,
3089 (struct key_params
*)(&g_key_gtk_params
));
3094 /*BugID_4847: registered frames in firmware are now*/
3095 /*lost due to mac close. So re-register those frames*/
3096 if (g_linux_wlan
->wilc1000_initialized
) {
3097 for (i
= 0; i
< num_reg_frame
; i
++) {
3098 PRINT_D(INIT_DBG
, "Frame registering Type: %x - Reg: %d\n", nic
->g_struct_frame_reg
[i
].frame_type
,
3099 nic
->g_struct_frame_reg
[i
].reg
);
3100 host_int_frame_register(priv
->hWILCWFIDrv
,
3101 nic
->g_struct_frame_reg
[i
].frame_type
,
3102 nic
->g_struct_frame_reg
[i
].reg
);
3109 PRINT_ER("Unknown interface type= %d\n", type
);
3118 /* (austin.2013-07-23)
3120 * To support revised cfg80211_ops
3122 * add_beacon --> start_ap
3123 * set_beacon --> change_beacon
3124 * del_beacon --> stop_ap
3126 * beacon_parameters --> cfg80211_ap_settings
3127 * cfg80211_beacon_data
3129 * applicable for linux kernel 3.4+
3134 * @details Add a beacon with given parameters, @head, @interval
3135 * and @dtim_period will be valid, @tail is optional.
3137 * @param[in] dev The net device structure
3138 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
3139 * @return int : Return 0 on Success.
3144 static int start_ap(struct wiphy
*wiphy
, struct net_device
*dev
,
3145 struct cfg80211_ap_settings
*settings
)
3147 struct cfg80211_beacon_data
*beacon
= &(settings
->beacon
);
3148 struct wilc_priv
*priv
;
3151 priv
= wiphy_priv(wiphy
);
3152 PRINT_D(HOSTAPD_DBG
, "Starting ap\n");
3154 PRINT_D(HOSTAPD_DBG
, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
3155 settings
->beacon_interval
, settings
->dtim_period
, beacon
->head_len
, beacon
->tail_len
);
3157 s32Error
= set_channel(wiphy
, &settings
->chandef
);
3160 PRINT_ER("Error in setting channel\n");
3162 linux_wlan_set_bssid(dev
, g_linux_wlan
->strInterfaceInfo
[0].aSrcAddress
);
3164 s32Error
= host_int_add_beacon(priv
->hWILCWFIDrv
,
3165 settings
->beacon_interval
,
3166 settings
->dtim_period
,
3167 beacon
->head_len
, (u8
*)beacon
->head
,
3168 beacon
->tail_len
, (u8
*)beacon
->tail
);
3174 * @brief change_beacon
3175 * @details Add a beacon with given parameters, @head, @interval
3176 * and @dtim_period will be valid, @tail is optional.
3178 * @param[in] dev The net device structure
3179 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
3180 * @return int : Return 0 on Success.
3185 static int change_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
3186 struct cfg80211_beacon_data
*beacon
)
3188 struct wilc_priv
*priv
;
3191 priv
= wiphy_priv(wiphy
);
3192 PRINT_D(HOSTAPD_DBG
, "Setting beacon\n");
3195 s32Error
= host_int_add_beacon(priv
->hWILCWFIDrv
,
3198 beacon
->head_len
, (u8
*)beacon
->head
,
3199 beacon
->tail_len
, (u8
*)beacon
->tail
);
3206 * @details Remove beacon configuration and stop sending the beacon.
3208 * @return int : Return 0 on Success.
3213 static int stop_ap(struct wiphy
*wiphy
, struct net_device
*dev
)
3216 struct wilc_priv
*priv
;
3217 u8 NullBssid
[ETH_ALEN
] = {0};
3222 priv
= wiphy_priv(wiphy
);
3224 PRINT_D(HOSTAPD_DBG
, "Deleting beacon\n");
3227 linux_wlan_set_bssid(dev
, NullBssid
);
3229 s32Error
= host_int_del_beacon(priv
->hWILCWFIDrv
);
3232 PRINT_ER("Host delete beacon fail\n");
3238 * @brief add_station
3239 * @details Add a new station.
3241 * @return int : Return 0 on Success.
3246 static int add_station(struct wiphy
*wiphy
, struct net_device
*dev
,
3247 const u8
*mac
, struct station_parameters
*params
)
3250 struct wilc_priv
*priv
;
3251 tstrWILC_AddStaParam strStaParams
= { {0} };
3252 perInterface_wlan_t
*nic
;
3257 priv
= wiphy_priv(wiphy
);
3258 nic
= netdev_priv(dev
);
3260 if (nic
->iftype
== AP_MODE
|| nic
->iftype
== GO_MODE
) {
3261 memcpy(strStaParams
.au8BSSID
, mac
, ETH_ALEN
);
3262 memcpy(priv
->assoc_stainfo
.au8Sta_AssociatedBss
[params
->aid
], mac
, ETH_ALEN
);
3263 strStaParams
.u16AssocID
= params
->aid
;
3264 strStaParams
.u8NumRates
= params
->supported_rates_len
;
3265 strStaParams
.pu8Rates
= params
->supported_rates
;
3267 PRINT_D(CFG80211_DBG
, "Adding station parameters %d\n", params
->aid
);
3269 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],
3270 priv
->assoc_stainfo
.au8Sta_AssociatedBss
[params
->aid
][5]);
3271 PRINT_D(HOSTAPD_DBG
, "ASSOC ID = %d\n", strStaParams
.u16AssocID
);
3272 PRINT_D(HOSTAPD_DBG
, "Number of supported rates = %d\n", strStaParams
.u8NumRates
);
3274 if (params
->ht_capa
== NULL
) {
3275 strStaParams
.bIsHTSupported
= false;
3277 strStaParams
.bIsHTSupported
= true;
3278 strStaParams
.u16HTCapInfo
= params
->ht_capa
->cap_info
;
3279 strStaParams
.u8AmpduParams
= params
->ht_capa
->ampdu_params_info
;
3280 memcpy(strStaParams
.au8SuppMCsSet
, ¶ms
->ht_capa
->mcs
, WILC_SUPP_MCS_SET_SIZE
);
3281 strStaParams
.u16HTExtParams
= params
->ht_capa
->extended_ht_cap_info
;
3282 strStaParams
.u32TxBeamformingCap
= params
->ht_capa
->tx_BF_cap_info
;
3283 strStaParams
.u8ASELCap
= params
->ht_capa
->antenna_selection_info
;
3286 strStaParams
.u16FlagsMask
= params
->sta_flags_mask
;
3287 strStaParams
.u16FlagsSet
= params
->sta_flags_set
;
3289 PRINT_D(HOSTAPD_DBG
, "IS HT supported = %d\n", strStaParams
.bIsHTSupported
);
3290 PRINT_D(HOSTAPD_DBG
, "Capability Info = %d\n", strStaParams
.u16HTCapInfo
);
3291 PRINT_D(HOSTAPD_DBG
, "AMPDU Params = %d\n", strStaParams
.u8AmpduParams
);
3292 PRINT_D(HOSTAPD_DBG
, "HT Extended params = %d\n", strStaParams
.u16HTExtParams
);
3293 PRINT_D(HOSTAPD_DBG
, "Tx Beamforming Cap = %d\n", strStaParams
.u32TxBeamformingCap
);
3294 PRINT_D(HOSTAPD_DBG
, "Antenna selection info = %d\n", strStaParams
.u8ASELCap
);
3295 PRINT_D(HOSTAPD_DBG
, "Flag Mask = %d\n", strStaParams
.u16FlagsMask
);
3296 PRINT_D(HOSTAPD_DBG
, "Flag Set = %d\n", strStaParams
.u16FlagsSet
);
3298 s32Error
= host_int_add_station(priv
->hWILCWFIDrv
, &strStaParams
);
3300 PRINT_ER("Host add station fail\n");
3307 * @brief del_station
3308 * @details Remove a station; @mac may be NULL to remove all stations.
3310 * @return int : Return 0 on Success.
3315 static int del_station(struct wiphy
*wiphy
, struct net_device
*dev
,
3316 struct station_del_parameters
*params
)
3318 const u8
*mac
= params
->mac
;
3320 struct wilc_priv
*priv
;
3321 perInterface_wlan_t
*nic
;
3326 priv
= wiphy_priv(wiphy
);
3327 nic
= netdev_priv(dev
);
3329 if (nic
->iftype
== AP_MODE
|| nic
->iftype
== GO_MODE
) {
3330 PRINT_D(HOSTAPD_DBG
, "Deleting station\n");
3334 PRINT_D(HOSTAPD_DBG
, "All associated stations\n");
3335 s32Error
= host_int_del_allstation(priv
->hWILCWFIDrv
, priv
->assoc_stainfo
.au8Sta_AssociatedBss
);
3337 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]);
3340 s32Error
= host_int_del_station(priv
->hWILCWFIDrv
, mac
);
3343 PRINT_ER("Host delete station fail\n");
3349 * @brief change_station
3350 * @details Modify a given station.
3352 * @return int : Return 0 on Success.
3357 static int change_station(struct wiphy
*wiphy
, struct net_device
*dev
,
3358 const u8
*mac
, struct station_parameters
*params
)
3361 struct wilc_priv
*priv
;
3362 tstrWILC_AddStaParam strStaParams
= { {0} };
3363 perInterface_wlan_t
*nic
;
3366 PRINT_D(HOSTAPD_DBG
, "Change station paramters\n");
3371 priv
= wiphy_priv(wiphy
);
3372 nic
= netdev_priv(dev
);
3374 if (nic
->iftype
== AP_MODE
|| nic
->iftype
== GO_MODE
) {
3375 memcpy(strStaParams
.au8BSSID
, mac
, ETH_ALEN
);
3376 strStaParams
.u16AssocID
= params
->aid
;
3377 strStaParams
.u8NumRates
= params
->supported_rates_len
;
3378 strStaParams
.pu8Rates
= params
->supported_rates
;
3380 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],
3381 strStaParams
.au8BSSID
[5]);
3382 PRINT_D(HOSTAPD_DBG
, "ASSOC ID = %d\n", strStaParams
.u16AssocID
);
3383 PRINT_D(HOSTAPD_DBG
, "Number of supported rates = %d\n", strStaParams
.u8NumRates
);
3385 if (params
->ht_capa
== NULL
) {
3386 strStaParams
.bIsHTSupported
= false;
3388 strStaParams
.bIsHTSupported
= true;
3389 strStaParams
.u16HTCapInfo
= params
->ht_capa
->cap_info
;
3390 strStaParams
.u8AmpduParams
= params
->ht_capa
->ampdu_params_info
;
3391 memcpy(strStaParams
.au8SuppMCsSet
, ¶ms
->ht_capa
->mcs
, WILC_SUPP_MCS_SET_SIZE
);
3392 strStaParams
.u16HTExtParams
= params
->ht_capa
->extended_ht_cap_info
;
3393 strStaParams
.u32TxBeamformingCap
= params
->ht_capa
->tx_BF_cap_info
;
3394 strStaParams
.u8ASELCap
= params
->ht_capa
->antenna_selection_info
;
3398 strStaParams
.u16FlagsMask
= params
->sta_flags_mask
;
3399 strStaParams
.u16FlagsSet
= params
->sta_flags_set
;
3401 PRINT_D(HOSTAPD_DBG
, "IS HT supported = %d\n", strStaParams
.bIsHTSupported
);
3402 PRINT_D(HOSTAPD_DBG
, "Capability Info = %d\n", strStaParams
.u16HTCapInfo
);
3403 PRINT_D(HOSTAPD_DBG
, "AMPDU Params = %d\n", strStaParams
.u8AmpduParams
);
3404 PRINT_D(HOSTAPD_DBG
, "HT Extended params = %d\n", strStaParams
.u16HTExtParams
);
3405 PRINT_D(HOSTAPD_DBG
, "Tx Beamforming Cap = %d\n", strStaParams
.u32TxBeamformingCap
);
3406 PRINT_D(HOSTAPD_DBG
, "Antenna selection info = %d\n", strStaParams
.u8ASELCap
);
3407 PRINT_D(HOSTAPD_DBG
, "Flag Mask = %d\n", strStaParams
.u16FlagsMask
);
3408 PRINT_D(HOSTAPD_DBG
, "Flag Set = %d\n", strStaParams
.u16FlagsSet
);
3410 s32Error
= host_int_edit_station(priv
->hWILCWFIDrv
, &strStaParams
);
3412 PRINT_ER("Host edit station fail\n");
3419 * @brief add_virtual_intf
3422 * @return int : Return 0 on Success.
3427 struct wireless_dev
*add_virtual_intf(struct wiphy
*wiphy
, const char *name
,
3428 unsigned char name_assign_type
,
3429 enum nl80211_iftype type
, u32
*flags
,
3430 struct vif_params
*params
)
3432 perInterface_wlan_t
*nic
;
3433 struct wilc_priv
*priv
;
3434 struct net_device
*new_ifc
= NULL
;
3436 priv
= wiphy_priv(wiphy
);
3440 PRINT_D(HOSTAPD_DBG
, "Adding monitor interface[%p]\n", priv
->wdev
->netdev
);
3442 nic
= netdev_priv(priv
->wdev
->netdev
);
3445 if (type
== NL80211_IFTYPE_MONITOR
) {
3446 PRINT_D(HOSTAPD_DBG
, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3447 PRINT_D(HOSTAPD_DBG
, "Adding monitor interface[%p]\n", nic
->wilc_netdev
);
3448 new_ifc
= WILC_WFI_init_mon_interface(name
, nic
->wilc_netdev
);
3449 if (new_ifc
!= NULL
) {
3450 PRINT_D(HOSTAPD_DBG
, "Setting monitor flag in private structure\n");
3451 nic
= netdev_priv(priv
->wdev
->netdev
);
3452 nic
->monitor_flag
= 1;
3454 PRINT_ER("Error in initializing monitor interface\n ");
3460 * @brief del_virtual_intf
3463 * @return int : Return 0 on Success.
3468 int del_virtual_intf(struct wiphy
*wiphy
, struct wireless_dev
*wdev
) /* tony for v3.8 support */
3470 PRINT_D(HOSTAPD_DBG
, "Deleting virtual interface\n");
3476 #endif /*WILC_AP_EXTERNAL_MLME*/
3477 static struct cfg80211_ops wilc_cfg80211_ops
= {
3479 .set_monitor_channel
= set_channel
,
3482 .disconnect
= disconnect
,
3486 .set_default_key
= set_default_key
,
3487 #ifdef WILC_AP_EXTERNAL_MLME
3488 .add_virtual_intf
= add_virtual_intf
,
3489 .del_virtual_intf
= del_virtual_intf
,
3490 .change_virtual_intf
= change_virtual_intf
,
3492 .start_ap
= start_ap
,
3493 .change_beacon
= change_beacon
,
3495 .add_station
= add_station
,
3496 .del_station
= del_station
,
3497 .change_station
= change_station
,
3498 #endif /* WILC_AP_EXTERNAL_MLME*/
3499 .get_station
= get_station
,
3500 .dump_station
= dump_station
,
3501 .change_bss
= change_bss
,
3502 .set_wiphy_params
= set_wiphy_params
,
3504 .set_pmksa
= set_pmksa
,
3505 .del_pmksa
= del_pmksa
,
3506 .flush_pmksa
= flush_pmksa
,
3508 .remain_on_channel
= remain_on_channel
,
3509 .cancel_remain_on_channel
= cancel_remain_on_channel
,
3510 .mgmt_tx_cancel_wait
= mgmt_tx_cancel_wait
,
3512 .mgmt_frame_register
= WILC_WFI_frame_register
,
3513 .set_power_mgmt
= WILC_WFI_set_power_mgmt
,
3514 .set_cqm_rssi_config
= WILC_WFI_set_cqm_rssi_config
,
3524 * @brief WILC_WFI_update_stats
3525 * @details Modify parameters for a given BSS.
3527 * @return int : Return 0 on Success.
3530 * @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
3532 int WILC_WFI_update_stats(struct wiphy
*wiphy
, u32 pktlen
, u8 changed
)
3535 struct wilc_priv
*priv
;
3537 priv
= wiphy_priv(wiphy
);
3541 case WILC_WFI_RX_PKT
:
3543 priv
->netstats
.rx_packets
++;
3544 priv
->netstats
.rx_bytes
+= pktlen
;
3545 priv
->netstats
.rx_time
= get_jiffies_64();
3549 case WILC_WFI_TX_PKT
:
3551 priv
->netstats
.tx_packets
++;
3552 priv
->netstats
.tx_bytes
+= pktlen
;
3553 priv
->netstats
.tx_time
= get_jiffies_64();
3566 * @brief WILC_WFI_CfgAlloc
3567 * @details Allocation of the wireless device structure and assigning it
3568 * to the cfg80211 operations structure.
3570 * @return wireless_dev : Returns pointer to wireless_dev structure.
3575 struct wireless_dev
*WILC_WFI_CfgAlloc(void)
3578 struct wireless_dev
*wdev
;
3581 PRINT_D(CFG80211_DBG
, "Allocating wireless device\n");
3582 /*Allocating the wireless device structure*/
3583 wdev
= kzalloc(sizeof(struct wireless_dev
), GFP_KERNEL
);
3585 PRINT_ER("Cannot allocate wireless device\n");
3589 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
3590 wdev
->wiphy
= wiphy_new(&wilc_cfg80211_ops
, sizeof(struct wilc_priv
));
3592 PRINT_ER("Cannot allocate wiphy\n");
3597 #ifdef WILC_AP_EXTERNAL_MLME
3598 /* enable 802.11n HT */
3599 WILC_WFI_band_2ghz
.ht_cap
.ht_supported
= 1;
3600 WILC_WFI_band_2ghz
.ht_cap
.cap
|= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT
);
3601 WILC_WFI_band_2ghz
.ht_cap
.mcs
.rx_mask
[0] = 0xff;
3602 WILC_WFI_band_2ghz
.ht_cap
.ampdu_factor
= IEEE80211_HT_MAX_AMPDU_8K
;
3603 WILC_WFI_band_2ghz
.ht_cap
.ampdu_density
= IEEE80211_HT_MPDU_DENSITY_NONE
;
3607 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &WILC_WFI_band_2ghz
;
3618 * @brief WILC_WFI_WiphyRegister
3619 * @details Registering of the wiphy structure and interface modes
3626 struct wireless_dev
*WILC_WFI_WiphyRegister(struct net_device
*net
)
3628 struct wilc_priv
*priv
;
3629 struct wireless_dev
*wdev
;
3632 PRINT_D(CFG80211_DBG
, "Registering wifi device\n");
3634 wdev
= WILC_WFI_CfgAlloc();
3636 PRINT_ER("CfgAlloc Failed\n");
3641 /*Return hardware description structure (wiphy)'s priv*/
3642 priv
= wdev_priv(wdev
);
3643 sema_init(&(priv
->SemHandleUpdateStats
), 1);
3645 /*Link the wiphy with wireless structure*/
3648 /*Maximum number of probed ssid to be added by user for the scan request*/
3649 wdev
->wiphy
->max_scan_ssids
= MAX_NUM_PROBED_SSID
;
3650 /*Maximum number of pmkids to be cashed*/
3651 wdev
->wiphy
->max_num_pmkids
= WILC_MAX_NUM_PMKIDS
;
3652 PRINT_INFO(CFG80211_DBG
, "Max number of PMKIDs = %d\n", wdev
->wiphy
->max_num_pmkids
);
3654 wdev
->wiphy
->max_scan_ie_len
= 1000;
3656 /*signal strength in mBm (100*dBm) */
3657 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
3659 /*Set the availaible cipher suites*/
3660 wdev
->wiphy
->cipher_suites
= cipher_suites
;
3661 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
3662 /*Setting default managment types: for register action frame: */
3663 wdev
->wiphy
->mgmt_stypes
= wilc_wfi_cfg80211_mgmt_types
;
3666 wdev
->wiphy
->max_remain_on_channel_duration
= 500;
3667 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3668 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) | BIT(NL80211_IFTYPE_AP
) | BIT(NL80211_IFTYPE_MONITOR
) | BIT(NL80211_IFTYPE_P2P_GO
) |
3669 BIT(NL80211_IFTYPE_P2P_CLIENT
);
3670 wdev
->wiphy
->flags
|= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
;
3672 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) | BIT(NL80211_IFTYPE_AP
) | BIT(NL80211_IFTYPE_MONITOR
);
3674 wdev
->iftype
= NL80211_IFTYPE_STATION
;
3678 PRINT_INFO(CFG80211_DBG
, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3679 wdev
->wiphy
->max_scan_ssids
, wdev
->wiphy
->max_scan_ie_len
, wdev
->wiphy
->signal_type
,
3680 wdev
->wiphy
->interface_modes
, wdev
->iftype
);
3683 set_wiphy_dev(wdev
->wiphy
, &local_sdio_func
->dev
); /* tony */
3686 /*Register wiphy structure*/
3687 s32Error
= wiphy_register(wdev
->wiphy
);
3689 PRINT_ER("Cannot register wiphy device\n");
3690 /*should define what action to be taken in such failure*/
3692 PRINT_D(CFG80211_DBG
, "Successful Registering\n");
3701 * @brief WILC_WFI_WiphyFree
3702 * @details Freeing allocation of the wireless device structure
3709 int WILC_WFI_InitHostInt(struct net_device
*net
)
3714 struct wilc_priv
*priv
;
3716 PRINT_D(INIT_DBG
, "Host[%p][%p]\n", net
, net
->ieee80211_ptr
);
3717 priv
= wdev_priv(net
->ieee80211_ptr
);
3719 setup_timer(&hAgingTimer
, remove_network_from_shadow
, 0);
3720 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
3721 setup_timer(&hDuringIpTimer
, clear_duringIP
, 0);
3726 PRINT_ER("Failed to creat refresh Timer\n");
3730 priv
->gbAutoRateAdjusted
= false;
3732 priv
->bInP2PlistenState
= false;
3734 sema_init(&(priv
->hSemScanReq
), 1);
3735 s32Error
= host_int_init(&priv
->hWILCWFIDrv
);
3737 PRINT_ER("Error while initializing hostinterface\n");
3743 * @brief WILC_WFI_WiphyFree
3744 * @details Freeing allocation of the wireless device structure
3751 int WILC_WFI_DeInitHostInt(struct net_device
*net
)
3755 struct wilc_priv
*priv
;
3757 priv
= wdev_priv(net
->ieee80211_ptr
);
3759 priv
->gbAutoRateAdjusted
= false;
3761 priv
->bInP2PlistenState
= false;
3765 s32Error
= host_int_deinit(priv
->hWILCWFIDrv
);
3767 /* Clear the Shadow scan */
3768 clear_shadow_scan(priv
);
3769 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
3771 PRINT_D(CORECONFIG_DBG
, "destroy during ip\n");
3772 del_timer_sync(&hDuringIpTimer
);
3777 PRINT_ER("Error while deintializing host interface\n");
3784 * @brief WILC_WFI_WiphyFree
3785 * @details Freeing allocation of the wireless device structure
3792 void WILC_WFI_WiphyFree(struct net_device
*net
)
3795 PRINT_D(CFG80211_DBG
, "Unregistering wiphy\n");
3798 PRINT_D(INIT_DBG
, "net_device is NULL\n");
3802 if (net
->ieee80211_ptr
== NULL
) {
3803 PRINT_D(INIT_DBG
, "ieee80211_ptr is NULL\n");
3807 if (net
->ieee80211_ptr
->wiphy
== NULL
) {
3808 PRINT_D(INIT_DBG
, "wiphy is NULL\n");
3812 wiphy_unregister(net
->ieee80211_ptr
->wiphy
);
3814 PRINT_D(INIT_DBG
, "Freeing wiphy\n");
3815 wiphy_free(net
->ieee80211_ptr
->wiphy
);
3816 kfree(net
->ieee80211_ptr
);