blob: 5c459679aa5a135f77f14ec1b24e98a27c0a6f3a [file] [log] [blame]
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001/*!
2 * @file wilc_wfi_cfgopertaions.c
3 * @brief CFG80211 Function Implementation functionality
4 * @author aabouzaeid
5 * mabubakr
6 * mdaftedar
7 * zsalah
8 * @sa wilc_wfi_cfgopertaions.h top level OS wrapper file
9 * @date 31 Aug 2010
10 * @version 1.0
11 */
12
13#include "wilc_wfi_cfgoperations.h"
14#include "wilc_wlan.c"
15#ifdef WILC_SDIO
16#include "linux_wlan_sdio.h" /* tony : for set_wiphy_dev() */
17#endif
18
19
20#define IS_MANAGMEMENT 0x100
21#define IS_MANAGMEMENT_CALLBACK 0x080
22#define IS_MGMT_STATUS_SUCCES 0x040
23#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
24
Johnny Kimc5c77ba2015-05-11 14:30:56 +090025extern int linux_wlan_get_firmware(perInterface_wlan_t *p_nic);
26extern void linux_wlan_unlock(void *vp);
Dean Lee72ed4dc2015-06-12 14:11:44 +090027extern u16 Set_machw_change_vir_if(bool bValue);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090028
29extern int mac_open(struct net_device *ndev);
30extern int mac_close(struct net_device *ndev);
31
32tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
Chaehyun Lim4e4467f2015-06-11 14:35:55 +090033u32 u32LastScannedNtwrksCountShadow;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090034#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
35WILC_TimerHandle hDuringIpTimer;
36#endif
37WILC_TimerHandle hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +090038static u8 op_ifcs;
39extern u8 u8ConnectedSSID[6];
Johnny Kimc5c77ba2015-05-11 14:30:56 +090040
41/*BugID_5137*/
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +090042u8 g_wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090043extern linux_wlan_t *g_linux_wlan;
44#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Dean Lee72ed4dc2015-06-12 14:11:44 +090045extern bool g_obtainingIP;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090046#endif
47
48#define CHAN2G(_channel, _freq, _flags) { \
49 .band = IEEE80211_BAND_2GHZ, \
50 .center_freq = (_freq), \
51 .hw_value = (_channel), \
52 .flags = (_flags), \
53 .max_antenna_gain = 0, \
54 .max_power = 30, \
55}
56
57/*Frequency range for channels*/
58static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
59 CHAN2G(1, 2412, 0),
60 CHAN2G(2, 2417, 0),
61 CHAN2G(3, 2422, 0),
62 CHAN2G(4, 2427, 0),
63 CHAN2G(5, 2432, 0),
64 CHAN2G(6, 2437, 0),
65 CHAN2G(7, 2442, 0),
66 CHAN2G(8, 2447, 0),
67 CHAN2G(9, 2452, 0),
68 CHAN2G(10, 2457, 0),
69 CHAN2G(11, 2462, 0),
70 CHAN2G(12, 2467, 0),
71 CHAN2G(13, 2472, 0),
72 CHAN2G(14, 2484, 0),
73};
74
75#define RATETAB_ENT(_rate, _hw_value, _flags) { \
76 .bitrate = (_rate), \
77 .hw_value = (_hw_value), \
78 .flags = (_flags), \
79}
80
81
82/* Table 6 in section 3.2.1.1 */
83static struct ieee80211_rate WILC_WFI_rates[] = {
84 RATETAB_ENT(10, 0, 0),
85 RATETAB_ENT(20, 1, 0),
86 RATETAB_ENT(55, 2, 0),
87 RATETAB_ENT(110, 3, 0),
88 RATETAB_ENT(60, 9, 0),
89 RATETAB_ENT(90, 6, 0),
90 RATETAB_ENT(120, 7, 0),
91 RATETAB_ENT(180, 8, 0),
92 RATETAB_ENT(240, 9, 0),
93 RATETAB_ENT(360, 10, 0),
94 RATETAB_ENT(480, 11, 0),
95 RATETAB_ENT(540, 12, 0),
96};
97
98#ifdef WILC_P2P
99struct p2p_mgmt_data {
100 int size;
101 u8 *buff;
102};
103
104/*Global variable used to state the current connected STA channel*/
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900105u8 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900106
107/*BugID_5442*/
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900108u8 u8CurrChannel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900109
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900110u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
111u8 u8P2Plocalrandom = 0x01;
112u8 u8P2Precvrandom = 0x00;
113u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
Daniel Machon7fc80962015-08-05 00:09:35 +0200114bool bWilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900115#endif
116
117static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
118 .channels = WILC_WFI_2ghz_channels,
119 .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels),
120 .bitrates = WILC_WFI_rates,
121 .n_bitrates = ARRAY_SIZE(WILC_WFI_rates),
122};
123
124
125/*BugID_5137*/
126struct add_key_params {
127 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900128 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900129 u8 *mac_addr;
130};
131struct add_key_params g_add_gtk_key_params;
132struct wilc_wfi_key g_key_gtk_params;
133struct add_key_params g_add_ptk_key_params;
134struct wilc_wfi_key g_key_ptk_params;
135struct wilc_wfi_wep_key g_key_wep_params;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900136u8 g_flushing_in_progress;
Daniel Machon7fc80962015-08-05 00:09:35 +0200137bool g_ptk_keys_saved;
138bool g_gtk_keys_saved;
139bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900140
141#define AGING_TIME (9 * 1000)
142#define duringIP_TIME 15000
143
144void clear_shadow_scan(void *pUserVoid)
145{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900146 int i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900147 if (op_ifcs == 0) {
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900148 WILC_TimerDestroy(&hAgingTimer, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900149 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
150
151 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
152 if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) {
153 WILC_FREE(astrLastScannedNtwrksShadow[i].pu8IEs);
154 astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL;
155 }
156
157 host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
158 astrLastScannedNtwrksShadow[i].pJoinParams = NULL;
159 }
160 u32LastScannedNtwrksCountShadow = 0;
161 }
162
163}
164
165uint32_t get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
166{
167 uint8_t i;
168 int rssi_v = 0;
169 uint8_t num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
170
171 for (i = 0; i < num_rssi; i++)
172 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
173
174 rssi_v /= num_rssi;
175 return rssi_v;
176}
177
Dean Lee72ed4dc2015-06-12 14:11:44 +0900178void refresh_scan(void *pUserVoid, uint8_t all, bool bDirectScan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900179{
180 struct WILC_WFI_priv *priv;
181 struct wiphy *wiphy;
182 struct cfg80211_bss *bss = NULL;
183 int i;
184 int rssi = 0;
185
186 priv = (struct WILC_WFI_priv *)pUserVoid;
187 wiphy = priv->dev->ieee80211_ptr->wiphy;
188
189 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
190 tstrNetworkInfo *pstrNetworkInfo;
191 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
192
193
194 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900195 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900196 struct ieee80211_channel *channel;
197
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900198 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900199
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900200 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900201 channel = ieee80211_get_channel(wiphy, s32Freq);
202
203 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900204 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900205 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
206 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900207 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900208 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900209 }
210 }
211
212 }
213 }
214
215}
216
217void reset_shadow_found(void *pUserVoid)
218{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900219 int i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900220 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
221 astrLastScannedNtwrksShadow[i].u8Found = 0;
222
223 }
224}
225
226void update_scan_time(void *pUserVoid)
227{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900228 int i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900229 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
230 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
231 }
232}
233
234void remove_network_from_shadow(void *pUserVoid)
235{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900236 unsigned long now = jiffies;
237 int i, j;
238
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900239
240 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
241 if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530242 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900243
244 if (astrLastScannedNtwrksShadow[i].pu8IEs != NULL) {
245 WILC_FREE(astrLastScannedNtwrksShadow[i].pu8IEs);
246 astrLastScannedNtwrksShadow[i].pu8IEs = NULL;
247 }
248
249 host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
250
251 for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) {
252 astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1];
253 }
254 u32LastScannedNtwrksCountShadow--;
255 }
256 }
257
258 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow);
259 if (u32LastScannedNtwrksCountShadow != 0)
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900260 WILC_TimerStart(&(hAgingTimer), AGING_TIME, pUserVoid, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900261 else
262 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
263}
264
265#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
266void clear_duringIP(void *pUserVoid)
267{
268 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900269 g_obtainingIP = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900270}
271#endif
272
273int8_t is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
274{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900275 int8_t state = -1;
276 int i;
277
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900278 if (u32LastScannedNtwrksCountShadow == 0) {
279 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900280 WILC_TimerStart(&(hAgingTimer), AGING_TIME, pUserVoid, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281 state = -1;
282 } else {
283 /* Linear search for now */
284 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900285 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900286 pstrNetworkInfo->au8bssid, 6) == 0) {
287 state = i;
288 break;
289 }
290 }
291 }
292 return state;
293}
294
295void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
296{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297 int8_t ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
298 uint32_t ap_index = 0;
299 uint8_t rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300
301 if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
302 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
303 return;
304 }
305 if (ap_found == -1) {
306 ap_index = u32LastScannedNtwrksCountShadow;
307 u32LastScannedNtwrksCountShadow++;
308
309 } else {
310 ap_index = ap_found;
311 }
312 rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
313 astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
314 if (rssi_index == NUM_RSSI) {
315 rssi_index = 0;
316 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
317 }
318 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
319
320 astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
321 astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
322
323 astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
324 WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
325 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
326
327 WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
328 pstrNetworkInfo->au8bssid, ETH_ALEN);
329
330 astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
331 astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
332 astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
333
334 astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
335 astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
336 if (ap_found != -1)
337 WILC_FREE(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
338 astrLastScannedNtwrksShadow[ap_index].pu8IEs =
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900339 (u8 *)WILC_MALLOC(pstrNetworkInfo->u16IEsLen); /* will be deallocated by the WILC_WFI_CfgScan() function */
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900340 WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
341 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
342
343 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
344 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
345 astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
346 if (ap_found != -1)
347 host_int_freeJoinParams(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
348 astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
349
350}
351
352
353/**
354 * @brief CfgScanResult
355 * @details Callback function which returns the scan results found
356 *
357 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
358 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
359 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
360 * void* pUserVoid: Private structure associated with the wireless interface
361 * @return NONE
362 * @author mabubakr
363 * @date
364 * @version 1.0
365 */
366static void CfgScanResult(tenuScanEvent enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
367{
368 struct WILC_WFI_priv *priv;
369 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900370 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900371 struct ieee80211_channel *channel;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900372 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900373 struct cfg80211_bss *bss = NULL;
374
375 priv = (struct WILC_WFI_priv *)pUserVoid;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900376 if (priv->bCfgScanning == true) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900377 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
378 wiphy = priv->dev->ieee80211_ptr->wiphy;
379 WILC_NULLCHECK(s32Error, wiphy);
380 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
381 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900382 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900383 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900384 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900385 ) {
386 WILC_ERRORREPORT(s32Error, WILC_FAIL);
387 }
388
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900389 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900390 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900391 channel = ieee80211_get_channel(wiphy, s32Freq);
392
393 WILC_NULLCHECK(s32Error, channel);
394
395 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530396 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900397 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
398
Dean Lee72ed4dc2015-06-12 14:11:44 +0900399 if (pstrNetworkInfo->bNewNetwork == true) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900400 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
401 /* max_scan_ssids */
402 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
403
404
405 priv->u32RcvdChCount++;
406
407
408
409 if (pJoinParams == NULL) {
410 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
411 }
412 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
413
414 /*P2P peers are sent to WPA supplicant and added to shadow table*/
415
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900416 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900417 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
418 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900419 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900420 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900421 }
422
423
424 } else {
425 PRINT_ER("Discovered networks exceeded the max limit\n");
426 }
427 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900428 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900429 /* So this network is discovered before, we'll just update its RSSI */
430 for (i = 0; i < priv->u32RcvdChCount; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900431 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530432 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900433
434 astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
435 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
436 break;
437 }
438 }
439 }
440 }
441 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530442 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
443 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900444 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900445
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530446 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530447 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530448 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530449 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900450
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200451 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900452
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900453 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900454 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900455 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900456 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900457 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200459 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900460
461 }
462 /*Aborting any scan operation during mac close*/
463 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200464 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900465
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530466 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900467 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900468
469 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900470 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900471
Dean Lee72ed4dc2015-06-12 14:11:44 +0900472 cfg80211_scan_done(priv->pstrScanReq, false);
473 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900474 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900475 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200476 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900477 }
478 }
479
480
481 WILC_CATCH(s32Error)
482 {
483 }
484}
485
486
487/**
488 * @brief WILC_WFI_Set_PMKSA
489 * @details Check if pmksa is cached and set it.
490 * @param[in]
491 * @return int : Return 0 on Success
492 * @author mdaftedar
493 * @date 01 MAR 2012
494 * @version 1.0
495 */
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900496int WILC_WFI_Set_PMKSA(u8 *bssid, struct WILC_WFI_priv *priv)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900497{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900498 u32 i;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900499 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900500
501
502 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
503
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900504 if (!memcmp(bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900505 ETH_ALEN)) {
506 PRINT_D(CFG80211_DBG, "PMKID successful comparison");
507
508 /*If bssid is found, set the values*/
509 s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
510
511 if (s32Error != WILC_SUCCESS)
512 PRINT_ER("Error in pmkid\n");
513
514 break;
515 }
516 }
517
518 return s32Error;
519
520
521}
522int linux_wlan_set_bssid(struct net_device *wilc_netdev, uint8_t *pBSSID);
523
524
525/**
526 * @brief CfgConnectResult
527 * @details
528 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
529 * connection response or disconnection notification.
530 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900531 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900532 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
533 * void* pUserVoid: Private data associated with wireless interface
534 * @return NONE
535 * @author mabubakr
536 * @date 01 MAR 2012
537 * @version 1.0
538 */
539int connecting;
540
541static void CfgConnectResult(tenuConnDisconnEvent enuConnDisconnEvent,
542 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900543 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900544 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
545 void *pUserVoid)
546{
547 struct WILC_WFI_priv *priv;
548 struct net_device *dev;
549 #ifdef WILC_P2P
550 tstrWILC_WFIDrv *pstrWFIDrv;
551 #endif
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900552 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900553 connecting = 0;
554
555 priv = (struct WILC_WFI_priv *)pUserVoid;
556 dev = priv->dev;
557 #ifdef WILC_P2P
558 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
559 #endif
560
561 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
562 /*Initialization*/
Chaehyun Limd85f5322015-06-11 14:35:54 +0900563 u16 u16ConnectStatus = WLAN_STATUS_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900564
565 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
566
567 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
568
569 if ((u8MacStatus == MAC_DISCONNECTED) &&
570 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
571 /* The case here is that our station was waiting for association response frame and has just received it containing status code
572 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
573 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
574 linux_wlan_set_bssid(priv->dev, NullBssid);
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900575 memset(u8ConnectedSSID, 0, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900576
577 /*BugID_5457*/
578 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
579 #ifdef WILC_P2P
580 if (!pstrWFIDrv->u8P2PConnect)
581 u8WLANChannel = INVALID_CHANNEL;
582 #endif
583
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530584 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900585 }
586
587 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900588 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900589 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900590
591 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
592 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
593 WILC_memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
594
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900595 /* BugID_4209: if this network has expired in the scan results in the above nl80211 layer, refresh them here by calling
596 * cfg80211_inform_bss() with the last Scan results before calling cfg80211_connect_result() to avoid
597 * Linux kernel warning generated at the nl80211 layer */
598
599 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900600 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900601 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
602 unsigned long now = jiffies;
603
604 if (time_after(now,
605 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900606 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607 }
608
609 break;
610 }
611 }
612
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000613 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900614 /*BugID_5418*/
615 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900616 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900617
618 }
619
620 }
621
622
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530623 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900624
625 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
626
627 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
628 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
629 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
630 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
631 /* be replaced by pstrConnectInfo->u16ConnectStatus */
632 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
633 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Dean Lee72ed4dc2015-06-12 14:11:44 +0900634 g_obtainingIP = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900635 #endif
636 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
637 pstrDisconnectNotifInfo->u16reason, priv->dev);
638 u8P2Plocalrandom = 0x01;
639 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900640 bWilc_ie = false;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900641 memset(priv->au8AssociatedBss, 0, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900642 linux_wlan_set_bssid(priv->dev, NullBssid);
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900643 memset(u8ConnectedSSID, 0, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900644
645 /*BugID_5457*/
646 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
647 #ifdef WILC_P2P
648 if (!pstrWFIDrv->u8P2PConnect)
649 u8WLANChannel = INVALID_CHANNEL;
650 #endif
651 /*BugID_5315*/
652 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
653 * virtual interface to station*/
654 if ((pstrWFIDrv->IFC_UP) && (dev == g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) {
655 pstrDisconnectNotifInfo->u16reason = 3;
656 }
657 /*BugID_5315*/
658 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
659 * to scan again and retry the connection*/
660 else if ((!pstrWFIDrv->IFC_UP) && (dev == g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) {
661 pstrDisconnectNotifInfo->u16reason = 1;
662 }
663 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530664 pstrDisconnectNotifInfo->ie_len, false,
665 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900666
667 }
668
669}
670
671
672/**
673 * @brief WILC_WFI_CfgSetChannel
674 * @details Set channel for a given wireless interface. Some devices
675 * may support multi-channel operation (by channel hopping) so cfg80211
676 * doesn't verify much. Note, however, that the passed netdev may be
677 * %NULL as well if the user requested changing the channel for the
678 * device itself, or for a monitor interface.
679 * @param[in]
680 * @return int : Return 0 on Success
681 * @author mdaftedar
682 * @date 01 MAR 2012
683 * @version 1.0
684 */
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900685static int WILC_WFI_CfgSetChannel(struct wiphy *wiphy,
686 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900687{
688
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900689 u32 channelnum = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900690 struct WILC_WFI_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900691 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900692 priv = wiphy_priv(wiphy);
693
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900694 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
695 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900696
697 u8CurrChannel = channelnum;
698 s32Error = host_int_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
699
700 if (s32Error != WILC_SUCCESS)
701 PRINT_ER("Error in setting channel %d\n", channelnum);
702
703 return s32Error;
704}
705
706/**
707 * @brief WILC_WFI_CfgScan
708 * @details Request to do a scan. If returning zero, the scan request is given
709 * the driver, and will be valid until passed to cfg80211_scan_done().
710 * For scan results, call cfg80211_inform_bss(); you can call this outside
711 * the scan/scan_done bracket too.
712 * @param[in]
713 * @return int : Return 0 on Success
714 * @author mabubakr
715 * @date 01 MAR 2012
716 * @version 1.0
717 */
718
719/*
720 * kernel version 3.8.8 supported
721 * tony, sswd, WILC-KR, 2013-10-29
722 */
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900723static int WILC_WFI_CfgScan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900724{
725 struct WILC_WFI_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900726 u32 i;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900727 s32 s32Error = WILC_SUCCESS;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900728 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900729 tstrHiddenNetwork strHiddenNetwork;
730
731 priv = wiphy_priv(wiphy);
732
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900733 priv->pstrScanReq = request;
734
735 priv->u32RcvdChCount = 0;
736
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900737 host_int_set_wfi_drv_handler((u32)priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900738
739
740 reset_shadow_found(priv);
741
Dean Lee72ed4dc2015-06-12 14:11:44 +0900742 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900743 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
744 /* max_scan_ssids */
745 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900746 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900747 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
748 }
749
750 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530751 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900752
753 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
754
755 if (request->n_ssids >= 1) {
756
757
758 strHiddenNetwork.pstrHiddenNetworkInfo = WILC_MALLOC(request->n_ssids * sizeof(tstrHiddenNetwork));
759 strHiddenNetwork.u8ssidnum = request->n_ssids;
760
761
762 /*BugID_4156*/
763 for (i = 0; i < request->n_ssids; i++) {
764
765 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
766 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = WILC_MALLOC(request->ssids[i].ssid_len);
767 WILC_memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
768 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
769 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530770 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900771 strHiddenNetwork.u8ssidnum -= 1;
772 }
773 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530774 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900775 s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
776 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900777 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900778 CfgScanResult, (void *)priv, &strHiddenNetwork);
779 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530780 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900781 s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
782 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900783 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900784 CfgScanResult, (void *)priv, NULL);
785 }
786
787 } else {
788 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530789 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900790 }
791
792 if (s32Error != WILC_SUCCESS) {
793 s32Error = -EBUSY;
794 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
795 }
796
797 return s32Error;
798}
799
800/**
801 * @brief WILC_WFI_CfgConnect
802 * @details Connect to the ESS with the specified parameters. When connected,
803 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
804 * If the connection fails for some reason, call cfg80211_connect_result()
805 * with the status from the AP.
806 * @param[in]
807 * @return int : Return 0 on Success
808 * @author mabubakr
809 * @date 01 MAR 2012
810 * @version 1.0
811 */
812static int WILC_WFI_CfgConnect(struct wiphy *wiphy, struct net_device *dev,
813 struct cfg80211_connect_params *sme)
814{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900815 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900816 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900817 u8 u8security = NO_ENCRYPT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900818 AUTHTYPE_T tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900819 char *pcgroup_encrypt_val = NULL;
820 char *pccipher_group = NULL;
821 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900822
823 struct WILC_WFI_priv *priv;
824 tstrWILC_WFIDrv *pstrWFIDrv;
825 tstrNetworkInfo *pstrNetworkInfo = NULL;
826
827
828 connecting = 1;
829 priv = wiphy_priv(wiphy);
830 pstrWFIDrv = (tstrWILC_WFIDrv *)(priv->hWILCWFIDrv);
831
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900832 host_int_set_wfi_drv_handler((u32)priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900833
Johnny Kim8a143302015-06-10 17:06:46 +0900834 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835 #ifdef WILC_P2P
836 if (!(WILC_strncmp(sme->ssid, "DIRECT-", 7))) {
837 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
838 pstrWFIDrv->u8P2PConnect = 1;
839 } else
840 pstrWFIDrv->u8P2PConnect = 0;
841 #endif
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530842 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900843
844 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
845 if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900846 memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900847 sme->ssid,
848 sme->ssid_len) == 0) {
849 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
850 if (sme->bssid == NULL) {
851 /* BSSID is not passed from the user, so decision of matching
852 * is done by SSID only */
853 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
854 break;
855 } else {
856 /* BSSID is also passed from the user, so decision of matching
857 * should consider also this passed BSSID */
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900858 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900859 sme->bssid,
860 ETH_ALEN) == 0) {
861 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
862 break;
863 }
864 }
865 }
866 }
867
868 if (i < u32LastScannedNtwrksCountShadow) {
869 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
870
871 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
872
873 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
874 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
875 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
876 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
877 } else {
878 s32Error = -ENOENT;
879 if (u32LastScannedNtwrksCountShadow == 0)
880 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
881 else
882 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
883
884 goto done;
885 }
886
887 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900888 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
889 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900890
891 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
892 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
893
894 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
895
896 if (INFO) {
897 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
898 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
899 }
900
901 if (sme->crypto.cipher_group != NO_ENCRYPT) {
902 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
903 * we will add to it the pairwise cipher suite(s) */
904 pcwpa_version = "Default";
905 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900906 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900907 u8security = ENCRYPT_ENABLED | WEP;
908 pcgroup_encrypt_val = "WEP40";
909 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
910 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
911
912 if (INFO) {
913 for (i = 0; i < sme->key_len; i++)
914 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
915 }
916 priv->WILC_WFI_wep_default = sme->key_idx;
917 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
918 WILC_memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
919
920 /*BugID_5137*/
921 g_key_wep_params.key_len = sme->key_len;
922 g_key_wep_params.key = WILC_MALLOC(sme->key_len);
923 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
924 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900925 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900926
927 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, sme->key_idx);
928 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
929 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
931 pcgroup_encrypt_val = "WEP104";
932 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
933
934 priv->WILC_WFI_wep_default = sme->key_idx;
935 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
936 WILC_memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
937
938 /*BugID_5137*/
939 g_key_wep_params.key_len = sme->key_len;
940 g_key_wep_params.key = WILC_MALLOC(sme->key_len);
941 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
942 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900943 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900944
945 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, sme->key_idx);
946 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
947 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900948 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900949 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
950 pcgroup_encrypt_val = "WPA2_TKIP";
951 pccipher_group = "TKIP";
952 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
953 /* tenuSecurity_t = WPA2_AES; */
954 u8security = ENCRYPT_ENABLED | WPA2 | AES;
955 pcgroup_encrypt_val = "WPA2_AES";
956 pccipher_group = "AES";
957 }
958 pcwpa_version = "WPA_VERSION_2";
959 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
960 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900961 u8security = ENCRYPT_ENABLED | WPA | TKIP;
962 pcgroup_encrypt_val = "WPA_TKIP";
963 pccipher_group = "TKIP";
964 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
965 /* tenuSecurity_t = WPA_AES; */
966 u8security = ENCRYPT_ENABLED | WPA | AES;
967 pcgroup_encrypt_val = "WPA_AES";
968 pccipher_group = "AES";
969
970 }
971 pcwpa_version = "WPA_VERSION_1";
972
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900973 } else {
974 s32Error = -ENOTSUPP;
975 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
976
977 goto done;
978 }
979
980 }
981
982 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
983 * add to it the pairwise cipher suite(s) */
984 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
985 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
986 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
987 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
988 u8security = u8security | TKIP;
989 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
990 u8security = u8security | AES;
991 }
992 }
993 }
994
995 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
996
997 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
998 switch (sme->auth_type) {
999 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1000 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
1001 tenuAuth_type = OPEN_SYSTEM;
1002 break;
1003
1004 case NL80211_AUTHTYPE_SHARED_KEY:
1005 tenuAuth_type = SHARED_KEY;
1006 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
1007 break;
1008
1009 default:
1010 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1011 }
1012
1013
1014 /* ai: key_mgmt: enterprise case */
1015 if (sme->crypto.n_akm_suites) {
1016 switch (sme->crypto.akm_suites[0]) {
1017 case WLAN_AKM_SUITE_8021X:
1018 tenuAuth_type = IEEE8021;
1019 break;
1020
1021 default:
1022 break;
1023 }
1024 }
1025
1026
1027 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1028
1029 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1030 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1031
1032 /*BugID_5442*/
1033 u8CurrChannel = pstrNetworkInfo->u8channel;
1034
1035 if (!pstrWFIDrv->u8P2PConnect) {
1036 u8WLANChannel = pstrNetworkInfo->u8channel;
1037 }
1038
1039 linux_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
1040
1041 s32Error = host_int_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
1042 sme->ssid_len, sme->ie, sme->ie_len,
1043 CfgConnectResult, (void *)priv, u8security,
1044 tenuAuth_type, pstrNetworkInfo->u8channel,
1045 pstrNetworkInfo->pJoinParams);
1046 if (s32Error != WILC_SUCCESS) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301047 PRINT_ER("host_int_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001048 s32Error = -ENOENT;
1049 goto done;
1050 }
1051
1052done:
1053
1054 return s32Error;
1055}
1056
1057
1058/**
1059 * @brief WILC_WFI_disconnect
1060 * @details Disconnect from the BSS/ESS.
1061 * @param[in]
1062 * @return int : Return 0 on Success
1063 * @author mdaftedar
1064 * @date 01 MAR 2012
1065 * @version 1.0
1066 */
1067static int WILC_WFI_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
1068{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001069 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001070 struct WILC_WFI_priv *priv;
1071 #ifdef WILC_P2P
1072 tstrWILC_WFIDrv *pstrWFIDrv;
1073 #endif
1074 uint8_t NullBssid[ETH_ALEN] = {0};
1075 connecting = 0;
1076 priv = wiphy_priv(wiphy);
1077
1078 /*BugID_5457*/
1079 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
1080 #ifdef WILC_P2P
1081 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
1082 if (!pstrWFIDrv->u8P2PConnect)
1083 u8WLANChannel = INVALID_CHANNEL;
1084 #endif
1085 linux_wlan_set_bssid(priv->dev, NullBssid);
1086
1087 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1088
1089 u8P2Plocalrandom = 0x01;
1090 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001091 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001092 #ifdef WILC_P2P
1093 pstrWFIDrv->u64P2p_MgmtTimeout = 0;
1094 #endif
1095
1096 s32Error = host_int_disconnect(priv->hWILCWFIDrv, reason_code);
1097 if (s32Error != WILC_SUCCESS) {
1098 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1099 s32Error = -EINVAL;
1100 }
1101
1102 return s32Error;
1103}
1104
1105/**
1106 * @brief WILC_WFI_add_key
1107 * @details Add a key with the given parameters. @mac_addr will be %NULL
1108 * when adding a group key.
1109 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1110 * @return int : Return 0 on Success
1111 * @author mdaftedar
1112 * @date 01 MAR 2012
1113 * @version 1.0
1114 */
1115static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001116 bool pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001117 const u8 *mac_addr, struct key_params *params)
1118
1119{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001120 s32 s32Error = WILC_SUCCESS, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001121 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001122 struct WILC_WFI_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001123 const u8 *pu8RxMic = NULL;
1124 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001125 u8 u8mode = NO_ENCRYPT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001126 #ifdef WILC_AP_EXTERNAL_MLME
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001127 u8 u8gmode = NO_ENCRYPT;
1128 u8 u8pmode = NO_ENCRYPT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001129 AUTHTYPE_T tenuAuth_type = ANY;
1130 #endif
1131
1132 priv = wiphy_priv(wiphy);
1133
1134 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1135
1136 /*BugID_5137*/
Johnny Kim8a143302015-06-10 17:06:46 +09001137 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001138
1139 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1140 params->key[1],
1141 params->key[2]);
1142
1143
1144 switch (params->cipher) {
1145 case WLAN_CIPHER_SUITE_WEP40:
1146 case WLAN_CIPHER_SUITE_WEP104:
1147 #ifdef WILC_AP_EXTERNAL_MLME
1148 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1149
1150 priv->WILC_WFI_wep_default = key_index;
1151 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
1152 WILC_memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
1153
1154 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1155 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1156
1157 for (i = 0; i < params->key_len; i++)
1158 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1159
1160 tenuAuth_type = OPEN_SYSTEM;
1161
1162 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1163 u8mode = ENCRYPT_ENABLED | WEP;
1164 else
1165 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1166
1167 host_int_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
1168 break;
1169 }
1170 #endif
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001171 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001172 priv->WILC_WFI_wep_default = key_index;
1173 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
1174 WILC_memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
1175
1176 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1177 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1178 if (INFO) {
1179 for (i = 0; i < params->key_len; i++)
1180 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1181 }
1182 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
1183 }
1184
1185 break;
1186
1187 case WLAN_CIPHER_SUITE_TKIP:
1188 case WLAN_CIPHER_SUITE_CCMP:
1189 #ifdef WILC_AP_EXTERNAL_MLME
1190 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1191
1192 if (priv->wilc_gtk[key_index] == NULL) {
1193 priv->wilc_gtk[key_index] = (struct wilc_wfi_key *)WILC_MALLOC(sizeof(struct wilc_wfi_key));
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001194 priv->wilc_gtk[key_index]->key = NULL;
1195 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001196
1197 }
1198 if (priv->wilc_ptk[key_index] == NULL) {
1199 priv->wilc_ptk[key_index] = (struct wilc_wfi_key *)WILC_MALLOC(sizeof(struct wilc_wfi_key));
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001200 priv->wilc_ptk[key_index]->key = NULL;
1201 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001202 }
1203
1204
1205
Daniel Machon19132212015-08-05 08:18:31 +02001206 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001207 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1208 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1209 else
1210 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1211
1212 priv->wilc_groupkey = u8gmode;
1213
1214 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1215
1216 pu8TxMic = params->key + 24;
1217 pu8RxMic = params->key + 16;
1218 KeyLen = params->key_len - 16;
1219 }
1220 /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
1221 if (priv->wilc_gtk[key_index]->key)
1222 WILC_FREE(priv->wilc_gtk[key_index]->key);
1223
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001224 priv->wilc_gtk[key_index]->key = (u8 *)WILC_MALLOC(params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001225 WILC_memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
1226
1227 /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
1228 if (priv->wilc_gtk[key_index]->seq)
1229 WILC_FREE(priv->wilc_gtk[key_index]->seq);
1230
1231 if ((params->seq_len) > 0) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001232 priv->wilc_gtk[key_index]->seq = (u8 *)WILC_MALLOC(params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001233 WILC_memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
1234 }
1235
1236 priv->wilc_gtk[key_index]->cipher = params->cipher;
1237 priv->wilc_gtk[key_index]->key_len = params->key_len;
1238 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1239
1240 if (INFO) {
1241 for (i = 0; i < params->key_len; i++)
1242 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1243 for (i = 0; i < params->seq_len; i++)
1244 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1245 }
1246
1247
1248 host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
1249 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1250
1251 } else {
1252 PRINT_INFO(CFG80211_DBG, "STA Address: %x%x%x%x%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4]);
1253
1254 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1255 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1256 else
1257 u8pmode = priv->wilc_groupkey | AES;
1258
1259
1260 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1261
1262 pu8TxMic = params->key + 24;
1263 pu8RxMic = params->key + 16;
1264 KeyLen = params->key_len - 16;
1265 }
1266
1267 if (priv->wilc_ptk[key_index]->key)
1268 WILC_FREE(priv->wilc_ptk[key_index]->key);
1269
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001270 priv->wilc_ptk[key_index]->key = (u8 *)WILC_MALLOC(params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001271
1272 if (priv->wilc_ptk[key_index]->seq)
1273 WILC_FREE(priv->wilc_ptk[key_index]->seq);
1274
1275 if ((params->seq_len) > 0)
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001276 priv->wilc_ptk[key_index]->seq = (u8 *)WILC_MALLOC(params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001277
1278 if (INFO) {
1279 for (i = 0; i < params->key_len; i++)
1280 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1281
1282 for (i = 0; i < params->seq_len; i++)
1283 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1284 }
1285
1286 WILC_memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
1287
1288 if ((params->seq_len) > 0)
1289 WILC_memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
1290
1291 priv->wilc_ptk[key_index]->cipher = params->cipher;
1292 priv->wilc_ptk[key_index]->key_len = params->key_len;
1293 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1294
1295 host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
1296 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1297 }
1298 break;
1299 }
1300 #endif
1301
1302 {
1303 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001304 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001305 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1306 /* swap the tx mic by rx mic */
1307 pu8RxMic = params->key + 24;
1308 pu8TxMic = params->key + 16;
1309 KeyLen = params->key_len - 16;
1310 }
1311
1312 /*BugID_5137*/
1313 /*save keys only on interface 0 (wifi interface)*/
1314 if (!g_gtk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
1315 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001316 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001317 if (!mac_addr) {
1318 g_add_gtk_key_params.mac_addr = NULL;
1319 } else {
1320 g_add_gtk_key_params.mac_addr = WILC_MALLOC(ETH_ALEN);
1321 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1322 }
1323 g_key_gtk_params.key_len = params->key_len;
1324 g_key_gtk_params.seq_len = params->seq_len;
1325 g_key_gtk_params.key = WILC_MALLOC(params->key_len);
1326 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1327 if (params->seq_len > 0) {
1328 g_key_gtk_params.seq = WILC_MALLOC(params->seq_len);
1329 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1330 }
1331 g_key_gtk_params.cipher = params->cipher;
1332
1333 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1334 g_key_gtk_params.key[1],
1335 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001336 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001337 }
1338
1339 host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
1340 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001341 } else {
1342 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1343 /* swap the tx mic by rx mic */
1344 pu8RxMic = params->key + 24;
1345 pu8TxMic = params->key + 16;
1346 KeyLen = params->key_len - 16;
1347 }
1348
1349 /*BugID_5137*/
1350 /*save keys only on interface 0 (wifi interface)*/
1351 if (!g_ptk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
1352 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001353 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001354 if (!mac_addr) {
1355 g_add_ptk_key_params.mac_addr = NULL;
1356 } else {
1357 g_add_ptk_key_params.mac_addr = WILC_MALLOC(ETH_ALEN);
1358 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1359 }
1360 g_key_ptk_params.key_len = params->key_len;
1361 g_key_ptk_params.seq_len = params->seq_len;
1362 g_key_ptk_params.key = WILC_MALLOC(params->key_len);
1363 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1364 if (params->seq_len > 0) {
1365 g_key_ptk_params.seq = WILC_MALLOC(params->seq_len);
1366 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1367 }
1368 g_key_ptk_params.cipher = params->cipher;
1369
1370 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1371 g_key_ptk_params.key[1],
1372 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001373 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001374 }
1375
1376 host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
1377 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1378 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1379 if (INFO) {
1380 for (i = 0; i < params->key_len; i++)
1381 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1382 }
1383 }
1384 }
1385 break;
1386
1387 default:
1388 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1389 s32Error = -ENOTSUPP;
1390
1391 }
1392
1393 return s32Error;
1394}
1395
1396/**
1397 * @brief WILC_WFI_del_key
1398 * @details Remove a key given the @mac_addr (%NULL for a group key)
1399 * and @key_index, return -ENOENT if the key doesn't exist.
1400 * @param[in]
1401 * @return int : Return 0 on Success
1402 * @author mdaftedar
1403 * @date 01 MAR 2012
1404 * @version 1.0
1405 */
1406static int WILC_WFI_del_key(struct wiphy *wiphy, struct net_device *netdev,
1407 u8 key_index,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001408 bool pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001409 const u8 *mac_addr)
1410{
1411 struct WILC_WFI_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001412 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001413
1414 priv = wiphy_priv(wiphy);
1415
1416 /*BugID_5137*/
1417 /*delete saved keys, if any*/
1418 if (netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001419 g_ptk_keys_saved = false;
1420 g_gtk_keys_saved = false;
1421 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001422
1423 /*Delete saved WEP keys params, if any*/
1424 if (g_key_wep_params.key != NULL) {
1425 WILC_FREE(g_key_wep_params.key);
1426 g_key_wep_params.key = NULL;
1427 }
1428
1429 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1430
1431 #ifdef WILC_AP_EXTERNAL_MLME
1432 if ((priv->wilc_gtk[key_index]) != NULL) {
1433
1434 if (priv->wilc_gtk[key_index]->key != NULL) {
1435
1436 WILC_FREE(priv->wilc_gtk[key_index]->key);
1437 priv->wilc_gtk[key_index]->key = NULL;
1438 }
1439 if (priv->wilc_gtk[key_index]->seq) {
1440
1441 WILC_FREE(priv->wilc_gtk[key_index]->seq);
1442 priv->wilc_gtk[key_index]->seq = NULL;
1443 }
1444
1445 WILC_FREE(priv->wilc_gtk[key_index]);
1446 priv->wilc_gtk[key_index] = NULL;
1447
1448 }
1449
1450 if ((priv->wilc_ptk[key_index]) != NULL) {
1451
1452 if (priv->wilc_ptk[key_index]->key) {
1453
1454 WILC_FREE(priv->wilc_ptk[key_index]->key);
1455 priv->wilc_ptk[key_index]->key = NULL;
1456 }
1457 if (priv->wilc_ptk[key_index]->seq) {
1458
1459 WILC_FREE(priv->wilc_ptk[key_index]->seq);
1460 priv->wilc_ptk[key_index]->seq = NULL;
1461 }
1462 WILC_FREE(priv->wilc_ptk[key_index]);
1463 priv->wilc_ptk[key_index] = NULL;
1464 }
1465 #endif
1466
1467 /*Delete saved PTK and GTK keys params, if any*/
1468 if (g_key_ptk_params.key != NULL) {
1469 WILC_FREE(g_key_ptk_params.key);
1470 g_key_ptk_params.key = NULL;
1471 }
1472 if (g_key_ptk_params.seq != NULL) {
1473 WILC_FREE(g_key_ptk_params.seq);
1474 g_key_ptk_params.seq = NULL;
1475 }
1476
1477 if (g_key_gtk_params.key != NULL) {
1478 WILC_FREE(g_key_gtk_params.key);
1479 g_key_gtk_params.key = NULL;
1480 }
1481 if (g_key_gtk_params.seq != NULL) {
1482 WILC_FREE(g_key_gtk_params.seq);
1483 g_key_gtk_params.seq = NULL;
1484 }
1485
1486 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Dean Lee72ed4dc2015-06-12 14:11:44 +09001487 Set_machw_change_vir_if(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001488 }
1489
1490 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001491 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001492 priv->WILC_WFI_wep_key_len[key_index] = 0;
1493
1494 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
1495 host_int_remove_wep_key(priv->hWILCWFIDrv, key_index);
1496 } else {
1497 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
1498 host_int_remove_key(priv->hWILCWFIDrv, mac_addr);
1499 }
1500
1501 return s32Error;
1502}
1503
1504/**
1505 * @brief WILC_WFI_get_key
1506 * @details Get information about the key with the given parameters.
1507 * @mac_addr will be %NULL when requesting information for a group
1508 * key. All pointers given to the @callback function need not be valid
1509 * after it returns. This function should return an error if it is
1510 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1511 * @param[in]
1512 * @return int : Return 0 on Success
1513 * @author mdaftedar
1514 * @date 01 MAR 2012
1515 * @version 1.0
1516 */
1517static int WILC_WFI_get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001518 bool pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001519 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1520{
1521
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001522 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001523
1524 struct WILC_WFI_priv *priv;
1525 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001526 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001527 priv = wiphy_priv(wiphy);
1528
1529
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001530 if (!pairwise)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001531 {
1532 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1533
1534 key_params.key = priv->wilc_gtk[key_index]->key;
1535 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1536 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1537 key_params.seq = priv->wilc_gtk[key_index]->seq;
1538 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1539 if (INFO) {
1540 for (i = 0; i < key_params.key_len; i++)
1541 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1542 }
1543 } else {
1544 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1545
1546 key_params.key = priv->wilc_ptk[key_index]->key;
1547 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1548 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1549 key_params.seq = priv->wilc_ptk[key_index]->seq;
1550 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1551 }
1552
1553 callback(cookie, &key_params);
1554
1555 return s32Error; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
1556}
1557
1558/**
1559 * @brief WILC_WFI_set_default_key
1560 * @details Set the default management frame key on an interface
1561 * @param[in]
1562 * @return int : Return 0 on Success.
1563 * @author mdaftedar
1564 * @date 01 MAR 2012
1565 * @version 1.0
1566 */
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001567static int WILC_WFI_set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1568 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001569{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001570 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001571 struct WILC_WFI_priv *priv;
1572
1573
1574 priv = wiphy_priv(wiphy);
1575
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301576 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001577
1578 if (key_index != priv->WILC_WFI_wep_default) {
1579
1580 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, key_index);
1581 }
1582
1583 return s32Error;
1584}
1585
1586/**
1587 * @brief WILC_WFI_dump_survey
1588 * @details Get site survey information
1589 * @param[in]
1590 * @return int : Return 0 on Success.
1591 * @author mdaftedar
1592 * @date 01 MAR 2012
1593 * @version 1.0
1594 */
1595static int WILC_WFI_dump_survey(struct wiphy *wiphy, struct net_device *netdev,
1596 int idx, struct survey_info *info)
1597{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001598 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001599
1600
1601 if (idx != 0) {
1602 s32Error = -ENOENT;
1603 PRINT_ER("Error Idx value doesn't equal zero: Error(%d)\n", s32Error);
1604
1605 }
1606
1607 return s32Error;
1608}
1609
1610
1611/**
1612 * @brief WILC_WFI_get_station
1613 * @details Get station information for the station identified by @mac
1614 * @param[in] NONE
1615 * @return int : Return 0 on Success.
1616 * @author mdaftedar
1617 * @date 01 MAR 2012
1618 * @version 1.0
1619 */
1620
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001621static int WILC_WFI_get_station(struct wiphy *wiphy, struct net_device *dev,
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001622 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001623{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001624 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001625 struct WILC_WFI_priv *priv;
1626 perInterface_wlan_t *nic;
1627 #ifdef WILC_AP_EXTERNAL_MLME
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001628 u32 i = 0;
1629 u32 associatedsta = 0;
1630 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001631 #endif
1632 priv = wiphy_priv(wiphy);
1633 nic = netdev_priv(dev);
1634
1635 #ifdef WILC_AP_EXTERNAL_MLME
1636 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1637 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1638
1639 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1640
1641 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1642
1643 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1644 associatedsta = i;
1645 break;
1646 }
1647
1648 }
1649
1650 if (associatedsta == -1) {
1651 s32Error = -ENOENT;
1652 PRINT_ER("Station required is not associated : Error(%d)\n", s32Error);
1653
1654 return s32Error;
1655 }
1656
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001657 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001658
1659 host_int_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
1660 sinfo->inactive_time = 1000 * inactive_time;
1661 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1662
1663 }
1664 #endif
1665
1666 if (nic->iftype == STATION_MODE) {
1667 tstrStatistics strStatistics;
1668 host_int_get_statistics(priv->hWILCWFIDrv, &strStatistics);
1669
1670 /*
1671 * tony: 2013-11-13
1672 * tx_failed introduced more than
1673 * kernel version 3.0.0
1674 */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001675 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301676 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001677 BIT(NL80211_STA_INFO_TX_PACKETS) |
1678 BIT(NL80211_STA_INFO_TX_FAILED) |
1679 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001680
1681 sinfo->signal = strStatistics.s8RSSI;
1682 sinfo->rx_packets = strStatistics.u32RxCount;
1683 sinfo->tx_packets = strStatistics.u32TxCount + strStatistics.u32TxFailureCount;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001684 sinfo->tx_failed = strStatistics.u32TxFailureCount;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001685 sinfo->txrate.legacy = strStatistics.u8LinkSpeed * 10;
1686
1687#ifdef TCP_ENHANCEMENTS
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301688 if ((strStatistics.u8LinkSpeed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED))
Dean Lee72ed4dc2015-06-12 14:11:44 +09001689 Enable_TCP_ACK_Filter(true);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301690 else if (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED)
Dean Lee72ed4dc2015-06-12 14:11:44 +09001691 Enable_TCP_ACK_Filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001692#endif
1693
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001694 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1695 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001696 }
1697 return s32Error;
1698}
1699
1700
1701/**
1702 * @brief WILC_WFI_change_bss
1703 * @details Modify parameters for a given BSS.
1704 * @param[in]
1705 * -use_cts_prot: Whether to use CTS protection
1706 * (0 = no, 1 = yes, -1 = do not change)
1707 * -use_short_preamble: Whether the use of short preambles is allowed
1708 * (0 = no, 1 = yes, -1 = do not change)
1709 * -use_short_slot_time: Whether the use of short slot time is allowed
1710 * (0 = no, 1 = yes, -1 = do not change)
1711 * -basic_rates: basic rates in IEEE 802.11 format
1712 * (or NULL for no change)
1713 * -basic_rates_len: number of basic rates
1714 * -ap_isolate: do not forward packets between connected stations
1715 * -ht_opmode: HT Operation mode
1716 * (u16 = opmode, -1 = do not change)
1717 * @return int : Return 0 on Success.
1718 * @author mdaftedar
1719 * @date 01 MAR 2012
1720 * @version 1.0
1721 */
1722static int WILC_WFI_change_bss(struct wiphy *wiphy, struct net_device *dev,
1723 struct bss_parameters *params)
1724{
1725 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1726 return 0;
1727}
1728
1729/**
1730 * @brief WILC_WFI_auth
1731 * @details Request to authenticate with the specified peer
1732 * @param[in]
1733 * @return int : Return 0 on Success.
1734 * @author mdaftedar
1735 * @date 01 MAR 2012
1736 * @version 1.0
1737 */
1738static int WILC_WFI_auth(struct wiphy *wiphy, struct net_device *dev,
1739 struct cfg80211_auth_request *req)
1740{
1741 PRINT_D(CFG80211_DBG, "In Authentication Function\n");
1742 return 0;
1743}
1744
1745/**
1746 * @brief WILC_WFI_assoc
1747 * @details Request to (re)associate with the specified peer
1748 * @param[in]
1749 * @return int : Return 0 on Success.
1750 * @author mdaftedar
1751 * @date 01 MAR 2012
1752 * @version 1.0
1753 */
1754static int WILC_WFI_assoc(struct wiphy *wiphy, struct net_device *dev,
1755 struct cfg80211_assoc_request *req)
1756{
1757 PRINT_D(CFG80211_DBG, "In Association Function\n");
1758 return 0;
1759}
1760
1761/**
1762 * @brief WILC_WFI_deauth
1763 * @details Request to deauthenticate from the specified peer
1764 * @param[in]
1765 * @return int : Return 0 on Success.
1766 * @author mdaftedar
1767 * @date 01 MAR 2012
1768 * @version 1.0
1769 */
1770static int WILC_WFI_deauth(struct wiphy *wiphy, struct net_device *dev,
1771 struct cfg80211_deauth_request *req, void *cookie)
1772{
1773 PRINT_D(CFG80211_DBG, "In De-authentication Function\n");
1774 return 0;
1775}
1776
1777/**
1778 * @brief WILC_WFI_disassoc
1779 * @details Request to disassociate from the specified peer
1780 * @param[in]
1781 * @return int : Return 0 on Success
1782 * @author mdaftedar
1783 * @date 01 MAR 2012
1784 * @version 1.0
1785 */
1786static int WILC_WFI_disassoc(struct wiphy *wiphy, struct net_device *dev,
1787 struct cfg80211_disassoc_request *req, void *cookie)
1788{
1789 PRINT_D(CFG80211_DBG, "In Disassociation Function\n");
1790 return 0;
1791}
1792
1793/**
1794 * @brief WILC_WFI_set_wiphy_params
1795 * @details Notify that wiphy parameters have changed;
1796 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1797 * have changed.
1798 * @return int : Return 0 on Success
1799 * @author mdaftedar
1800 * @date 01 MAR 2012
1801 * @version 1.0
1802 */
1803static int WILC_WFI_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1804{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001805 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001806 tstrCfgParamVal pstrCfgParamVal;
1807 struct WILC_WFI_priv *priv;
1808
1809 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001810
1811 pstrCfgParamVal.u32SetCfgFlag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301812 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001813
1814 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1815 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1816 priv->dev->ieee80211_ptr->wiphy->retry_short);
1817 pstrCfgParamVal.u32SetCfgFlag |= RETRY_SHORT;
1818 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1819 }
1820 if (changed & WIPHY_PARAM_RETRY_LONG) {
1821
1822 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
1823 pstrCfgParamVal.u32SetCfgFlag |= RETRY_LONG;
1824 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1825
1826 }
1827 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1828 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
1829 pstrCfgParamVal.u32SetCfgFlag |= FRAG_THRESHOLD;
1830 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1831
1832 }
1833
1834 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1835 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1836
1837 pstrCfgParamVal.u32SetCfgFlag |= RTS_THRESHOLD;
1838 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1839
1840 }
1841
1842 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
1843 s32Error = hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
1844 if (s32Error)
1845 PRINT_ER("Error in setting WIPHY PARAMS\n");
1846
1847
1848 return s32Error;
1849}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001850
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851/**
1852 * @brief WILC_WFI_set_bitrate_mask
1853 * @details set the bitrate mask configuration
1854 * @param[in]
1855 * @return int : Return 0 on Success
1856 * @author mdaftedar
1857 * @date 01 MAR 2012
1858 * @version 1.0
1859 */
1860static int WILC_WFI_set_bitrate_mask(struct wiphy *wiphy,
1861 struct net_device *dev, const u8 *peer,
1862 const struct cfg80211_bitrate_mask *mask)
1863{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001864 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001865
1866 PRINT_D(CFG80211_DBG, "Setting Bitrate mask function\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001867 return s32Error;
1868
1869}
1870
1871/**
1872 * @brief WILC_WFI_set_pmksa
1873 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1874 * devices running firmwares capable of generating the (re) association
1875 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1876 * @param[in]
1877 * @return int : Return 0 on Success
1878 * @author mdaftedar
1879 * @date 01 MAR 2012
1880 * @version 1.0
1881 */
1882static int WILC_WFI_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1883 struct cfg80211_pmksa *pmksa)
1884{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001885 u32 i;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001886 s32 s32Error = WILC_SUCCESS;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001887 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001888
1889 struct WILC_WFI_priv *priv = wiphy_priv(wiphy);
1890
1891 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1892
1893
1894 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001895 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001896 ETH_ALEN)) {
1897 /*If bssid already exists and pmkid value needs to reset*/
1898 flag = PMKID_FOUND;
1899 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1900 break;
1901 }
1902 }
1903 if (i < WILC_MAX_NUM_PMKIDS) {
1904 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
1905 WILC_memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1906 ETH_ALEN);
1907 WILC_memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1908 PMKID_LEN);
1909 if (!(flag == PMKID_FOUND))
1910 priv->pmkid_list.numpmkid++;
1911 } else {
1912 PRINT_ER("Invalid PMKID index\n");
1913 s32Error = -EINVAL;
1914 }
1915
1916 if (!s32Error) {
1917 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
1918 s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
1919 }
1920 return s32Error;
1921}
1922
1923/**
1924 * @brief WILC_WFI_del_pmksa
1925 * @details Delete a cached PMKID.
1926 * @param[in]
1927 * @return int : Return 0 on Success
1928 * @author mdaftedar
1929 * @date 01 MAR 2012
1930 * @version 1.0
1931 */
1932static int WILC_WFI_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1933 struct cfg80211_pmksa *pmksa)
1934{
1935
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001936 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001937 u8 flag = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001938 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001939
1940 struct WILC_WFI_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001941
1942 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1943
1944 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001945 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001946 ETH_ALEN)) {
1947 /*If bssid is found, reset the values*/
1948 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001949 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(tstrHostIFpmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001950 flag = PMKID_FOUND;
1951 break;
1952 }
1953 }
1954
1955 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1956 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1957 WILC_memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1958 priv->pmkid_list.pmkidlist[i + 1].bssid,
1959 ETH_ALEN);
1960 WILC_memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1961 priv->pmkid_list.pmkidlist[i].pmkid,
1962 PMKID_LEN);
1963 }
1964 priv->pmkid_list.numpmkid--;
1965 } else {
1966 s32Error = -EINVAL;
1967 }
1968
1969 return s32Error;
1970}
1971
1972/**
1973 * @brief WILC_WFI_flush_pmksa
1974 * @details Flush all cached PMKIDs.
1975 * @param[in]
1976 * @return int : Return 0 on Success
1977 * @author mdaftedar
1978 * @date 01 MAR 2012
1979 * @version 1.0
1980 */
1981static int WILC_WFI_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1982{
1983 struct WILC_WFI_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001984
1985 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1986
1987 /*Get cashed Pmkids and set all with zeros*/
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001988 memset(&priv->pmkid_list, 0, sizeof(tstrHostIFpmkidAttr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001989
1990 return 0;
1991}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001992
1993#ifdef WILC_P2P
1994
1995/**
1996 * @brief WILC_WFI_CfgParseRxAction
1997 * @details Function parses the received frames and modifies the following attributes:
1998 * -GO Intent
1999 * -Channel list
2000 * -Operating Channel
2001 *
2002 * @param[in] u8* Buffer, u32 length
2003 * @return NONE.
2004 * @author mdaftedar
2005 * @date 12 DEC 2012
2006 * @version
2007 */
2008
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002009void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002010{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002011 u32 index = 0;
2012 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002013
2014 /*BugID_5460*/
2015 #ifdef USE_SUPPLICANT_GO_INTENT
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002016 u8 intent;
2017 u8 tie_breaker;
Dean Lee72ed4dc2015-06-12 14:11:44 +09002018 bool is_wilc_go = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002019 #endif
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002020 u8 op_channel_attr_index = 0;
2021 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002022
2023 while (index < len) {
2024 if (buf[index] == GO_INTENT_ATTR_ID) {
2025 #ifdef USE_SUPPLICANT_GO_INTENT
2026 /*BugID_5460*/
2027 /*Case 1: If we are going to be p2p client, no need to modify channels attributes*/
2028 /*In negotiation frames, go intent attr value determines who will be GO*/
2029 intent = GET_GO_INTENT(buf[index + 3]);
2030 tie_breaker = GET_TIE_BREAKER(buf[index + 3]);
2031 if (intent > SUPPLICANT_GO_INTENT
2032 || (intent == SUPPLICANT_GO_INTENT && tie_breaker == 1)) {
2033 PRINT_D(GENERIC_DBG, "WILC will be client (intent %d tie breaker %d)\n", intent, tie_breaker);
Dean Lee72ed4dc2015-06-12 14:11:44 +09002034 is_wilc_go = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002035 } else {
2036 PRINT_D(GENERIC_DBG, "WILC will be GO (intent %d tie breaker %d)\n", intent, tie_breaker);
Dean Lee72ed4dc2015-06-12 14:11:44 +09002037 is_wilc_go = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002038 }
2039
2040 #else /* USE_SUPPLICANT_GO_INTENT */
2041 #ifdef FORCE_P2P_CLIENT
2042 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
2043 #else
2044 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
2045 #endif
2046 #endif /* USE_SUPPLICANT_GO_INTENT */
2047 }
2048
2049 #ifdef USE_SUPPLICANT_GO_INTENT
2050 /*Case 2: If group bssid attribute is present, no need to modify channels attributes*/
2051 /*In invitation req and rsp, group bssid attr presence determines who will be GO*/
2052 if (buf[index] == GROUP_BSSID_ATTR_ID) {
2053 PRINT_D(GENERIC_DBG, "Group BSSID: %2x:%2x:%2x\n", buf[index + 3]
2054 , buf[index + 4]
2055 , buf[index + 5]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09002056 is_wilc_go = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002057 }
2058 #endif /* USE_SUPPLICANT_GO_INTENT */
2059
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302060 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002061 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302062 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002063 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002064 index += buf[index + 1] + 3; /* ID,Length byte */
2065 }
2066
2067 #ifdef USE_SUPPLICANT_GO_INTENT
2068 if (u8WLANChannel != INVALID_CHANNEL && is_wilc_go)
2069 #else
2070 if (u8WLANChannel != INVALID_CHANNEL)
2071 #endif
2072 {
2073 /*Modify channel list attribute*/
2074 if (channel_list_attr_index) {
2075 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
2076 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
2077 if (buf[i] == 0x51) {
2078 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
2079 buf[j] = u8WLANChannel;
2080 }
2081 break;
2082 }
2083 }
2084 }
2085 /*Modify operating channel attribute*/
2086 if (op_channel_attr_index) {
2087 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
2088 buf[op_channel_attr_index + 6] = 0x51;
2089 buf[op_channel_attr_index + 7] = u8WLANChannel;
2090 }
2091 }
2092}
2093
2094/**
2095 * @brief WILC_WFI_CfgParseTxAction
2096 * @details Function parses the transmitted action frames and modifies the
2097 * GO Intent attribute
2098 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
2099 * @return NONE.
2100 * @author mdaftedar
2101 * @date 12 DEC 2012
2102 * @version
2103 */
Dean Lee72ed4dc2015-06-12 14:11:44 +09002104void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002105{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002106 u32 index = 0;
2107 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002109 u8 op_channel_attr_index = 0;
2110 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002111 #ifdef USE_SUPPLICANT_GO_INTENT
Dean Lee72ed4dc2015-06-12 14:11:44 +09002112 bool is_wilc_go = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002113
2114 /*BugID_5460*/
2115 /*Case 1: If we are already p2p client, no need to modify channels attributes*/
2116 /*This to handle the case of inviting a p2p peer to join an existing group which we are a member in*/
2117 if (iftype == CLIENT_MODE)
2118 return;
2119 #endif
2120
2121 while (index < len) {
2122 #ifdef USE_SUPPLICANT_GO_INTENT
2123 /*Case 2: If group bssid attribute is present, no need to modify channels attributes*/
2124 /*In invitation req and rsp, group bssid attr presence determines who will be GO*/
2125 /*Note: If we are already p2p client, group bssid attr may also be present (handled in Case 1)*/
2126 if (buf[index] == GROUP_BSSID_ATTR_ID) {
2127 PRINT_D(GENERIC_DBG, "Group BSSID: %2x:%2x:%2x\n", buf[index + 3]
2128 , buf[index + 4]
2129 , buf[index + 5]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09002130 is_wilc_go = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002131 }
2132
2133 #else /* USE_SUPPLICANT_GO_INTENT */
2134 if (buf[index] == GO_INTENT_ATTR_ID) {
2135 #ifdef FORCE_P2P_CLIENT
2136 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
2137 #else
2138 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
2139 #endif
2140
2141 break;
2142 }
2143 #endif
2144
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302145 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002146 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302147 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002148 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002149 index += buf[index + 1] + 3; /* ID,Length byte */
2150 }
2151
2152 #ifdef USE_SUPPLICANT_GO_INTENT
2153 /*No need to check bOperChan since only transmitted invitation frames are parsed*/
2154 if (u8WLANChannel != INVALID_CHANNEL && is_wilc_go)
2155 #else
2156 if (u8WLANChannel != INVALID_CHANNEL && bOperChan)
2157 #endif
2158 {
2159 /*Modify channel list attribute*/
2160 if (channel_list_attr_index) {
2161 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
2162 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
2163 if (buf[i] == 0x51) {
2164 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
2165 buf[j] = u8WLANChannel;
2166 }
2167 break;
2168 }
2169 }
2170 }
2171 /*Modify operating channel attribute*/
2172 if (op_channel_attr_index) {
2173 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
2174 buf[op_channel_attr_index + 6] = 0x51;
2175 buf[op_channel_attr_index + 7] = u8WLANChannel;
2176 }
2177 }
2178}
2179
2180/* @brief WILC_WFI_p2p_rx
2181 * @details
2182 * @param[in]
2183 *
2184 * @return None
2185 * @author Mai Daftedar
2186 * @date 2 JUN 2013
2187 * @version 1.0
2188 */
2189
2190void WILC_WFI_p2p_rx (struct net_device *dev, uint8_t *buff, uint32_t size)
2191{
2192
2193 struct WILC_WFI_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002194 u32 header, pkt_offset;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002195 tstrWILC_WFIDrv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002196 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002197 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002198 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
2199 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2200
2201 /* Get WILC header */
2202 WILC_memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
2203
2204 /* The packet offset field conain info about what type of managment frame */
2205 /* we are dealing with and ack status */
2206 pkt_offset = GET_PKT_OFFSET(header);
2207
2208 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
2209 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
2210 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002211 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002212 return;
2213 } else {
2214 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
2215 PRINT_D(GENERIC_DBG, "Success Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID],
2216 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002217 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002218 } else {
2219 PRINT_D(GENERIC_DBG, "Fail Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID],
2220 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002221 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002222 }
2223 return;
2224 }
2225 } else {
2226
2227 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
2228
2229 /*BugID_5442*/
2230 /*Upper layer is informed that the frame is received on this freq*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002231 s32Freq = ieee80211_channel_to_frequency(u8CurrChannel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002232
2233 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
2234 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
2235
Dean Lee72ed4dc2015-06-12 14:11:44 +09002236 if (priv->bCfgScanning == true && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->u64P2p_MgmtTimeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002237 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
2238 return;
2239 }
2240 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2241
2242 switch (buff[ACTION_SUBTYPE_ID]) {
2243 case GAS_INTIAL_REQ:
2244 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
2245 break;
2246
2247 case GAS_INTIAL_RSP:
2248 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
2249 break;
2250
2251 case PUBLIC_ACT_VENDORSPEC:
2252 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2253 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002254 if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002255 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2256 if (!bWilc_ie) {
2257 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002258 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002259 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09002260 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002261 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
2262 break;
2263 }
2264 }
2265 }
2266 }
2267 if (u8P2Plocalrandom > u8P2Precvrandom) {
2268 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2269 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2270 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002271 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002272 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2273 break;
2274 }
2275 }
2276 }
2277 } else
2278 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2279 }
2280
2281
2282 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2283 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2284 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002285 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002286 return;
2287 }
2288 break;
2289
2290 default:
2291 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2292 break;
2293 }
2294 }
2295 }
2296
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002297 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002298 }
2299}
2300
2301/**
2302 * @brief WILC_WFI_mgmt_tx_complete
2303 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2304 * @param[in] priv
2305 * transmitting status
2306 * @return None
2307 * @author Amr Abdelmoghny
2308 * @date 20 MAY 2013
2309 * @version 1.0
2310 */
2311static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2312{
2313 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2314
2315
2316 kfree(pv_data->buff);
2317 kfree(pv_data);
2318}
2319
2320/**
2321 * @brief WILC_WFI_RemainOnChannelReady
2322 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2323 * @param
2324 * @return none
2325 * @author Amr abdelmoghny
2326 * @date 9 JUNE 2013
2327 * @version
2328 */
2329
2330static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2331{
2332 struct WILC_WFI_priv *priv;
2333 priv = (struct WILC_WFI_priv *)pUserVoid;
2334
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302335 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002336
Dean Lee72ed4dc2015-06-12 14:11:44 +09002337 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002338
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002339 cfg80211_ready_on_channel(priv->wdev,
2340 priv->strRemainOnChanParams.u64ListenCookie,
2341 priv->strRemainOnChanParams.pstrListenChan,
2342 priv->strRemainOnChanParams.u32ListenDuration,
2343 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002344}
2345
2346/**
2347 * @brief WILC_WFI_RemainOnChannelExpired
2348 * @details Callback function, called on expiration of remain-on-channel duration
2349 * @param
2350 * @return none
2351 * @author Amr abdelmoghny
2352 * @date 15 MAY 2013
2353 * @version
2354 */
2355
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002356static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002357{
2358 struct WILC_WFI_priv *priv;
2359 priv = (struct WILC_WFI_priv *)pUserVoid;
2360
2361 /*BugID_5477*/
2362 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302363 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002364
Dean Lee72ed4dc2015-06-12 14:11:44 +09002365 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002366
2367 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002368 cfg80211_remain_on_channel_expired(priv->wdev,
2369 priv->strRemainOnChanParams.u64ListenCookie,
2370 priv->strRemainOnChanParams.pstrListenChan,
2371 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002372 } else {
2373 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2374 , priv->strRemainOnChanParams.u32ListenSessionID);
2375 }
2376}
2377
2378
2379/**
2380 * @brief WILC_WFI_remain_on_channel
2381 * @details Request the driver to remain awake on the specified
2382 * channel for the specified duration to complete an off-channel
2383 * operation (e.g., public action frame exchange). When the driver is
2384 * ready on the requested channel, it must indicate this with an event
2385 * notification by calling cfg80211_ready_on_channel().
2386 * @param[in]
2387 * @return int : Return 0 on Success
2388 * @author mdaftedar
2389 * @date 01 MAR 2012
2390 * @version 1.0
2391 */
2392static int WILC_WFI_remain_on_channel(struct wiphy *wiphy,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393 struct wireless_dev *wdev,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002394 struct ieee80211_channel *chan,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002395 unsigned int duration, u64 *cookie)
2396{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002397 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002398 struct WILC_WFI_priv *priv;
2399 priv = wiphy_priv(wiphy);
2400
2401 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2402
2403 /*BugID_4800: if in AP mode, return.*/
2404 /*This check is to handle the situation when user*/
2405 /*requests "create group" during a running scan*/
2406
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002407 if (wdev->iftype == NL80211_IFTYPE_AP) {
2408 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2409 return s32Error;
2410 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002411
2412 u8CurrChannel = chan->hw_value;
2413
2414 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2415 priv->strRemainOnChanParams.pstrListenChan = chan;
2416 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002417 priv->strRemainOnChanParams.u32ListenDuration = duration;
2418 priv->strRemainOnChanParams.u32ListenSessionID++;
2419
2420 s32Error = host_int_remain_on_channel(priv->hWILCWFIDrv
2421 , priv->strRemainOnChanParams.u32ListenSessionID
2422 , duration
2423 , chan->hw_value
2424 , WILC_WFI_RemainOnChannelExpired
2425 , WILC_WFI_RemainOnChannelReady
2426 , (void *)priv);
2427
2428 return s32Error;
2429}
2430
2431/**
2432 * @brief WILC_WFI_cancel_remain_on_channel
2433 * @details Cancel an on-going remain-on-channel operation.
2434 * This allows the operation to be terminated prior to timeout based on
2435 * the duration value.
2436 * @param[in] struct wiphy *wiphy,
2437 * @param[in] struct net_device *dev
2438 * @param[in] u64 cookie,
2439 * @return int : Return 0 on Success
2440 * @author mdaftedar
2441 * @date 01 MAR 2012
2442 * @version 1.0
2443 */
2444static int WILC_WFI_cancel_remain_on_channel(struct wiphy *wiphy,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002445 struct wireless_dev *wdev,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002446 u64 cookie)
2447{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002448 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002449 struct WILC_WFI_priv *priv;
2450 priv = wiphy_priv(wiphy);
2451
2452 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2453
2454 s32Error = host_int_ListenStateExpired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
2455 return s32Error;
2456}
2457/**
2458 * @brief WILC_WFI_add_wilcvendorspec
2459 * @details Adding WILC information elemet to allow two WILC devices to
2460 * identify each other and connect
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002461 * @param[in] u8 * buf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002462 * @return void
2463 * @author mdaftedar
2464 * @date 01 JAN 2014
2465 * @version 1.0
2466 */
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002467void WILC_WFI_add_wilcvendorspec(u8 *buff)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002468{
2469 WILC_memcpy(buff, u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
2470}
2471/**
2472 * @brief WILC_WFI_mgmt_tx_frame
2473 * @details
2474 *
2475 * @param[in]
2476 * @return NONE.
2477 * @author mdaftedar
2478 * @date 01 JUL 2012
2479 * @version
2480 */
2481extern linux_wlan_t *g_linux_wlan;
Dean Lee72ed4dc2015-06-12 14:11:44 +09002482extern bool bEnablePS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002483int WILC_WFI_mgmt_tx(struct wiphy *wiphy,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002484 struct wireless_dev *wdev,
2485 struct cfg80211_mgmt_tx_params *params,
2486 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002487{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002488 struct ieee80211_channel *chan = params->chan;
2489 unsigned int wait = params->wait;
2490 const u8 *buf = params->buf;
2491 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002492 const struct ieee80211_mgmt *mgmt;
2493 struct p2p_mgmt_data *mgmt_tx;
2494 struct WILC_WFI_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002495 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002496 tstrWILC_WFIDrv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002497 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002498 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002499 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002500
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002501 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002502 priv = wiphy_priv(wiphy);
2503 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2504
2505 *cookie = (unsigned long)buf;
2506 priv->u64tx_cookie = *cookie;
2507 mgmt = (const struct ieee80211_mgmt *) buf;
2508
2509 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2510
2511 /*mgmt frame allocation*/
2512 mgmt_tx = (struct p2p_mgmt_data *)WILC_MALLOC(sizeof(struct p2p_mgmt_data));
2513 if (mgmt_tx == NULL) {
2514 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
2515 return WILC_FAIL;
2516 }
2517 mgmt_tx->buff = (char *)WILC_MALLOC(buf_len);
2518 if (mgmt_tx->buff == NULL) {
2519 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
2520 return WILC_FAIL;
2521 }
2522 WILC_memcpy(mgmt_tx->buff, buf, len);
2523 mgmt_tx->size = len;
2524
2525
2526 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2527 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2528 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
2529 host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
2530 /*Save the current channel after we tune to it*/
2531 u8CurrChannel = chan->hw_value;
2532 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002533 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002534
2535
2536 /*BugID_4847*/
2537 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2538 /*BugID_4847*/
2539 /*Only set the channel, if not a negotiation confirmation frame
2540 * (If Negotiation confirmation frame, force it
2541 * to be transmitted on the same negotiation channel)*/
2542
2543 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2544 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2545 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
2546 host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
2547 /*Save the current channel after we tune to it*/
2548 u8CurrChannel = chan->hw_value;
2549 }
2550 switch (buf[ACTION_SUBTYPE_ID]) {
2551 case GAS_INTIAL_REQ:
2552 {
2553 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2554 break;
2555 }
2556
2557 case GAS_INTIAL_RSP:
2558 {
2559 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2560 break;
2561 }
2562
2563 case PUBLIC_ACT_VENDORSPEC:
2564 {
2565 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2566 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002567 if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002568 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2569 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2570 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2571 get_random_bytes(&u8P2Plocalrandom, 1);
2572 /*Increment the number to prevent if its 0*/
2573 u8P2Plocalrandom++;
2574 }
2575 }
2576
2577 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2578 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2579 if (u8P2Plocalrandom > u8P2Precvrandom) {
2580 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2581
2582 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2583 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002584 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002585 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002586 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002587
2588 /*BugID_5460*/
2589 /*If using supplicant go intent, no need at all*/
2590 /*to parse transmitted negotiation frames*/
2591 #ifndef USE_SUPPLICANT_GO_INTENT
2592 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002593 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594 #endif
2595 break;
2596 }
2597 }
2598
2599 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
2600 WILC_WFI_add_wilcvendorspec(&mgmt_tx->buff[len]);
2601 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2602 mgmt_tx->size = buf_len;
2603 }
2604 } else
2605 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2606 }
2607
2608 } else {
2609 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2610 }
2611
2612 break;
2613 }
2614
2615 default:
2616 {
2617 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2618 break;
2619 }
2620 }
2621
2622 }
2623
2624 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
2625 pstrWFIDrv->u64P2p_MgmtTimeout = (jiffies + msecs_to_jiffies(wait));
2626
2627 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", jiffies, pstrWFIDrv->u64P2p_MgmtTimeout);
2628
2629 }
2630
2631 g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, WILC_WFI_mgmt_tx_complete);
2632 } else {
2633 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2634 }
2635 return s32Error;
2636}
2637
2638int WILC_WFI_mgmt_tx_cancel_wait(struct wiphy *wiphy,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002639 struct wireless_dev *wdev,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002640 u64 cookie)
2641{
2642 struct WILC_WFI_priv *priv;
2643 tstrWILC_WFIDrv *pstrWFIDrv;
2644 priv = wiphy_priv(wiphy);
2645 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2646
2647
2648 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
2649 pstrWFIDrv->u64P2p_MgmtTimeout = jiffies;
2650
Dean Lee72ed4dc2015-06-12 14:11:44 +09002651 if (priv->bInP2PlistenState == false) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002652 /* Bug 5504: This is just to avoid connection failure when getting stuck when the supplicant
2653 * considers the driver falsely that it is in Listen state */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002654 cfg80211_remain_on_channel_expired(priv->wdev,
2655 priv->strRemainOnChanParams.u64ListenCookie,
2656 priv->strRemainOnChanParams.pstrListenChan,
2657 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002658 }
2659
2660 return 0;
2661}
2662
2663/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002664 * @brief WILC_WFI_frame_register
2665 * @details Notify driver that a management frame type was
2666 * registered. Note that this callback may not sleep, and cannot run
2667 * concurrently with itself.
2668 * @param[in]
2669 * @return NONE.
2670 * @author mdaftedar
2671 * @date 01 JUL 2012
2672 * @version
2673 */
2674void WILC_WFI_frame_register(struct wiphy *wiphy,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002675 struct wireless_dev *wdev,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002676 u16 frame_type, bool reg)
2677{
2678
2679 struct WILC_WFI_priv *priv;
2680 perInterface_wlan_t *nic;
2681
2682
2683 priv = wiphy_priv(wiphy);
2684 nic = netdev_priv(priv->wdev->netdev);
2685
2686
2687
2688 /*BugID_5137*/
2689 if (!frame_type)
2690 return;
2691
2692 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2693 switch (frame_type) {
2694 case PROBE_REQ:
2695 {
2696 nic->g_struct_frame_reg[0].frame_type = frame_type;
2697 nic->g_struct_frame_reg[0].reg = reg;
2698 }
2699 break;
2700
2701 case ACTION:
2702 {
2703 nic->g_struct_frame_reg[1].frame_type = frame_type;
2704 nic->g_struct_frame_reg[1].reg = reg;
2705 }
2706 break;
2707
2708 default:
2709 {
2710 break;
2711 }
2712
2713 }
2714 /*If mac is closed, then return*/
2715 if (!g_linux_wlan->wilc1000_initialized) {
2716 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2717 return;
2718 }
2719 host_int_frame_register(priv->hWILCWFIDrv, frame_type, reg);
2720
2721
2722}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002723#endif /*WILC_P2P*/
2724
2725/**
2726 * @brief WILC_WFI_set_cqm_rssi_config
2727 * @details Configure connection quality monitor RSSI threshold.
2728 * @param[in] struct wiphy *wiphy:
2729 * @param[in] struct net_device *dev:
2730 * @param[in] s32 rssi_thold:
2731 * @param[in] u32 rssi_hyst:
2732 * @return int : Return 0 on Success
2733 * @author mdaftedar
2734 * @date 01 MAR 2012
2735 * @version 1.0
2736 */
2737static int WILC_WFI_set_cqm_rssi_config(struct wiphy *wiphy,
2738 struct net_device *dev, s32 rssi_thold, u32 rssi_hyst)
2739{
2740 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2741 return 0;
2742
2743}
2744/**
2745 * @brief WILC_WFI_dump_station
2746 * @details Configure connection quality monitor RSSI threshold.
2747 * @param[in] struct wiphy *wiphy:
2748 * @param[in] struct net_device *dev
2749 * @param[in] int idx
2750 * @param[in] u8 *mac
2751 * @param[in] struct station_info *sinfo
2752 * @return int : Return 0 on Success
2753 * @author mdaftedar
2754 * @date 01 MAR 2012
2755 * @version 1.0
2756 */
2757static int WILC_WFI_dump_station(struct wiphy *wiphy, struct net_device *dev,
2758 int idx, u8 *mac, struct station_info *sinfo)
2759{
2760 struct WILC_WFI_priv *priv;
2761 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2762
2763 if (idx != 0)
2764 return -ENOENT;
2765
2766 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002767
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002768 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002769
2770 host_int_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
2771
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002772 return 0;
2773
2774}
2775
2776
2777/**
2778 * @brief WILC_WFI_set_power_mgmt
2779 * @details
2780 * @param[in]
2781 * @return int : Return 0 on Success.
2782 * @author mdaftedar
2783 * @date 01 JUL 2012
2784 * @version 1.0WILC_WFI_set_cqmWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_config_rssi_config
2785 */
2786int WILC_WFI_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2787 bool enabled, int timeout)
2788{
2789 struct WILC_WFI_priv *priv;
2790 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2791
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002792 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002793 return -ENOENT;
2794
2795 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002796 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002797 PRINT_ER("Driver is NULL\n");
2798 return -EIO;
2799 }
2800
Abdul Hussain5a66bf22015-06-16 09:44:06 +00002801 if (bEnablePS)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002802 host_int_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
2803
2804
2805 return WILC_SUCCESS;
2806
2807}
2808#ifdef WILC_AP_EXTERNAL_MLME
2809/**
2810 * @brief WILC_WFI_change_virt_intf
2811 * @details Change type/configuration of virtual interface,
2812 * keep the struct wireless_dev's iftype updated.
2813 * @param[in] NONE
2814 * @return int : Return 0 on Success.
2815 * @author mdaftedar
2816 * @date 01 MAR 2012
2817 * @version 1.0
2818 */
2819void wilc1000_wlan_deinit(linux_wlan_t *nic);
2820int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic);
2821
2822static int WILC_WFI_change_virt_intf(struct wiphy *wiphy, struct net_device *dev,
2823 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
2824{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002825 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002826 struct WILC_WFI_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002827 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002828 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002829 u16 TID = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002830 #ifdef WILC_P2P
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002831 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002832 #endif
2833
2834 nic = netdev_priv(dev);
2835 priv = wiphy_priv(wiphy);
2836
2837 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2838 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2839 u8P2Plocalrandom = 0x01;
2840 u8P2Precvrandom = 0x00;
2841
Dean Lee72ed4dc2015-06-12 14:11:44 +09002842 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002843
2844 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Dean Lee72ed4dc2015-06-12 14:11:44 +09002845 g_obtainingIP = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002846 WILC_TimerStop(&hDuringIpTimer, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002847 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
2848 #endif
2849 /*BugID_5137*/
2850 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2851 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09002852 Set_machw_change_vir_if(true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002853 }
2854
2855 switch (type) {
2856 case NL80211_IFTYPE_STATION:
2857 connecting = 0;
2858 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002859
2860 /* send delba over wlan interface */
2861
2862
2863 dev->ieee80211_ptr->iftype = type;
2864 priv->wdev->iftype = type;
2865 nic->monitor_flag = 0;
2866 nic->iftype = STATION_MODE;
2867
2868 /*Remove the enteries of the previously connected clients*/
2869 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002870 #ifdef WILC_P2P
2871 interface_type = nic->iftype;
2872 nic->iftype = STATION_MODE;
2873
2874 if (g_linux_wlan->wilc1000_initialized) {
2875 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
2876 /* ensure that the message Q is empty */
2877 host_int_wait_msg_queue_idle();
2878
2879 /*BugID_5213*/
2880 /*Eliminate host interface blocking state*/
2881 linux_wlan_unlock((void *)&g_linux_wlan->cfg_event);
2882
2883 wilc1000_wlan_deinit(g_linux_wlan);
2884 wilc1000_wlan_init(dev, nic);
2885 g_wilc_initialized = 1;
2886 nic->iftype = interface_type;
2887
2888 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
2889 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
2890 host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
2891 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
2892 host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
2893
2894 /*Add saved WEP keys, if any*/
2895 if (g_wep_keys_saved) {
2896 host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
2897 g_key_wep_params.key_idx);
2898 host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
2899 g_key_wep_params.key,
2900 g_key_wep_params.key_len,
2901 g_key_wep_params.key_idx);
2902 }
2903
2904 /*No matter the driver handler passed here, it will be overwriiten*/
2905 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2906 host_int_flush_join_req(priv->hWILCWFIDrv);
2907
2908 /*Add saved PTK and GTK keys, if any*/
2909 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2910 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2911 g_key_ptk_params.key[1],
2912 g_key_ptk_params.key[2]);
2913 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2914 g_key_gtk_params.key[1],
2915 g_key_gtk_params.key[2]);
2916 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
2917 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
2918 g_add_ptk_key_params.key_idx,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002919 g_add_ptk_key_params.pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002920 g_add_ptk_key_params.mac_addr,
2921 (struct key_params *)(&g_key_ptk_params));
2922
2923 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
2924 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
2925 g_add_gtk_key_params.key_idx,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002926 g_add_gtk_key_params.pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002927 g_add_gtk_key_params.mac_addr,
2928 (struct key_params *)(&g_key_gtk_params));
2929 }
2930
2931 /*BugID_4847: registered frames in firmware are now*/
2932 /*lost due to mac close. So re-register those frames*/
2933 if (g_linux_wlan->wilc1000_initialized) {
2934 for (i = 0; i < num_reg_frame; i++) {
2935 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2936 nic->g_struct_frame_reg[i].reg);
2937 host_int_frame_register(priv->hWILCWFIDrv,
2938 nic->g_struct_frame_reg[i].frame_type,
2939 nic->g_struct_frame_reg[i].reg);
2940 }
2941 }
2942
Dean Lee72ed4dc2015-06-12 14:11:44 +09002943 bEnablePS = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002944 host_int_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
2945 }
2946 #endif
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002947 break;
2948
2949 case NL80211_IFTYPE_P2P_CLIENT:
Dean Lee72ed4dc2015-06-12 14:11:44 +09002950 bEnablePS = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002951 host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2952 connecting = 0;
2953 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002954
2955 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
2956
2957 dev->ieee80211_ptr->iftype = type;
2958 priv->wdev->iftype = type;
2959 nic->monitor_flag = 0;
2960
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002961 #ifdef WILC_P2P
2962
2963 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2964 nic->iftype = CLIENT_MODE;
2965
2966
2967 if (g_linux_wlan->wilc1000_initialized) {
2968 /* ensure that the message Q is empty */
2969 host_int_wait_msg_queue_idle();
2970
2971 wilc1000_wlan_deinit(g_linux_wlan);
2972 wilc1000_wlan_init(dev, nic);
2973 g_wilc_initialized = 1;
2974
2975 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
2976 host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
2977 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
2978 host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
2979
2980 /*Add saved WEP keys, if any*/
2981 if (g_wep_keys_saved) {
2982 host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
2983 g_key_wep_params.key_idx);
2984 host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
2985 g_key_wep_params.key,
2986 g_key_wep_params.key_len,
2987 g_key_wep_params.key_idx);
2988 }
2989
2990 /*No matter the driver handler passed here, it will be overwriiten*/
2991 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2992 host_int_flush_join_req(priv->hWILCWFIDrv);
2993
2994 /*Add saved PTK and GTK keys, if any*/
2995 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2996 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2997 g_key_ptk_params.key[1],
2998 g_key_ptk_params.key[2]);
2999 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
3000 g_key_gtk_params.key[1],
3001 g_key_gtk_params.key[2]);
3002 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3003 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3004 g_add_ptk_key_params.key_idx,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003005 g_add_ptk_key_params.pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003006 g_add_ptk_key_params.mac_addr,
3007 (struct key_params *)(&g_key_ptk_params));
3008
3009 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3010 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3011 g_add_gtk_key_params.key_idx,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003012 g_add_gtk_key_params.pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003013 g_add_gtk_key_params.mac_addr,
3014 (struct key_params *)(&g_key_gtk_params));
3015 }
3016
3017 /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/
Dean Lee72ed4dc2015-06-12 14:11:44 +09003018 refresh_scan(priv, 1, true);
3019 Set_machw_change_vir_if(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003020
3021 /*BugID_4847: registered frames in firmware are now lost
3022 * due to mac close. So re-register those frames */
3023 if (g_linux_wlan->wilc1000_initialized) {
3024 for (i = 0; i < num_reg_frame; i++) {
3025 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3026 nic->g_struct_frame_reg[i].reg);
3027 host_int_frame_register(priv->hWILCWFIDrv,
3028 nic->g_struct_frame_reg[i].frame_type,
3029 nic->g_struct_frame_reg[i].reg);
3030 }
3031 }
3032 }
3033 #endif
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003034 break;
3035
3036 case NL80211_IFTYPE_AP:
Dean Lee72ed4dc2015-06-12 14:11:44 +09003037 bEnablePS = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003038 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003039 dev->ieee80211_ptr->iftype = type;
3040 priv->wdev->iftype = type;
3041 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09003042 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003043
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003044 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
3045 linux_wlan_get_firmware(nic);
3046 #ifdef WILC_P2P
3047 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
3048 if (g_linux_wlan->wilc1000_initialized) {
3049 nic->iftype = AP_MODE;
3050 g_linux_wlan->wilc1000_initialized = 1;
3051 mac_close(dev);
3052 mac_open(dev);
3053
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003054 /*BugID_4847: registered frames in firmware are now lost
3055 * due to mac close. So re-register those frames */
3056 for (i = 0; i < num_reg_frame; i++) {
3057 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3058 nic->g_struct_frame_reg[i].reg);
3059 host_int_frame_register(priv->hWILCWFIDrv,
3060 nic->g_struct_frame_reg[i].frame_type,
3061 nic->g_struct_frame_reg[i].reg);
3062 }
3063 }
3064 #endif
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003065 break;
3066
3067 case NL80211_IFTYPE_P2P_GO:
3068 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
3069
3070 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Dean Lee72ed4dc2015-06-12 14:11:44 +09003071 g_obtainingIP = true;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003072 WILC_TimerStart(&hDuringIpTimer, duringIP_TIME, NULL, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003073 #endif
3074 host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
3075 /*BugID_5222*/
3076 /*Delete block ack has to be the latest config packet*/
3077 /*sent before downloading new FW. This is because it blocks on*/
3078 /*hWaitResponse semaphore, which allows previous config*/
3079 /*packets to actually take action on old FW*/
3080 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
Dean Lee72ed4dc2015-06-12 14:11:44 +09003081 bEnablePS = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003082 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003083 dev->ieee80211_ptr->iftype = type;
3084 priv->wdev->iftype = type;
3085
Johnny Kim8a143302015-06-10 17:06:46 +09003086 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003087
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003088 #ifdef WILC_P2P
3089 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
3090
3091
3092 #if 1
3093 nic->iftype = GO_MODE;
3094
3095 /* ensure that the message Q is empty */
3096 host_int_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003097 wilc1000_wlan_deinit(g_linux_wlan);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003098 wilc1000_wlan_init(dev, nic);
3099 g_wilc_initialized = 1;
3100
3101
3102 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
3103 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
3104 host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3105 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3106 host_int_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
3107
3108 /*Add saved WEP keys, if any*/
3109 if (g_wep_keys_saved) {
3110 host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3111 g_key_wep_params.key_idx);
3112 host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
3113 g_key_wep_params.key,
3114 g_key_wep_params.key_len,
3115 g_key_wep_params.key_idx);
3116 }
3117
3118 /*No matter the driver handler passed here, it will be overwriiten*/
3119 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
3120 host_int_flush_join_req(priv->hWILCWFIDrv);
3121
3122 /*Add saved PTK and GTK keys, if any*/
3123 if (g_ptk_keys_saved && g_gtk_keys_saved) {
3124 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
3125 g_key_ptk_params.key[1],
3126 g_key_ptk_params.key[2],
3127 g_key_ptk_params.cipher);
3128 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
3129 g_key_gtk_params.key[1],
3130 g_key_gtk_params.key[2],
3131 g_key_gtk_params.cipher);
3132 #if 1
3133 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3134 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3135 g_add_ptk_key_params.key_idx,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003136 g_add_ptk_key_params.pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003137 g_add_ptk_key_params.mac_addr,
3138 (struct key_params *)(&g_key_ptk_params));
3139
3140 WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3141 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3142 g_add_gtk_key_params.key_idx,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003143 g_add_gtk_key_params.pairwise,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003144 g_add_gtk_key_params.mac_addr,
3145 (struct key_params *)(&g_key_gtk_params));
3146 #endif
3147 }
3148 #endif
3149
3150 /*BugID_4847: registered frames in firmware are now*/
3151 /*lost due to mac close. So re-register those frames*/
3152 if (g_linux_wlan->wilc1000_initialized) {
3153 for (i = 0; i < num_reg_frame; i++) {
3154 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3155 nic->g_struct_frame_reg[i].reg);
3156 host_int_frame_register(priv->hWILCWFIDrv,
3157 nic->g_struct_frame_reg[i].frame_type,
3158 nic->g_struct_frame_reg[i].reg);
3159 }
3160 }
3161 #endif
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003162 break;
3163
3164 default:
3165 PRINT_ER("Unknown interface type= %d\n", type);
3166 s32Error = -EINVAL;
3167 return s32Error;
3168 break;
3169 }
3170
3171 return s32Error;
3172}
3173
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003174/* (austin.2013-07-23)
3175 *
3176 * To support revised cfg80211_ops
3177 *
3178 * add_beacon --> start_ap
3179 * set_beacon --> change_beacon
3180 * del_beacon --> stop_ap
3181 *
3182 * beacon_parameters --> cfg80211_ap_settings
3183 * cfg80211_beacon_data
3184 *
3185 * applicable for linux kernel 3.4+
3186 */
3187
3188/**
3189 * @brief WILC_WFI_start_ap
3190 * @details Add a beacon with given parameters, @head, @interval
3191 * and @dtim_period will be valid, @tail is optional.
3192 * @param[in] wiphy
3193 * @param[in] dev The net device structure
3194 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
3195 * @return int : Return 0 on Success.
3196 * @author austin
3197 * @date 23 JUL 2013
3198 * @version 1.0
3199 */
3200static int WILC_WFI_start_ap(struct wiphy *wiphy, struct net_device *dev,
3201 struct cfg80211_ap_settings *settings)
3202{
3203 struct cfg80211_beacon_data *beacon = &(settings->beacon);
3204 struct WILC_WFI_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003205 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003206
3207 priv = wiphy_priv(wiphy);
3208 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
3209
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303210 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003211 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
3212
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003213 s32Error = WILC_WFI_CfgSetChannel(wiphy, &settings->chandef);
3214
3215 if (s32Error != WILC_SUCCESS)
3216 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003217
3218 linux_wlan_set_bssid(dev, g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3219
3220 #ifndef WILC_FULLY_HOSTING_AP
3221 s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
3222 settings->beacon_interval,
3223 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003224 beacon->head_len, (u8 *)beacon->head,
3225 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003226 #else
3227 s32Error = host_add_beacon(priv->hWILCWFIDrv,
3228 settings->beacon_interval,
3229 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003230 beacon->head_len, (u8 *)beacon->head,
3231 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003232 #endif
3233
3234 return s32Error;
3235}
3236
3237/**
3238 * @brief WILC_WFI_change_beacon
3239 * @details Add a beacon with given parameters, @head, @interval
3240 * and @dtim_period will be valid, @tail is optional.
3241 * @param[in] wiphy
3242 * @param[in] dev The net device structure
3243 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
3244 * @return int : Return 0 on Success.
3245 * @author austin
3246 * @date 23 JUL 2013
3247 * @version 1.0
3248 */
3249static int WILC_WFI_change_beacon(struct wiphy *wiphy, struct net_device *dev,
3250 struct cfg80211_beacon_data *beacon)
3251{
3252 struct WILC_WFI_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003253 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003254
3255 priv = wiphy_priv(wiphy);
3256 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
3257
3258
3259#ifndef WILC_FULLY_HOSTING_AP
3260 s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
3261 0,
3262 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003263 beacon->head_len, (u8 *)beacon->head,
3264 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003265#else
3266 s32Error = host_add_beacon(priv->hWILCWFIDrv,
3267 0,
3268 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003269 beacon->head_len, (u8 *)beacon->head,
3270 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003271#endif
3272
3273 return s32Error;
3274}
3275
3276/**
3277 * @brief WILC_WFI_stop_ap
3278 * @details Remove beacon configuration and stop sending the beacon.
3279 * @param[in]
3280 * @return int : Return 0 on Success.
3281 * @author austin
3282 * @date 23 JUL 2013
3283 * @version 1.0
3284 */
3285static int WILC_WFI_stop_ap(struct wiphy *wiphy, struct net_device *dev)
3286{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003287 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003288 struct WILC_WFI_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003289 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003290
3291
3292 WILC_NULLCHECK(s32Error, wiphy);
3293
3294 priv = wiphy_priv(wiphy);
3295
3296 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
3297
3298 /*BugID_5188*/
3299 linux_wlan_set_bssid(dev, NullBssid);
3300
3301 #ifndef WILC_FULLY_HOSTING_AP
3302 s32Error = host_int_del_beacon(priv->hWILCWFIDrv);
3303 #else
3304 s32Error = host_del_beacon(priv->hWILCWFIDrv);
3305 #endif
3306
3307 WILC_ERRORCHECK(s32Error);
3308
3309 WILC_CATCH(s32Error)
3310 {
3311 }
3312 return s32Error;
3313}
3314
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003315/**
3316 * @brief WILC_WFI_add_station
3317 * @details Add a new station.
3318 * @param[in]
3319 * @return int : Return 0 on Success.
3320 * @author mdaftedar
3321 * @date 01 MAR 2012
3322 * @version 1.0
3323 */
3324static int WILC_WFI_add_station(struct wiphy *wiphy, struct net_device *dev,
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003325 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003326{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003327 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003328 struct WILC_WFI_priv *priv;
Chandra S Gorentlaa2b40412015-08-08 17:41:33 +05303329 tstrWILC_AddStaParam strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003330 perInterface_wlan_t *nic;
3331
3332
3333 WILC_NULLCHECK(s32Error, wiphy);
3334
3335 priv = wiphy_priv(wiphy);
3336 nic = netdev_priv(dev);
3337
3338 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3339 #ifndef WILC_FULLY_HOSTING_AP
3340
3341 WILC_memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
3342 WILC_memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
3343 strStaParams.u16AssocID = params->aid;
3344 strStaParams.u8NumRates = params->supported_rates_len;
3345 strStaParams.pu8Rates = params->supported_rates;
3346
3347 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3348
3349 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
3350 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
3351 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID);
3352 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates);
3353
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003354 if (params->ht_capa == NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09003355 strStaParams.bIsHTSupported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003356 } else {
Dean Lee72ed4dc2015-06-12 14:11:44 +09003357 strStaParams.bIsHTSupported = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003358 strStaParams.u16HTCapInfo = params->ht_capa->cap_info;
3359 strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info;
3360 WILC_memcpy(strStaParams.au8SuppMCsSet, &params->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE);
3361 strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info;
3362 strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info;
3363 strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info;
3364 }
3365
3366 strStaParams.u16FlagsMask = params->sta_flags_mask;
3367 strStaParams.u16FlagsSet = params->sta_flags_set;
3368
3369 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported);
3370 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo);
3371 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams);
3372 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams);
3373 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap);
3374 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap);
3375 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask);
3376 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet);
3377
3378 s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams);
3379 WILC_ERRORCHECK(s32Error);
3380
3381 #else
3382 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3383 WILC_memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
3384
3385 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
3386 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
3387
3388 WILC_AP_AddSta(mac, params);
3389 WILC_ERRORCHECK(s32Error);
3390 #endif /* WILC_FULLY_HOSTING_AP */
3391
3392 }
3393
3394 WILC_CATCH(s32Error)
3395 {
3396 }
3397 return s32Error;
3398}
3399
3400/**
3401 * @brief WILC_WFI_del_station
3402 * @details Remove a station; @mac may be NULL to remove all stations.
3403 * @param[in]
3404 * @return int : Return 0 on Success.
3405 * @author mdaftedar
3406 * @date 01 MAR 2012
3407 * @version 1.0
3408 */
3409static int WILC_WFI_del_station(struct wiphy *wiphy, struct net_device *dev,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003410 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003411{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003412 const u8 *mac = params->mac;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003413 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003414 struct WILC_WFI_priv *priv;
3415 perInterface_wlan_t *nic;
3416 WILC_NULLCHECK(s32Error, wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003417
3418 priv = wiphy_priv(wiphy);
3419 nic = netdev_priv(dev);
3420
3421 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3422 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3423
3424
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003425 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303426 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003427 s32Error = host_int_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
3428 } else {
3429 PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
3430 }
3431
3432 #ifndef WILC_FULLY_HOSTING_AP
3433 s32Error = host_int_del_station(priv->hWILCWFIDrv, mac);
3434 #else
3435 WILC_AP_RemoveSta(mac);
3436 #endif /* WILC_FULLY_HOSTING_AP */
3437
3438 WILC_ERRORCHECK(s32Error);
3439 }
3440 WILC_CATCH(s32Error)
3441 {
3442 }
3443 return s32Error;
3444}
3445
3446/**
3447 * @brief WILC_WFI_change_station
3448 * @details Modify a given station.
3449 * @param[in]
3450 * @return int : Return 0 on Success.
3451 * @author mdaftedar
3452 * @date 01 MAR 2012
3453 * @version 1.0
3454 */
3455static int WILC_WFI_change_station(struct wiphy *wiphy, struct net_device *dev,
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003456 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003457{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003458 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003459 struct WILC_WFI_priv *priv;
Chandra S Gorentlaa2b40412015-08-08 17:41:33 +05303460 tstrWILC_AddStaParam strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003461 perInterface_wlan_t *nic;
3462
3463
3464 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3465
3466 WILC_NULLCHECK(s32Error, wiphy);
3467
3468 priv = wiphy_priv(wiphy);
3469 nic = netdev_priv(dev);
3470
3471 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3472 #ifndef WILC_FULLY_HOSTING_AP
3473
3474 WILC_memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
3475 strStaParams.u16AssocID = params->aid;
3476 strStaParams.u8NumRates = params->supported_rates_len;
3477 strStaParams.pu8Rates = params->supported_rates;
3478
3479 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n", strStaParams.au8BSSID[0], strStaParams.au8BSSID[1], strStaParams.au8BSSID[2], strStaParams.au8BSSID[3], strStaParams.au8BSSID[4],
3480 strStaParams.au8BSSID[5]);
3481 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID);
3482 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates);
3483
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003484 if (params->ht_capa == NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09003485 strStaParams.bIsHTSupported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003486 } else {
Dean Lee72ed4dc2015-06-12 14:11:44 +09003487 strStaParams.bIsHTSupported = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003488 strStaParams.u16HTCapInfo = params->ht_capa->cap_info;
3489 strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info;
3490 WILC_memcpy(strStaParams.au8SuppMCsSet, &params->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE);
3491 strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info;
3492 strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info;
3493 strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info;
3494
3495 }
3496
3497 strStaParams.u16FlagsMask = params->sta_flags_mask;
3498 strStaParams.u16FlagsSet = params->sta_flags_set;
3499
3500 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported);
3501 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo);
3502 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams);
3503 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams);
3504 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap);
3505 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap);
3506 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask);
3507 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet);
3508
3509 s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams);
3510 WILC_ERRORCHECK(s32Error);
3511
3512 #else
3513 WILC_AP_EditSta(mac, params);
3514 WILC_ERRORCHECK(s32Error);
3515 #endif /* WILC_FULLY_HOSTING_AP */
3516
3517 }
3518 WILC_CATCH(s32Error)
3519 {
3520 }
3521 return s32Error;
3522}
3523
3524
3525/**
3526 * @brief WILC_WFI_add_virt_intf
3527 * @details
3528 * @param[in]
3529 * @return int : Return 0 on Success.
3530 * @author mdaftedar
3531 * @date 01 JUL 2012
3532 * @version 1.0
3533 */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003534struct wireless_dev *WILC_WFI_add_virt_intf(struct wiphy *wiphy, const char *name,
3535 unsigned char name_assign_type,
3536 enum nl80211_iftype type, u32 *flags,
3537 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003538{
3539 perInterface_wlan_t *nic;
3540 struct WILC_WFI_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003541 struct net_device *new_ifc = NULL;
3542 priv = wiphy_priv(wiphy);
3543
3544
3545
3546 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3547
3548 nic = netdev_priv(priv->wdev->netdev);
3549
3550
3551 if (type == NL80211_IFTYPE_MONITOR) {
3552 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3553 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3554 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3555 if (new_ifc != NULL) {
3556 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003557 nic = netdev_priv(priv->wdev->netdev);
3558 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003559 } else
3560 PRINT_ER("Error in initializing monitor interface\n ");
3561 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003562 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003563}
3564
3565/**
3566 * @brief WILC_WFI_del_virt_intf
3567 * @details
3568 * @param[in]
3569 * @return int : Return 0 on Success.
3570 * @author mdaftedar
3571 * @date 01 JUL 2012
3572 * @version 1.0
3573 */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003574int WILC_WFI_del_virt_intf(struct wiphy *wiphy, struct wireless_dev *wdev) /* tony for v3.8 support */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003575{
3576 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
3577 return WILC_SUCCESS;
3578}
3579
3580
3581
3582#endif /*WILC_AP_EXTERNAL_MLME*/
3583static struct cfg80211_ops WILC_WFI_cfg80211_ops = {
3584
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003585 .set_monitor_channel = WILC_WFI_CfgSetChannel,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003586 .scan = WILC_WFI_CfgScan,
3587 .connect = WILC_WFI_CfgConnect,
3588 .disconnect = WILC_WFI_disconnect,
3589 .add_key = WILC_WFI_add_key,
3590 .del_key = WILC_WFI_del_key,
3591 .get_key = WILC_WFI_get_key,
3592 .set_default_key = WILC_WFI_set_default_key,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003593 #ifdef WILC_AP_EXTERNAL_MLME
3594 .add_virtual_intf = WILC_WFI_add_virt_intf,
3595 .del_virtual_intf = WILC_WFI_del_virt_intf,
3596 .change_virtual_intf = WILC_WFI_change_virt_intf,
3597
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003598 .start_ap = WILC_WFI_start_ap,
3599 .change_beacon = WILC_WFI_change_beacon,
3600 .stop_ap = WILC_WFI_stop_ap,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003601 .add_station = WILC_WFI_add_station,
3602 .del_station = WILC_WFI_del_station,
3603 .change_station = WILC_WFI_change_station,
3604 #endif /* WILC_AP_EXTERNAL_MLME*/
3605 #ifndef WILC_FULLY_HOSTING_AP
3606 .get_station = WILC_WFI_get_station,
3607 #endif
3608 .dump_station = WILC_WFI_dump_station,
3609 .change_bss = WILC_WFI_change_bss,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003610 .set_wiphy_params = WILC_WFI_set_wiphy_params,
3611
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003612 .set_pmksa = WILC_WFI_set_pmksa,
3613 .del_pmksa = WILC_WFI_del_pmksa,
3614 .flush_pmksa = WILC_WFI_flush_pmksa,
3615#ifdef WILC_P2P
3616 .remain_on_channel = WILC_WFI_remain_on_channel,
3617 .cancel_remain_on_channel = WILC_WFI_cancel_remain_on_channel,
3618 .mgmt_tx_cancel_wait = WILC_WFI_mgmt_tx_cancel_wait,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003619 .mgmt_tx = WILC_WFI_mgmt_tx,
3620 .mgmt_frame_register = WILC_WFI_frame_register,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003621 .set_power_mgmt = WILC_WFI_set_power_mgmt,
3622 .set_cqm_rssi_config = WILC_WFI_set_cqm_rssi_config,
3623#endif
3624
3625};
3626
3627
3628
3629
3630
3631/**
3632 * @brief WILC_WFI_update_stats
3633 * @details Modify parameters for a given BSS.
3634 * @param[in]
3635 * @return int : Return 0 on Success.
3636 * @author mdaftedar
3637 * @date 01 MAR 2012
3638 * @version 1.0WILC_WFI_set_cqmWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_config_rssi_config
3639 */
3640int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3641{
3642
3643 struct WILC_WFI_priv *priv;
3644
3645 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003646#if 1
3647 switch (changed) {
3648
3649 case WILC_WFI_RX_PKT:
3650 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003651 priv->netstats.rx_packets++;
3652 priv->netstats.rx_bytes += pktlen;
3653 priv->netstats.rx_time = get_jiffies_64();
3654 }
3655 break;
3656
3657 case WILC_WFI_TX_PKT:
3658 {
3659 priv->netstats.tx_packets++;
3660 priv->netstats.tx_bytes += pktlen;
3661 priv->netstats.tx_time = get_jiffies_64();
3662
3663 }
3664 break;
3665
3666 default:
3667 break;
3668 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003669#endif
3670 return 0;
3671}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003672
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003673/**
3674 * @brief WILC_WFI_CfgAlloc
3675 * @details Allocation of the wireless device structure and assigning it
3676 * to the cfg80211 operations structure.
3677 * @param[in] NONE
3678 * @return wireless_dev : Returns pointer to wireless_dev structure.
3679 * @author mdaftedar
3680 * @date 01 MAR 2012
3681 * @version 1.0
3682 */
3683struct wireless_dev *WILC_WFI_CfgAlloc(void)
3684{
3685
3686 struct wireless_dev *wdev;
3687
3688
3689 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3690 /*Allocating the wireless device structure*/
3691 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3692 if (!wdev) {
3693 PRINT_ER("Cannot allocate wireless device\n");
3694 goto _fail_;
3695 }
3696
3697 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
3698 wdev->wiphy = wiphy_new(&WILC_WFI_cfg80211_ops, sizeof(struct WILC_WFI_priv));
3699 if (!wdev->wiphy) {
3700 PRINT_ER("Cannot allocate wiphy\n");
3701 goto _fail_mem_;
3702
3703 }
3704
3705 #ifdef WILC_AP_EXTERNAL_MLME
3706 /* enable 802.11n HT */
3707 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3708 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3709 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3710 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3711 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
3712 #endif
3713
3714 /*wiphy bands*/
3715 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3716
3717 return wdev;
3718
3719_fail_mem_:
3720 kfree(wdev);
3721_fail_:
3722 return NULL;
3723
3724}
3725/**
3726 * @brief WILC_WFI_WiphyRegister
3727 * @details Registering of the wiphy structure and interface modes
3728 * @param[in] NONE
3729 * @return NONE
3730 * @author mdaftedar
3731 * @date 01 MAR 2012
3732 * @version 1.0
3733 */
3734struct wireless_dev *WILC_WFI_WiphyRegister(struct net_device *net)
3735{
3736 struct WILC_WFI_priv *priv;
3737 struct wireless_dev *wdev;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003738 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003739
3740 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3741
3742 wdev = WILC_WFI_CfgAlloc();
3743 if (wdev == NULL) {
3744 PRINT_ER("CfgAlloc Failed\n");
3745 return NULL;
3746 }
3747
3748
3749 /*Return hardware description structure (wiphy)'s priv*/
3750 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003751 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003752
3753 /*Link the wiphy with wireless structure*/
3754 priv->wdev = wdev;
3755
3756 /*Maximum number of probed ssid to be added by user for the scan request*/
3757 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003758 /*Maximum number of pmkids to be cashed*/
3759 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3760 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003761
3762 wdev->wiphy->max_scan_ie_len = 1000;
3763
3764 /*signal strength in mBm (100*dBm) */
3765 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3766
3767 /*Set the availaible cipher suites*/
3768 wdev->wiphy->cipher_suites = cipher_suites;
3769 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003770 /*Setting default managment types: for register action frame: */
3771 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003772
3773#ifdef WILC_P2P
3774 wdev->wiphy->max_remain_on_channel_duration = 500;
3775 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3776 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3777 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003778 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003779#else
3780 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
3781#endif
3782 wdev->iftype = NL80211_IFTYPE_STATION;
3783
3784
3785
3786 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3787 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3788 wdev->wiphy->interface_modes, wdev->iftype);
3789
3790 #ifdef WILC_SDIO
3791 set_wiphy_dev(wdev->wiphy, &local_sdio_func->dev); /* tony */
3792 #endif
3793
3794 /*Register wiphy structure*/
3795 s32Error = wiphy_register(wdev->wiphy);
3796 if (s32Error) {
3797 PRINT_ER("Cannot register wiphy device\n");
3798 /*should define what action to be taken in such failure*/
3799 } else {
3800 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3801 }
3802
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003803 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003804 return wdev;
3805
3806
3807}
3808/**
3809 * @brief WILC_WFI_WiphyFree
3810 * @details Freeing allocation of the wireless device structure
3811 * @param[in] NONE
3812 * @return NONE
3813 * @author mdaftedar
3814 * @date 01 MAR 2012
3815 * @version 1.0
3816 */
3817int WILC_WFI_InitHostInt(struct net_device *net)
3818{
3819
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003820 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003821
3822 struct WILC_WFI_priv *priv;
3823
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003824 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3825 priv = wdev_priv(net->ieee80211_ptr);
3826 if (op_ifcs == 0) {
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003827 s32Error = WILC_TimerCreate(&(hAgingTimer), remove_network_from_shadow, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003828 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003829 s32Error = WILC_TimerCreate(&(hDuringIpTimer), clear_duringIP, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003830 #endif
3831 }
3832 op_ifcs++;
3833 if (s32Error < 0) {
3834 PRINT_ER("Failed to creat refresh Timer\n");
3835 return s32Error;
3836 }
3837
Dean Lee72ed4dc2015-06-12 14:11:44 +09003838 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003839
Dean Lee72ed4dc2015-06-12 14:11:44 +09003840 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003841
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003842 sema_init(&(priv->hSemScanReq), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003843 s32Error = host_int_init(&priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003844 if (s32Error) {
3845 PRINT_ER("Error while initializing hostinterface\n");
3846 }
3847 return s32Error;
3848}
3849
3850/**
3851 * @brief WILC_WFI_WiphyFree
3852 * @details Freeing allocation of the wireless device structure
3853 * @param[in] NONE
3854 * @return NONE
3855 * @author mdaftedar
3856 * @date 01 MAR 2012
3857 * @version 1.0
3858 */
3859int WILC_WFI_DeInitHostInt(struct net_device *net)
3860{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003861 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003862
3863 struct WILC_WFI_priv *priv;
3864 priv = wdev_priv(net->ieee80211_ptr);
3865
Dean Lee72ed4dc2015-06-12 14:11:44 +09003866 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003867
Dean Lee72ed4dc2015-06-12 14:11:44 +09003868 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003869
3870 op_ifcs--;
3871
3872 s32Error = host_int_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003873
3874 /* Clear the Shadow scan */
3875 clear_shadow_scan(priv);
3876 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
3877 if (op_ifcs == 0) {
3878 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003879 WILC_TimerDestroy(&hDuringIpTimer, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003880 }
3881 #endif
3882
3883 if (s32Error) {
3884 PRINT_ER("Error while deintializing host interface\n");
3885 }
3886 return s32Error;
3887}
3888
3889
3890/**
3891 * @brief WILC_WFI_WiphyFree
3892 * @details Freeing allocation of the wireless device structure
3893 * @param[in] NONE
3894 * @return NONE
3895 * @author mdaftedar
3896 * @date 01 MAR 2012
3897 * @version 1.0
3898 */
3899void WILC_WFI_WiphyFree(struct net_device *net)
3900{
3901
3902 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3903
3904 if (net == NULL) {
3905 PRINT_D(INIT_DBG, "net_device is NULL\n");
3906 return;
3907 }
3908
3909 if (net->ieee80211_ptr == NULL) {
3910 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3911 return;
3912 }
3913
3914 if (net->ieee80211_ptr->wiphy == NULL) {
3915 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3916 return;
3917 }
3918
3919 wiphy_unregister(net->ieee80211_ptr->wiphy);
3920
3921 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3922 wiphy_free(net->ieee80211_ptr->wiphy);
3923 kfree(net->ieee80211_ptr);
3924
3925}