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