blob: 32fd54312659e2b978828f235b01a9f7e7a5bd81 [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
Leo Kim7ae43362015-09-16 18:35:59 +090018#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +090019
20#define IS_MANAGMEMENT 0x100
21#define IS_MANAGMEMENT_CALLBACK 0x080
22#define IS_MGMT_STATUS_SUCCES 0x040
23#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
24
Johnny Kimc5c77ba2015-05-11 14:30:56 +090025extern int linux_wlan_get_firmware(perInterface_wlan_t *p_nic);
Dean Lee72ed4dc2015-06-12 14:11:44 +090026extern u16 Set_machw_change_vir_if(bool bValue);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090027
28extern int mac_open(struct net_device *ndev);
29extern int mac_close(struct net_device *ndev);
30
31tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
Chaehyun Lim4e4467f2015-06-11 14:35:55 +090032u32 u32LastScannedNtwrksCountShadow;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090033#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Greg Kroah-Hartmanda711eb2015-08-14 19:46:06 -070034struct timer_list hDuringIpTimer;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090035#endif
Greg Kroah-Hartmanda711eb2015-08-14 19:46:06 -070036struct timer_list hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +090037static u8 op_ifcs;
38extern u8 u8ConnectedSSID[6];
Johnny Kimc5c77ba2015-05-11 14:30:56 +090039
40/*BugID_5137*/
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +090041u8 g_wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090042extern linux_wlan_t *g_linux_wlan;
43#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Dean Lee72ed4dc2015-06-12 14:11:44 +090044extern bool g_obtainingIP;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090045#endif
46
47#define CHAN2G(_channel, _freq, _flags) { \
48 .band = IEEE80211_BAND_2GHZ, \
49 .center_freq = (_freq), \
50 .hw_value = (_channel), \
51 .flags = (_flags), \
52 .max_antenna_gain = 0, \
53 .max_power = 30, \
54}
55
56/*Frequency range for channels*/
57static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
58 CHAN2G(1, 2412, 0),
59 CHAN2G(2, 2417, 0),
60 CHAN2G(3, 2422, 0),
61 CHAN2G(4, 2427, 0),
62 CHAN2G(5, 2432, 0),
63 CHAN2G(6, 2437, 0),
64 CHAN2G(7, 2442, 0),
65 CHAN2G(8, 2447, 0),
66 CHAN2G(9, 2452, 0),
67 CHAN2G(10, 2457, 0),
68 CHAN2G(11, 2462, 0),
69 CHAN2G(12, 2467, 0),
70 CHAN2G(13, 2472, 0),
71 CHAN2G(14, 2484, 0),
72};
73
74#define RATETAB_ENT(_rate, _hw_value, _flags) { \
75 .bitrate = (_rate), \
76 .hw_value = (_hw_value), \
77 .flags = (_flags), \
78}
79
80
81/* Table 6 in section 3.2.1.1 */
82static struct ieee80211_rate WILC_WFI_rates[] = {
83 RATETAB_ENT(10, 0, 0),
84 RATETAB_ENT(20, 1, 0),
85 RATETAB_ENT(55, 2, 0),
86 RATETAB_ENT(110, 3, 0),
87 RATETAB_ENT(60, 9, 0),
88 RATETAB_ENT(90, 6, 0),
89 RATETAB_ENT(120, 7, 0),
90 RATETAB_ENT(180, 8, 0),
91 RATETAB_ENT(240, 9, 0),
92 RATETAB_ENT(360, 10, 0),
93 RATETAB_ENT(480, 11, 0),
94 RATETAB_ENT(540, 12, 0),
95};
96
97#ifdef WILC_P2P
98struct p2p_mgmt_data {
99 int size;
100 u8 *buff;
101};
102
103/*Global variable used to state the current connected STA channel*/
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900104u8 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900105
106/*BugID_5442*/
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900107u8 u8CurrChannel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900108
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900109u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
110u8 u8P2Plocalrandom = 0x01;
111u8 u8P2Precvrandom = 0x00;
112u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
Daniel Machon7fc80962015-08-05 00:09:35 +0200113bool bWilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900114#endif
115
116static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
117 .channels = WILC_WFI_2ghz_channels,
118 .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels),
119 .bitrates = WILC_WFI_rates,
120 .n_bitrates = ARRAY_SIZE(WILC_WFI_rates),
121};
122
123
124/*BugID_5137*/
125struct add_key_params {
126 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900127 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900128 u8 *mac_addr;
129};
130struct add_key_params g_add_gtk_key_params;
131struct wilc_wfi_key g_key_gtk_params;
132struct add_key_params g_add_ptk_key_params;
133struct wilc_wfi_key g_key_ptk_params;
134struct wilc_wfi_wep_key g_key_wep_params;
Daniel Machon7fc80962015-08-05 00:09:35 +0200135bool g_ptk_keys_saved;
136bool g_gtk_keys_saved;
137bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900138
139#define AGING_TIME (9 * 1000)
140#define duringIP_TIME 15000
141
142void clear_shadow_scan(void *pUserVoid)
143{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900144 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900145
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900146 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700147 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900148 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
149
150 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
151 if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +0900152 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900153 astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL;
154 }
155
156 host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
157 astrLastScannedNtwrksShadow[i].pJoinParams = NULL;
158 }
159 u32LastScannedNtwrksCountShadow = 0;
160 }
161
162}
163
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900164u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900165{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900166 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900167 int rssi_v = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900168 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900169
170 for (i = 0; i < num_rssi; i++)
171 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
172
173 rssi_v /= num_rssi;
174 return rssi_v;
175}
176
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900177void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900178{
Chaehyun Lim27268872015-09-15 14:06:13 +0900179 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900180 struct wiphy *wiphy;
181 struct cfg80211_bss *bss = NULL;
182 int i;
183 int rssi = 0;
184
Chaehyun Lim27268872015-09-15 14:06:13 +0900185 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900186 wiphy = priv->dev->ieee80211_ptr->wiphy;
187
188 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
189 tstrNetworkInfo *pstrNetworkInfo;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900190
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
192
193
194 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900195 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900196 struct ieee80211_channel *channel;
197
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900198 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900199
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900200 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900201 channel = ieee80211_get_channel(wiphy, s32Freq);
202
203 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900204 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900205 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
206 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900207 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900208 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900209 }
210 }
211
212 }
213 }
214
215}
216
217void reset_shadow_found(void *pUserVoid)
218{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900219 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900220
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900221 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
222 astrLastScannedNtwrksShadow[i].u8Found = 0;
223
224 }
225}
226
227void update_scan_time(void *pUserVoid)
228{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900229 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900230
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900231 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
232 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
233 }
234}
235
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700236static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900237{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900238 unsigned long now = jiffies;
239 int i, j;
240
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900241
242 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
243 if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530244 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900245
246 if (astrLastScannedNtwrksShadow[i].pu8IEs != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +0900247 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900248 astrLastScannedNtwrksShadow[i].pu8IEs = NULL;
249 }
250
251 host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
252
253 for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) {
254 astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1];
255 }
256 u32LastScannedNtwrksCountShadow--;
257 }
258 }
259
260 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow);
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700261 if (u32LastScannedNtwrksCountShadow != 0) {
262 hAgingTimer.data = arg;
263 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
264 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900265 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700266 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900267}
268
269#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700270static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271{
272 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900273 g_obtainingIP = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900274}
275#endif
276
277int8_t is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
278{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900279 int8_t state = -1;
280 int i;
281
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900282 if (u32LastScannedNtwrksCountShadow == 0) {
283 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700284 hAgingTimer.data = (unsigned long)pUserVoid;
285 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900286 state = -1;
287 } else {
288 /* Linear search for now */
289 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900290 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900291 pstrNetworkInfo->au8bssid, 6) == 0) {
292 state = i;
293 break;
294 }
295 }
296 }
297 return state;
298}
299
300void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
301{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900302 int8_t ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900303 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900304 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900305
306 if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
307 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
308 return;
309 }
310 if (ap_found == -1) {
311 ap_index = u32LastScannedNtwrksCountShadow;
312 u32LastScannedNtwrksCountShadow++;
313
314 } else {
315 ap_index = ap_found;
316 }
317 rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
318 astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
319 if (rssi_index == NUM_RSSI) {
320 rssi_index = 0;
321 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
322 }
323 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
324
325 astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
326 astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
327
328 astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900329 memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900330 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
331
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900332 memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900333 pstrNetworkInfo->au8bssid, ETH_ALEN);
334
335 astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
336 astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
337 astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
338
339 astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
340 astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
341 if (ap_found != -1)
Chaehyun Lim49188af2015-08-11 10:32:41 +0900342 kfree(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900343 astrLastScannedNtwrksShadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900344 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900345 memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900346 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
347
348 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
349 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
350 astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
351 if (ap_found != -1)
352 host_int_freeJoinParams(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
353 astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
354
355}
356
357
358/**
359 * @brief CfgScanResult
360 * @details Callback function which returns the scan results found
361 *
362 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
363 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
364 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
365 * void* pUserVoid: Private structure associated with the wireless interface
366 * @return NONE
367 * @author mabubakr
368 * @date
369 * @version 1.0
370 */
371static void CfgScanResult(tenuScanEvent enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
372{
Chaehyun Lim27268872015-09-15 14:06:13 +0900373 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900374 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900375 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900376 struct ieee80211_channel *channel;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900377 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900378 struct cfg80211_bss *bss = NULL;
379
Chaehyun Lim27268872015-09-15 14:06:13 +0900380 priv = (struct wilc_priv *)pUserVoid;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900381 if (priv->bCfgScanning == true) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900382 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
383 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900384
385 if (!wiphy)
386 return;
387
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900388 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
389 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900390 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900391 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900392 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900393 ) {
394 WILC_ERRORREPORT(s32Error, WILC_FAIL);
395 }
396
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900397 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900398 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900399 channel = ieee80211_get_channel(wiphy, s32Freq);
400
Leo Kim7ae43362015-09-16 18:35:59 +0900401 if (!channel)
402 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900403
404 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530405 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900406 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
407
Dean Lee72ed4dc2015-06-12 14:11:44 +0900408 if (pstrNetworkInfo->bNewNetwork == true) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900409 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
410 /* max_scan_ssids */
411 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
412
413
414 priv->u32RcvdChCount++;
415
416
417
418 if (pJoinParams == NULL) {
419 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
420 }
421 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
422
423 /*P2P peers are sent to WPA supplicant and added to shadow table*/
424
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900425 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
427 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900428 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900429 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900430 }
431
432
433 } else {
434 PRINT_ER("Discovered networks exceeded the max limit\n");
435 }
436 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900437 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900438 /* So this network is discovered before, we'll just update its RSSI */
439 for (i = 0; i < priv->u32RcvdChCount; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900440 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530441 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900442
443 astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
444 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
445 break;
446 }
447 }
448 }
449 }
450 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530451 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
452 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900453 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900454
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530455 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530456 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530457 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530458 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900459
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200460 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900461
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900462 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900463 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900464 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900465 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900466 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900467 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200468 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900469
470 }
471 /*Aborting any scan operation during mac close*/
472 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200473 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900474
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530475 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900476 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900477
478 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900479 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480
Dean Lee72ed4dc2015-06-12 14:11:44 +0900481 cfg80211_scan_done(priv->pstrScanReq, false);
482 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900483 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900484 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200485 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900486 }
487 }
488
489
490 WILC_CATCH(s32Error)
491 {
492 }
493}
494
495
496/**
497 * @brief WILC_WFI_Set_PMKSA
498 * @details Check if pmksa is cached and set it.
499 * @param[in]
500 * @return int : Return 0 on Success
501 * @author mdaftedar
502 * @date 01 MAR 2012
503 * @version 1.0
504 */
Chaehyun Lim27268872015-09-15 14:06:13 +0900505int WILC_WFI_Set_PMKSA(u8 *bssid, struct wilc_priv *priv)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900506{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900507 u32 i;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900508 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900509
510
511 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
512
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900513 if (!memcmp(bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900514 ETH_ALEN)) {
515 PRINT_D(CFG80211_DBG, "PMKID successful comparison");
516
517 /*If bssid is found, set the values*/
518 s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
519
520 if (s32Error != WILC_SUCCESS)
521 PRINT_ER("Error in pmkid\n");
522
523 break;
524 }
525 }
526
527 return s32Error;
528
529
530}
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900531int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900532
533
534/**
535 * @brief CfgConnectResult
536 * @details
537 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
538 * connection response or disconnection notification.
539 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900540 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900541 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
542 * void* pUserVoid: Private data associated with wireless interface
543 * @return NONE
544 * @author mabubakr
545 * @date 01 MAR 2012
546 * @version 1.0
547 */
548int connecting;
549
550static void CfgConnectResult(tenuConnDisconnEvent enuConnDisconnEvent,
551 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900552 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900553 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
554 void *pUserVoid)
555{
Chaehyun Lim27268872015-09-15 14:06:13 +0900556 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900557 struct net_device *dev;
558 #ifdef WILC_P2P
559 tstrWILC_WFIDrv *pstrWFIDrv;
560 #endif
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900561 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900562
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900563 connecting = 0;
564
Chaehyun Lim27268872015-09-15 14:06:13 +0900565 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900566 dev = priv->dev;
567 #ifdef WILC_P2P
568 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
569 #endif
570
571 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
572 /*Initialization*/
Chaehyun Limd85f5322015-06-11 14:35:54 +0900573 u16 u16ConnectStatus = WLAN_STATUS_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900574
575 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
576
577 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
578
579 if ((u8MacStatus == MAC_DISCONNECTED) &&
580 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
581 /* The case here is that our station was waiting for association response frame and has just received it containing status code
582 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
583 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
584 linux_wlan_set_bssid(priv->dev, NullBssid);
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900585 memset(u8ConnectedSSID, 0, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900586
587 /*BugID_5457*/
588 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
589 #ifdef WILC_P2P
590 if (!pstrWFIDrv->u8P2PConnect)
591 u8WLANChannel = INVALID_CHANNEL;
592 #endif
593
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530594 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900595 }
596
597 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900598 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900599 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900600
601 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
602 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900603 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900604
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900605 /* BugID_4209: if this network has expired in the scan results in the above nl80211 layer, refresh them here by calling
606 * cfg80211_inform_bss() with the last Scan results before calling cfg80211_connect_result() to avoid
607 * Linux kernel warning generated at the nl80211 layer */
608
609 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900610 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900611 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
612 unsigned long now = jiffies;
613
614 if (time_after(now,
615 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900616 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900617 }
618
619 break;
620 }
621 }
622
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000623 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900624 /*BugID_5418*/
625 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900626 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900627
628 }
629
630 }
631
632
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530633 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900634
635 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
636
637 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
638 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
639 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
640 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
641 /* be replaced by pstrConnectInfo->u16ConnectStatus */
642 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
643 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Dean Lee72ed4dc2015-06-12 14:11:44 +0900644 g_obtainingIP = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900645 #endif
646 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
647 pstrDisconnectNotifInfo->u16reason, priv->dev);
648 u8P2Plocalrandom = 0x01;
649 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900650 bWilc_ie = false;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900651 memset(priv->au8AssociatedBss, 0, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900652 linux_wlan_set_bssid(priv->dev, NullBssid);
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900653 memset(u8ConnectedSSID, 0, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900654
655 /*BugID_5457*/
656 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
657 #ifdef WILC_P2P
658 if (!pstrWFIDrv->u8P2PConnect)
659 u8WLANChannel = INVALID_CHANNEL;
660 #endif
661 /*BugID_5315*/
662 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
663 * virtual interface to station*/
664 if ((pstrWFIDrv->IFC_UP) && (dev == g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) {
665 pstrDisconnectNotifInfo->u16reason = 3;
666 }
667 /*BugID_5315*/
668 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
669 * to scan again and retry the connection*/
670 else if ((!pstrWFIDrv->IFC_UP) && (dev == g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) {
671 pstrDisconnectNotifInfo->u16reason = 1;
672 }
673 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530674 pstrDisconnectNotifInfo->ie_len, false,
675 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900676
677 }
678
679}
680
681
682/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900683 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900684 * @details Set channel for a given wireless interface. Some devices
685 * may support multi-channel operation (by channel hopping) so cfg80211
686 * doesn't verify much. Note, however, that the passed netdev may be
687 * %NULL as well if the user requested changing the channel for the
688 * device itself, or for a monitor interface.
689 * @param[in]
690 * @return int : Return 0 on Success
691 * @author mdaftedar
692 * @date 01 MAR 2012
693 * @version 1.0
694 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900695static int set_channel(struct wiphy *wiphy,
696 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900697{
698
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900699 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900700 struct wilc_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900701 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900702
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900703 priv = wiphy_priv(wiphy);
704
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900705 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
706 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900707
708 u8CurrChannel = channelnum;
709 s32Error = host_int_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
710
711 if (s32Error != WILC_SUCCESS)
712 PRINT_ER("Error in setting channel %d\n", channelnum);
713
714 return s32Error;
715}
716
717/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900718 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900719 * @details Request to do a scan. If returning zero, the scan request is given
720 * the driver, and will be valid until passed to cfg80211_scan_done().
721 * For scan results, call cfg80211_inform_bss(); you can call this outside
722 * the scan/scan_done bracket too.
723 * @param[in]
724 * @return int : Return 0 on Success
725 * @author mabubakr
726 * @date 01 MAR 2012
727 * @version 1.0
728 */
729
730/*
731 * kernel version 3.8.8 supported
732 * tony, sswd, WILC-KR, 2013-10-29
733 */
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900734static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900735{
Chaehyun Lim27268872015-09-15 14:06:13 +0900736 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900737 u32 i;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900738 s32 s32Error = WILC_SUCCESS;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900739 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900740 tstrHiddenNetwork strHiddenNetwork;
741
742 priv = wiphy_priv(wiphy);
743
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744 priv->pstrScanReq = request;
745
746 priv->u32RcvdChCount = 0;
747
Johnny Kim218dc402015-08-13 13:41:19 +0900748 host_int_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900749
750
751 reset_shadow_found(priv);
752
Dean Lee72ed4dc2015-06-12 14:11:44 +0900753 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900754 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
755 /* max_scan_ssids */
756 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900757 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900758 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
759 }
760
761 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530762 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900763
764 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
765
766 if (request->n_ssids >= 1) {
767
768
Glen Leef3052582015-09-10 12:03:04 +0900769 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(tstrHiddenNetwork), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900770 strHiddenNetwork.u8ssidnum = request->n_ssids;
771
772
773 /*BugID_4156*/
774 for (i = 0; i < request->n_ssids; i++) {
775
776 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900777 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900778 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900779 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
780 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530781 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900782 strHiddenNetwork.u8ssidnum -= 1;
783 }
784 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530785 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900786 s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
787 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900788 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900789 CfgScanResult, (void *)priv, &strHiddenNetwork);
790 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530791 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900792 s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
793 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900794 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900795 CfgScanResult, (void *)priv, NULL);
796 }
797
798 } else {
799 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530800 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900801 }
802
803 if (s32Error != WILC_SUCCESS) {
804 s32Error = -EBUSY;
805 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
806 }
807
808 return s32Error;
809}
810
811/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900812 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900813 * @details Connect to the ESS with the specified parameters. When connected,
814 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
815 * If the connection fails for some reason, call cfg80211_connect_result()
816 * with the status from the AP.
817 * @param[in]
818 * @return int : Return 0 on Success
819 * @author mabubakr
820 * @date 01 MAR 2012
821 * @version 1.0
822 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900823static int connect(struct wiphy *wiphy, struct net_device *dev,
824 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900825{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900826 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900827 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900828 u8 u8security = NO_ENCRYPT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900829 AUTHTYPE_T tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900830 char *pcgroup_encrypt_val = NULL;
831 char *pccipher_group = NULL;
832 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900833
Chaehyun Lim27268872015-09-15 14:06:13 +0900834 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835 tstrWILC_WFIDrv *pstrWFIDrv;
836 tstrNetworkInfo *pstrNetworkInfo = NULL;
837
838
839 connecting = 1;
840 priv = wiphy_priv(wiphy);
841 pstrWFIDrv = (tstrWILC_WFIDrv *)(priv->hWILCWFIDrv);
842
Johnny Kim218dc402015-08-13 13:41:19 +0900843 host_int_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900844
Johnny Kim8a143302015-06-10 17:06:46 +0900845 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 +0900846 #ifdef WILC_P2P
Chaehyun Lim3f882892015-08-10 11:33:17 +0900847 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900848 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
849 pstrWFIDrv->u8P2PConnect = 1;
850 } else
851 pstrWFIDrv->u8P2PConnect = 0;
852 #endif
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530853 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900854
855 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
856 if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900857 memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900858 sme->ssid,
859 sme->ssid_len) == 0) {
860 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
861 if (sme->bssid == NULL) {
862 /* BSSID is not passed from the user, so decision of matching
863 * is done by SSID only */
864 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
865 break;
866 } else {
867 /* BSSID is also passed from the user, so decision of matching
868 * should consider also this passed BSSID */
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900869 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900870 sme->bssid,
871 ETH_ALEN) == 0) {
872 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
873 break;
874 }
875 }
876 }
877 }
878
879 if (i < u32LastScannedNtwrksCountShadow) {
880 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
881
882 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
883
884 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
885 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
886 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
887 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
888 } else {
889 s32Error = -ENOENT;
890 if (u32LastScannedNtwrksCountShadow == 0)
891 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
892 else
893 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
894
895 goto done;
896 }
897
898 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900899 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
900 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900901
902 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
903 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
904
905 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
906
907 if (INFO) {
908 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
909 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
910 }
911
912 if (sme->crypto.cipher_group != NO_ENCRYPT) {
913 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
914 * we will add to it the pairwise cipher suite(s) */
915 pcwpa_version = "Default";
916 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900917 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900918 u8security = ENCRYPT_ENABLED | WEP;
919 pcgroup_encrypt_val = "WEP40";
920 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
921 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
922
923 if (INFO) {
924 for (i = 0; i < sme->key_len; i++)
925 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
926 }
927 priv->WILC_WFI_wep_default = sme->key_idx;
928 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900929 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930
931 /*BugID_5137*/
932 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900933 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900934 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
935 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900936 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900937
938 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, sme->key_idx);
939 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
940 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900941 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
942 pcgroup_encrypt_val = "WEP104";
943 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
944
945 priv->WILC_WFI_wep_default = sme->key_idx;
946 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900947 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900948
949 /*BugID_5137*/
950 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900951 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900952 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
953 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900954 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900955
956 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, sme->key_idx);
957 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
958 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900959 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900960 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
961 pcgroup_encrypt_val = "WPA2_TKIP";
962 pccipher_group = "TKIP";
963 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
964 /* tenuSecurity_t = WPA2_AES; */
965 u8security = ENCRYPT_ENABLED | WPA2 | AES;
966 pcgroup_encrypt_val = "WPA2_AES";
967 pccipher_group = "AES";
968 }
969 pcwpa_version = "WPA_VERSION_2";
970 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
971 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900972 u8security = ENCRYPT_ENABLED | WPA | TKIP;
973 pcgroup_encrypt_val = "WPA_TKIP";
974 pccipher_group = "TKIP";
975 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
976 /* tenuSecurity_t = WPA_AES; */
977 u8security = ENCRYPT_ENABLED | WPA | AES;
978 pcgroup_encrypt_val = "WPA_AES";
979 pccipher_group = "AES";
980
981 }
982 pcwpa_version = "WPA_VERSION_1";
983
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900984 } else {
985 s32Error = -ENOTSUPP;
986 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
987
988 goto done;
989 }
990
991 }
992
993 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
994 * add to it the pairwise cipher suite(s) */
995 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
996 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
997 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
998 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
999 u8security = u8security | TKIP;
1000 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
1001 u8security = u8security | AES;
1002 }
1003 }
1004 }
1005
1006 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
1007
1008 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
1009 switch (sme->auth_type) {
1010 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1011 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
1012 tenuAuth_type = OPEN_SYSTEM;
1013 break;
1014
1015 case NL80211_AUTHTYPE_SHARED_KEY:
1016 tenuAuth_type = SHARED_KEY;
1017 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
1018 break;
1019
1020 default:
1021 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1022 }
1023
1024
1025 /* ai: key_mgmt: enterprise case */
1026 if (sme->crypto.n_akm_suites) {
1027 switch (sme->crypto.akm_suites[0]) {
1028 case WLAN_AKM_SUITE_8021X:
1029 tenuAuth_type = IEEE8021;
1030 break;
1031
1032 default:
1033 break;
1034 }
1035 }
1036
1037
1038 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1039
1040 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1041 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1042
1043 /*BugID_5442*/
1044 u8CurrChannel = pstrNetworkInfo->u8channel;
1045
1046 if (!pstrWFIDrv->u8P2PConnect) {
1047 u8WLANChannel = pstrNetworkInfo->u8channel;
1048 }
1049
1050 linux_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
1051
1052 s32Error = host_int_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
1053 sme->ssid_len, sme->ie, sme->ie_len,
1054 CfgConnectResult, (void *)priv, u8security,
1055 tenuAuth_type, pstrNetworkInfo->u8channel,
1056 pstrNetworkInfo->pJoinParams);
1057 if (s32Error != WILC_SUCCESS) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301058 PRINT_ER("host_int_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001059 s32Error = -ENOENT;
1060 goto done;
1061 }
1062
1063done:
1064
1065 return s32Error;
1066}
1067
1068
1069/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001070 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001071 * @details Disconnect from the BSS/ESS.
1072 * @param[in]
1073 * @return int : Return 0 on Success
1074 * @author mdaftedar
1075 * @date 01 MAR 2012
1076 * @version 1.0
1077 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001078static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001079{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001080 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09001081 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001082 #ifdef WILC_P2P
1083 tstrWILC_WFIDrv *pstrWFIDrv;
1084 #endif
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001085 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001086
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001087 connecting = 0;
1088 priv = wiphy_priv(wiphy);
1089
1090 /*BugID_5457*/
1091 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
1092 #ifdef WILC_P2P
1093 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
1094 if (!pstrWFIDrv->u8P2PConnect)
1095 u8WLANChannel = INVALID_CHANNEL;
1096 #endif
1097 linux_wlan_set_bssid(priv->dev, NullBssid);
1098
1099 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1100
1101 u8P2Plocalrandom = 0x01;
1102 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001103 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001104 #ifdef WILC_P2P
1105 pstrWFIDrv->u64P2p_MgmtTimeout = 0;
1106 #endif
1107
1108 s32Error = host_int_disconnect(priv->hWILCWFIDrv, reason_code);
1109 if (s32Error != WILC_SUCCESS) {
1110 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1111 s32Error = -EINVAL;
1112 }
1113
1114 return s32Error;
1115}
1116
1117/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001118 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001119 * @details Add a key with the given parameters. @mac_addr will be %NULL
1120 * when adding a group key.
1121 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1122 * @return int : Return 0 on Success
1123 * @author mdaftedar
1124 * @date 01 MAR 2012
1125 * @version 1.0
1126 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001127static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1128 bool pairwise,
1129 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001130
1131{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001132 s32 s32Error = WILC_SUCCESS, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001133 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001134 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001135 const u8 *pu8RxMic = NULL;
1136 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001137 u8 u8mode = NO_ENCRYPT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001138 #ifdef WILC_AP_EXTERNAL_MLME
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001139 u8 u8gmode = NO_ENCRYPT;
1140 u8 u8pmode = NO_ENCRYPT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001141 AUTHTYPE_T tenuAuth_type = ANY;
1142 #endif
1143
1144 priv = wiphy_priv(wiphy);
1145
1146 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1147
1148 /*BugID_5137*/
Johnny Kim8a143302015-06-10 17:06:46 +09001149 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001150
1151 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1152 params->key[1],
1153 params->key[2]);
1154
1155
1156 switch (params->cipher) {
1157 case WLAN_CIPHER_SUITE_WEP40:
1158 case WLAN_CIPHER_SUITE_WEP104:
1159 #ifdef WILC_AP_EXTERNAL_MLME
1160 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1161
1162 priv->WILC_WFI_wep_default = key_index;
1163 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001164 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001165
1166 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1167 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1168
1169 for (i = 0; i < params->key_len; i++)
1170 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1171
1172 tenuAuth_type = OPEN_SYSTEM;
1173
1174 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1175 u8mode = ENCRYPT_ENABLED | WEP;
1176 else
1177 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1178
1179 host_int_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
1180 break;
1181 }
1182 #endif
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001183 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001184 priv->WILC_WFI_wep_default = key_index;
1185 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001186 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001187
1188 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1189 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1190 if (INFO) {
1191 for (i = 0; i < params->key_len; i++)
1192 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1193 }
1194 host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
1195 }
1196
1197 break;
1198
1199 case WLAN_CIPHER_SUITE_TKIP:
1200 case WLAN_CIPHER_SUITE_CCMP:
1201 #ifdef WILC_AP_EXTERNAL_MLME
1202 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1203
1204 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001205 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001206 priv->wilc_gtk[key_index]->key = NULL;
1207 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001208
1209 }
1210 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001211 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001212 priv->wilc_ptk[key_index]->key = NULL;
1213 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001214 }
1215
1216
1217
Daniel Machon19132212015-08-05 08:18:31 +02001218 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001219 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1220 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1221 else
1222 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1223
1224 priv->wilc_groupkey = u8gmode;
1225
1226 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1227
1228 pu8TxMic = params->key + 24;
1229 pu8RxMic = params->key + 16;
1230 KeyLen = params->key_len - 16;
1231 }
1232 /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
1233 if (priv->wilc_gtk[key_index]->key)
Chaehyun Lim49188af2015-08-11 10:32:41 +09001234 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001235
Glen Leef3052582015-09-10 12:03:04 +09001236 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001237 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001238
1239 /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
1240 if (priv->wilc_gtk[key_index]->seq)
Chaehyun Lim49188af2015-08-11 10:32:41 +09001241 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001242
1243 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001244 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001245 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001246 }
1247
1248 priv->wilc_gtk[key_index]->cipher = params->cipher;
1249 priv->wilc_gtk[key_index]->key_len = params->key_len;
1250 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1251
1252 if (INFO) {
1253 for (i = 0; i < params->key_len; i++)
1254 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1255 for (i = 0; i < params->seq_len; i++)
1256 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1257 }
1258
1259
1260 host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
1261 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1262
1263 } else {
1264 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]);
1265
1266 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1267 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1268 else
1269 u8pmode = priv->wilc_groupkey | AES;
1270
1271
1272 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1273
1274 pu8TxMic = params->key + 24;
1275 pu8RxMic = params->key + 16;
1276 KeyLen = params->key_len - 16;
1277 }
1278
1279 if (priv->wilc_ptk[key_index]->key)
Chaehyun Lim49188af2015-08-11 10:32:41 +09001280 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001281
Glen Leef3052582015-09-10 12:03:04 +09001282 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001283
1284 if (priv->wilc_ptk[key_index]->seq)
Chaehyun Lim49188af2015-08-11 10:32:41 +09001285 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001286
1287 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001288 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001289
1290 if (INFO) {
1291 for (i = 0; i < params->key_len; i++)
1292 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1293
1294 for (i = 0; i < params->seq_len; i++)
1295 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1296 }
1297
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001298 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001299
1300 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001301 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001302
1303 priv->wilc_ptk[key_index]->cipher = params->cipher;
1304 priv->wilc_ptk[key_index]->key_len = params->key_len;
1305 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1306
1307 host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
1308 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1309 }
1310 break;
1311 }
1312 #endif
1313
1314 {
1315 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001316 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001317 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1318 /* swap the tx mic by rx mic */
1319 pu8RxMic = params->key + 24;
1320 pu8TxMic = params->key + 16;
1321 KeyLen = params->key_len - 16;
1322 }
1323
1324 /*BugID_5137*/
1325 /*save keys only on interface 0 (wifi interface)*/
1326 if (!g_gtk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
1327 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 if (!mac_addr) {
1330 g_add_gtk_key_params.mac_addr = NULL;
1331 } else {
Glen Leef3052582015-09-10 12:03:04 +09001332 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001333 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1334 }
1335 g_key_gtk_params.key_len = params->key_len;
1336 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001337 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1339 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001340 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001341 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1342 }
1343 g_key_gtk_params.cipher = params->cipher;
1344
1345 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1346 g_key_gtk_params.key[1],
1347 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001348 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001349 }
1350
1351 host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
1352 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001353 } else {
1354 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1355 /* swap the tx mic by rx mic */
1356 pu8RxMic = params->key + 24;
1357 pu8TxMic = params->key + 16;
1358 KeyLen = params->key_len - 16;
1359 }
1360
1361 /*BugID_5137*/
1362 /*save keys only on interface 0 (wifi interface)*/
1363 if (!g_ptk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
1364 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001365 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001366 if (!mac_addr) {
1367 g_add_ptk_key_params.mac_addr = NULL;
1368 } else {
Glen Leef3052582015-09-10 12:03:04 +09001369 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001370 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1371 }
1372 g_key_ptk_params.key_len = params->key_len;
1373 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001374 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001375 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1376 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001377 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001378 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1379 }
1380 g_key_ptk_params.cipher = params->cipher;
1381
1382 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1383 g_key_ptk_params.key[1],
1384 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001385 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001386 }
1387
1388 host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
1389 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1390 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1391 if (INFO) {
1392 for (i = 0; i < params->key_len; i++)
1393 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1394 }
1395 }
1396 }
1397 break;
1398
1399 default:
1400 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1401 s32Error = -ENOTSUPP;
1402
1403 }
1404
1405 return s32Error;
1406}
1407
1408/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001409 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001410 * @details Remove a key given the @mac_addr (%NULL for a group key)
1411 * and @key_index, return -ENOENT if the key doesn't exist.
1412 * @param[in]
1413 * @return int : Return 0 on Success
1414 * @author mdaftedar
1415 * @date 01 MAR 2012
1416 * @version 1.0
1417 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001418static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1419 u8 key_index,
1420 bool pairwise,
1421 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001422{
Chaehyun Lim27268872015-09-15 14:06:13 +09001423 struct wilc_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001424 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001425
1426 priv = wiphy_priv(wiphy);
1427
1428 /*BugID_5137*/
1429 /*delete saved keys, if any*/
1430 if (netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001431 g_ptk_keys_saved = false;
1432 g_gtk_keys_saved = false;
1433 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001434
1435 /*Delete saved WEP keys params, if any*/
1436 if (g_key_wep_params.key != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +09001437 kfree(g_key_wep_params.key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001438 g_key_wep_params.key = NULL;
1439 }
1440
1441 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1442
1443 #ifdef WILC_AP_EXTERNAL_MLME
1444 if ((priv->wilc_gtk[key_index]) != NULL) {
1445
1446 if (priv->wilc_gtk[key_index]->key != NULL) {
1447
Chaehyun Lim49188af2015-08-11 10:32:41 +09001448 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001449 priv->wilc_gtk[key_index]->key = NULL;
1450 }
1451 if (priv->wilc_gtk[key_index]->seq) {
1452
Chaehyun Lim49188af2015-08-11 10:32:41 +09001453 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001454 priv->wilc_gtk[key_index]->seq = NULL;
1455 }
1456
Chaehyun Lim49188af2015-08-11 10:32:41 +09001457 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001458 priv->wilc_gtk[key_index] = NULL;
1459
1460 }
1461
1462 if ((priv->wilc_ptk[key_index]) != NULL) {
1463
1464 if (priv->wilc_ptk[key_index]->key) {
1465
Chaehyun Lim49188af2015-08-11 10:32:41 +09001466 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001467 priv->wilc_ptk[key_index]->key = NULL;
1468 }
1469 if (priv->wilc_ptk[key_index]->seq) {
1470
Chaehyun Lim49188af2015-08-11 10:32:41 +09001471 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001472 priv->wilc_ptk[key_index]->seq = NULL;
1473 }
Chaehyun Lim49188af2015-08-11 10:32:41 +09001474 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001475 priv->wilc_ptk[key_index] = NULL;
1476 }
1477 #endif
1478
1479 /*Delete saved PTK and GTK keys params, if any*/
1480 if (g_key_ptk_params.key != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +09001481 kfree(g_key_ptk_params.key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001482 g_key_ptk_params.key = NULL;
1483 }
1484 if (g_key_ptk_params.seq != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +09001485 kfree(g_key_ptk_params.seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001486 g_key_ptk_params.seq = NULL;
1487 }
1488
1489 if (g_key_gtk_params.key != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +09001490 kfree(g_key_gtk_params.key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001491 g_key_gtk_params.key = NULL;
1492 }
1493 if (g_key_gtk_params.seq != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +09001494 kfree(g_key_gtk_params.seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001495 g_key_gtk_params.seq = NULL;
1496 }
1497
1498 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Dean Lee72ed4dc2015-06-12 14:11:44 +09001499 Set_machw_change_vir_if(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001500 }
1501
1502 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001503 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001504 priv->WILC_WFI_wep_key_len[key_index] = 0;
1505
1506 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
1507 host_int_remove_wep_key(priv->hWILCWFIDrv, key_index);
1508 } else {
1509 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
1510 host_int_remove_key(priv->hWILCWFIDrv, mac_addr);
1511 }
1512
1513 return s32Error;
1514}
1515
1516/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001517 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001518 * @details Get information about the key with the given parameters.
1519 * @mac_addr will be %NULL when requesting information for a group
1520 * key. All pointers given to the @callback function need not be valid
1521 * after it returns. This function should return an error if it is
1522 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1523 * @param[in]
1524 * @return int : Return 0 on Success
1525 * @author mdaftedar
1526 * @date 01 MAR 2012
1527 * @version 1.0
1528 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001529static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1530 bool pairwise,
1531 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001532{
1533
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001534 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001535
Chaehyun Lim27268872015-09-15 14:06:13 +09001536 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001537 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001538 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001539
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001540 priv = wiphy_priv(wiphy);
1541
1542
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001543 if (!pairwise)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001544 {
1545 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1546
1547 key_params.key = priv->wilc_gtk[key_index]->key;
1548 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1549 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1550 key_params.seq = priv->wilc_gtk[key_index]->seq;
1551 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1552 if (INFO) {
1553 for (i = 0; i < key_params.key_len; i++)
1554 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1555 }
1556 } else {
1557 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1558
1559 key_params.key = priv->wilc_ptk[key_index]->key;
1560 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1561 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1562 key_params.seq = priv->wilc_ptk[key_index]->seq;
1563 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1564 }
1565
1566 callback(cookie, &key_params);
1567
1568 return s32Error; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
1569}
1570
1571/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001572 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001573 * @details Set the default management frame key on an interface
1574 * @param[in]
1575 * @return int : Return 0 on Success.
1576 * @author mdaftedar
1577 * @date 01 MAR 2012
1578 * @version 1.0
1579 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001580static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1581 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001582{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001583 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09001584 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001585
1586
1587 priv = wiphy_priv(wiphy);
1588
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301589 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590
1591 if (key_index != priv->WILC_WFI_wep_default) {
1592
1593 host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, key_index);
1594 }
1595
1596 return s32Error;
1597}
1598
1599/**
1600 * @brief WILC_WFI_dump_survey
1601 * @details Get site survey information
1602 * @param[in]
1603 * @return int : Return 0 on Success.
1604 * @author mdaftedar
1605 * @date 01 MAR 2012
1606 * @version 1.0
1607 */
1608static int WILC_WFI_dump_survey(struct wiphy *wiphy, struct net_device *netdev,
1609 int idx, struct survey_info *info)
1610{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001611 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001612
1613
1614 if (idx != 0) {
1615 s32Error = -ENOENT;
1616 PRINT_ER("Error Idx value doesn't equal zero: Error(%d)\n", s32Error);
1617
1618 }
1619
1620 return s32Error;
1621}
1622
1623
1624/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001625 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001626 * @details Get station information for the station identified by @mac
1627 * @param[in] NONE
1628 * @return int : Return 0 on Success.
1629 * @author mdaftedar
1630 * @date 01 MAR 2012
1631 * @version 1.0
1632 */
1633
Chaehyun Limf06f5622015-09-14 12:24:18 +09001634static int get_station(struct wiphy *wiphy, struct net_device *dev,
1635 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001636{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001637 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09001638 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001639 perInterface_wlan_t *nic;
1640 #ifdef WILC_AP_EXTERNAL_MLME
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001641 u32 i = 0;
1642 u32 associatedsta = 0;
1643 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001644 #endif
1645 priv = wiphy_priv(wiphy);
1646 nic = netdev_priv(dev);
1647
1648 #ifdef WILC_AP_EXTERNAL_MLME
1649 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1650 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1651
1652 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1653
1654 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1655
1656 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1657 associatedsta = i;
1658 break;
1659 }
1660
1661 }
1662
1663 if (associatedsta == -1) {
1664 s32Error = -ENOENT;
1665 PRINT_ER("Station required is not associated : Error(%d)\n", s32Error);
1666
1667 return s32Error;
1668 }
1669
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001670 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001671
1672 host_int_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
1673 sinfo->inactive_time = 1000 * inactive_time;
1674 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1675
1676 }
1677 #endif
1678
1679 if (nic->iftype == STATION_MODE) {
1680 tstrStatistics strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001681
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001682 host_int_get_statistics(priv->hWILCWFIDrv, &strStatistics);
1683
1684 /*
1685 * tony: 2013-11-13
1686 * tx_failed introduced more than
1687 * kernel version 3.0.0
1688 */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001689 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301690 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001691 BIT(NL80211_STA_INFO_TX_PACKETS) |
1692 BIT(NL80211_STA_INFO_TX_FAILED) |
1693 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001694
1695 sinfo->signal = strStatistics.s8RSSI;
1696 sinfo->rx_packets = strStatistics.u32RxCount;
1697 sinfo->tx_packets = strStatistics.u32TxCount + strStatistics.u32TxFailureCount;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001698 sinfo->tx_failed = strStatistics.u32TxFailureCount;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001699 sinfo->txrate.legacy = strStatistics.u8LinkSpeed * 10;
1700
1701#ifdef TCP_ENHANCEMENTS
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301702 if ((strStatistics.u8LinkSpeed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED))
Dean Lee72ed4dc2015-06-12 14:11:44 +09001703 Enable_TCP_ACK_Filter(true);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301704 else if (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED)
Dean Lee72ed4dc2015-06-12 14:11:44 +09001705 Enable_TCP_ACK_Filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001706#endif
1707
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001708 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1709 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001710 }
1711 return s32Error;
1712}
1713
1714
1715/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001716 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001717 * @details Modify parameters for a given BSS.
1718 * @param[in]
1719 * -use_cts_prot: Whether to use CTS protection
1720 * (0 = no, 1 = yes, -1 = do not change)
1721 * -use_short_preamble: Whether the use of short preambles is allowed
1722 * (0 = no, 1 = yes, -1 = do not change)
1723 * -use_short_slot_time: Whether the use of short slot time is allowed
1724 * (0 = no, 1 = yes, -1 = do not change)
1725 * -basic_rates: basic rates in IEEE 802.11 format
1726 * (or NULL for no change)
1727 * -basic_rates_len: number of basic rates
1728 * -ap_isolate: do not forward packets between connected stations
1729 * -ht_opmode: HT Operation mode
1730 * (u16 = opmode, -1 = do not change)
1731 * @return int : Return 0 on Success.
1732 * @author mdaftedar
1733 * @date 01 MAR 2012
1734 * @version 1.0
1735 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001736static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1737 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001738{
1739 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1740 return 0;
1741}
1742
1743/**
1744 * @brief WILC_WFI_auth
1745 * @details Request to authenticate with the specified peer
1746 * @param[in]
1747 * @return int : Return 0 on Success.
1748 * @author mdaftedar
1749 * @date 01 MAR 2012
1750 * @version 1.0
1751 */
1752static int WILC_WFI_auth(struct wiphy *wiphy, struct net_device *dev,
1753 struct cfg80211_auth_request *req)
1754{
1755 PRINT_D(CFG80211_DBG, "In Authentication Function\n");
1756 return 0;
1757}
1758
1759/**
1760 * @brief WILC_WFI_assoc
1761 * @details Request to (re)associate with the specified peer
1762 * @param[in]
1763 * @return int : Return 0 on Success.
1764 * @author mdaftedar
1765 * @date 01 MAR 2012
1766 * @version 1.0
1767 */
1768static int WILC_WFI_assoc(struct wiphy *wiphy, struct net_device *dev,
1769 struct cfg80211_assoc_request *req)
1770{
1771 PRINT_D(CFG80211_DBG, "In Association Function\n");
1772 return 0;
1773}
1774
1775/**
1776 * @brief WILC_WFI_deauth
1777 * @details Request to deauthenticate from the specified peer
1778 * @param[in]
1779 * @return int : Return 0 on Success.
1780 * @author mdaftedar
1781 * @date 01 MAR 2012
1782 * @version 1.0
1783 */
1784static int WILC_WFI_deauth(struct wiphy *wiphy, struct net_device *dev,
1785 struct cfg80211_deauth_request *req, void *cookie)
1786{
1787 PRINT_D(CFG80211_DBG, "In De-authentication Function\n");
1788 return 0;
1789}
1790
1791/**
1792 * @brief WILC_WFI_disassoc
1793 * @details Request to disassociate from the specified peer
1794 * @param[in]
1795 * @return int : Return 0 on Success
1796 * @author mdaftedar
1797 * @date 01 MAR 2012
1798 * @version 1.0
1799 */
1800static int WILC_WFI_disassoc(struct wiphy *wiphy, struct net_device *dev,
1801 struct cfg80211_disassoc_request *req, void *cookie)
1802{
1803 PRINT_D(CFG80211_DBG, "In Disassociation Function\n");
1804 return 0;
1805}
1806
1807/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001808 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001809 * @details Notify that wiphy parameters have changed;
1810 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1811 * have changed.
1812 * @return int : Return 0 on Success
1813 * @author mdaftedar
1814 * @date 01 MAR 2012
1815 * @version 1.0
1816 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001817static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001818{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001819 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001820 tstrCfgParamVal pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001821 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001822
1823 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001824
1825 pstrCfgParamVal.u32SetCfgFlag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301826 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001827
1828 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1829 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1830 priv->dev->ieee80211_ptr->wiphy->retry_short);
1831 pstrCfgParamVal.u32SetCfgFlag |= RETRY_SHORT;
1832 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1833 }
1834 if (changed & WIPHY_PARAM_RETRY_LONG) {
1835
1836 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
1837 pstrCfgParamVal.u32SetCfgFlag |= RETRY_LONG;
1838 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1839
1840 }
1841 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1842 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
1843 pstrCfgParamVal.u32SetCfgFlag |= FRAG_THRESHOLD;
1844 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1845
1846 }
1847
1848 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1849 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1850
1851 pstrCfgParamVal.u32SetCfgFlag |= RTS_THRESHOLD;
1852 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1853
1854 }
1855
1856 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
1857 s32Error = hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
1858 if (s32Error)
1859 PRINT_ER("Error in setting WIPHY PARAMS\n");
1860
1861
1862 return s32Error;
1863}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001864
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001865/**
1866 * @brief WILC_WFI_set_bitrate_mask
1867 * @details set the bitrate mask configuration
1868 * @param[in]
1869 * @return int : Return 0 on Success
1870 * @author mdaftedar
1871 * @date 01 MAR 2012
1872 * @version 1.0
1873 */
1874static int WILC_WFI_set_bitrate_mask(struct wiphy *wiphy,
1875 struct net_device *dev, const u8 *peer,
1876 const struct cfg80211_bitrate_mask *mask)
1877{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001878 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001879
1880 PRINT_D(CFG80211_DBG, "Setting Bitrate mask function\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001881 return s32Error;
1882
1883}
1884
1885/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001886 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001887 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1888 * devices running firmwares capable of generating the (re) association
1889 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1890 * @param[in]
1891 * @return int : Return 0 on Success
1892 * @author mdaftedar
1893 * @date 01 MAR 2012
1894 * @version 1.0
1895 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001896static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1897 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001898{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001899 u32 i;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001900 s32 s32Error = WILC_SUCCESS;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001901 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001902
Chaehyun Lim27268872015-09-15 14:06:13 +09001903 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001904
1905 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1906
1907
1908 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001909 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001910 ETH_ALEN)) {
1911 /*If bssid already exists and pmkid value needs to reset*/
1912 flag = PMKID_FOUND;
1913 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1914 break;
1915 }
1916 }
1917 if (i < WILC_MAX_NUM_PMKIDS) {
1918 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001919 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001920 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001921 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001922 PMKID_LEN);
1923 if (!(flag == PMKID_FOUND))
1924 priv->pmkid_list.numpmkid++;
1925 } else {
1926 PRINT_ER("Invalid PMKID index\n");
1927 s32Error = -EINVAL;
1928 }
1929
1930 if (!s32Error) {
1931 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
1932 s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
1933 }
1934 return s32Error;
1935}
1936
1937/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001938 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001939 * @details Delete a cached PMKID.
1940 * @param[in]
1941 * @return int : Return 0 on Success
1942 * @author mdaftedar
1943 * @date 01 MAR 2012
1944 * @version 1.0
1945 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001946static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1947 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001948{
1949
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001950 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001951 u8 flag = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001952 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001953
Chaehyun Lim27268872015-09-15 14:06:13 +09001954 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001955
1956 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1957
1958 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001959 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001960 ETH_ALEN)) {
1961 /*If bssid is found, reset the values*/
1962 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001963 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(tstrHostIFpmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001964 flag = PMKID_FOUND;
1965 break;
1966 }
1967 }
1968
1969 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1970 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001971 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001972 priv->pmkid_list.pmkidlist[i + 1].bssid,
1973 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001974 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001975 priv->pmkid_list.pmkidlist[i].pmkid,
1976 PMKID_LEN);
1977 }
1978 priv->pmkid_list.numpmkid--;
1979 } else {
1980 s32Error = -EINVAL;
1981 }
1982
1983 return s32Error;
1984}
1985
1986/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001987 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001988 * @details Flush all cached PMKIDs.
1989 * @param[in]
1990 * @return int : Return 0 on Success
1991 * @author mdaftedar
1992 * @date 01 MAR 2012
1993 * @version 1.0
1994 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001995static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001996{
Chaehyun Lim27268872015-09-15 14:06:13 +09001997 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001998
1999 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
2000
2001 /*Get cashed Pmkids and set all with zeros*/
Chaehyun Lim2cc46832015-08-07 09:02:01 +09002002 memset(&priv->pmkid_list, 0, sizeof(tstrHostIFpmkidAttr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002003
2004 return 0;
2005}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002006
2007#ifdef WILC_P2P
2008
2009/**
2010 * @brief WILC_WFI_CfgParseRxAction
2011 * @details Function parses the received frames and modifies the following attributes:
2012 * -GO Intent
2013 * -Channel list
2014 * -Operating Channel
2015 *
2016 * @param[in] u8* Buffer, u32 length
2017 * @return NONE.
2018 * @author mdaftedar
2019 * @date 12 DEC 2012
2020 * @version
2021 */
2022
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002023void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002024{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002025 u32 index = 0;
2026 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002027
2028 /*BugID_5460*/
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002029 u8 op_channel_attr_index = 0;
2030 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002031
2032 while (index < len) {
2033 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002034 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002035 }
2036
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302037 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002038 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302039 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002040 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002041 index += buf[index + 1] + 3; /* ID,Length byte */
2042 }
2043
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002044 if (u8WLANChannel != INVALID_CHANNEL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002045 {
2046 /*Modify channel list attribute*/
2047 if (channel_list_attr_index) {
2048 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
2049 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
2050 if (buf[i] == 0x51) {
2051 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
2052 buf[j] = u8WLANChannel;
2053 }
2054 break;
2055 }
2056 }
2057 }
2058 /*Modify operating channel attribute*/
2059 if (op_channel_attr_index) {
2060 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
2061 buf[op_channel_attr_index + 6] = 0x51;
2062 buf[op_channel_attr_index + 7] = u8WLANChannel;
2063 }
2064 }
2065}
2066
2067/**
2068 * @brief WILC_WFI_CfgParseTxAction
2069 * @details Function parses the transmitted action frames and modifies the
2070 * GO Intent attribute
2071 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
2072 * @return NONE.
2073 * @author mdaftedar
2074 * @date 12 DEC 2012
2075 * @version
2076 */
Dean Lee72ed4dc2015-06-12 14:11:44 +09002077void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002078{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002079 u32 index = 0;
2080 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002081
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002082 u8 op_channel_attr_index = 0;
2083 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002084
2085 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002086 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002087 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002088
2089 break;
2090 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002091
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302092 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002093 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302094 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002095 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002096 index += buf[index + 1] + 3; /* ID,Length byte */
2097 }
2098
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002099 if (u8WLANChannel != INVALID_CHANNEL && bOperChan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002100 {
2101 /*Modify channel list attribute*/
2102 if (channel_list_attr_index) {
2103 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
2104 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
2105 if (buf[i] == 0x51) {
2106 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
2107 buf[j] = u8WLANChannel;
2108 }
2109 break;
2110 }
2111 }
2112 }
2113 /*Modify operating channel attribute*/
2114 if (op_channel_attr_index) {
2115 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
2116 buf[op_channel_attr_index + 6] = 0x51;
2117 buf[op_channel_attr_index + 7] = u8WLANChannel;
2118 }
2119 }
2120}
2121
2122/* @brief WILC_WFI_p2p_rx
2123 * @details
2124 * @param[in]
2125 *
2126 * @return None
2127 * @author Mai Daftedar
2128 * @date 2 JUN 2013
2129 * @version 1.0
2130 */
2131
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09002132void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002133{
2134
Chaehyun Lim27268872015-09-15 14:06:13 +09002135 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002136 u32 header, pkt_offset;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002137 tstrWILC_WFIDrv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002138 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002139 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002140
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002141 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
2142 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2143
2144 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002145 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002146
2147 /* The packet offset field conain info about what type of managment frame */
2148 /* we are dealing with and ack status */
2149 pkt_offset = GET_PKT_OFFSET(header);
2150
2151 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
2152 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
2153 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002154 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002155 return;
2156 } else {
2157 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
2158 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],
2159 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002161 } else {
2162 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],
2163 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002164 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002165 }
2166 return;
2167 }
2168 } else {
2169
2170 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
2171
2172 /*BugID_5442*/
2173 /*Upper layer is informed that the frame is received on this freq*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002174 s32Freq = ieee80211_channel_to_frequency(u8CurrChannel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002175
2176 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
2177 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
2178
Dean Lee72ed4dc2015-06-12 14:11:44 +09002179 if (priv->bCfgScanning == true && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->u64P2p_MgmtTimeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002180 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
2181 return;
2182 }
2183 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2184
2185 switch (buff[ACTION_SUBTYPE_ID]) {
2186 case GAS_INTIAL_REQ:
2187 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
2188 break;
2189
2190 case GAS_INTIAL_RSP:
2191 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
2192 break;
2193
2194 case PUBLIC_ACT_VENDORSPEC:
2195 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2196 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002197 if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002198 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2199 if (!bWilc_ie) {
2200 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002201 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002202 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09002203 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002204 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
2205 break;
2206 }
2207 }
2208 }
2209 }
2210 if (u8P2Plocalrandom > u8P2Precvrandom) {
2211 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2212 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2213 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002214 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002215 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2216 break;
2217 }
2218 }
2219 }
2220 } else
2221 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2222 }
2223
2224
2225 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2226 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2227 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002228 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002229 return;
2230 }
2231 break;
2232
2233 default:
2234 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2235 break;
2236 }
2237 }
2238 }
2239
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002240 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002241 }
2242}
2243
2244/**
2245 * @brief WILC_WFI_mgmt_tx_complete
2246 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2247 * @param[in] priv
2248 * transmitting status
2249 * @return None
2250 * @author Amr Abdelmoghny
2251 * @date 20 MAY 2013
2252 * @version 1.0
2253 */
2254static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2255{
2256 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2257
2258
2259 kfree(pv_data->buff);
2260 kfree(pv_data);
2261}
2262
2263/**
2264 * @brief WILC_WFI_RemainOnChannelReady
2265 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2266 * @param
2267 * @return none
2268 * @author Amr abdelmoghny
2269 * @date 9 JUNE 2013
2270 * @version
2271 */
2272
2273static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2274{
Chaehyun Lim27268872015-09-15 14:06:13 +09002275 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002276
Chaehyun Lim27268872015-09-15 14:06:13 +09002277 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002278
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302279 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002280
Dean Lee72ed4dc2015-06-12 14:11:44 +09002281 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002282
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002283 cfg80211_ready_on_channel(priv->wdev,
2284 priv->strRemainOnChanParams.u64ListenCookie,
2285 priv->strRemainOnChanParams.pstrListenChan,
2286 priv->strRemainOnChanParams.u32ListenDuration,
2287 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002288}
2289
2290/**
2291 * @brief WILC_WFI_RemainOnChannelExpired
2292 * @details Callback function, called on expiration of remain-on-channel duration
2293 * @param
2294 * @return none
2295 * @author Amr abdelmoghny
2296 * @date 15 MAY 2013
2297 * @version
2298 */
2299
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002300static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002301{
Chaehyun Lim27268872015-09-15 14:06:13 +09002302 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002303
Chaehyun Lim27268872015-09-15 14:06:13 +09002304 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002305
2306 /*BugID_5477*/
2307 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302308 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002309
Dean Lee72ed4dc2015-06-12 14:11:44 +09002310 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002311
2312 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002313 cfg80211_remain_on_channel_expired(priv->wdev,
2314 priv->strRemainOnChanParams.u64ListenCookie,
2315 priv->strRemainOnChanParams.pstrListenChan,
2316 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002317 } else {
2318 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2319 , priv->strRemainOnChanParams.u32ListenSessionID);
2320 }
2321}
2322
2323
2324/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002325 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002326 * @details Request the driver to remain awake on the specified
2327 * channel for the specified duration to complete an off-channel
2328 * operation (e.g., public action frame exchange). When the driver is
2329 * ready on the requested channel, it must indicate this with an event
2330 * notification by calling cfg80211_ready_on_channel().
2331 * @param[in]
2332 * @return int : Return 0 on Success
2333 * @author mdaftedar
2334 * @date 01 MAR 2012
2335 * @version 1.0
2336 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002337static int remain_on_channel(struct wiphy *wiphy,
2338 struct wireless_dev *wdev,
2339 struct ieee80211_channel *chan,
2340 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002341{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002342 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09002343 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002344
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002345 priv = wiphy_priv(wiphy);
2346
2347 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2348
2349 /*BugID_4800: if in AP mode, return.*/
2350 /*This check is to handle the situation when user*/
2351 /*requests "create group" during a running scan*/
2352
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002353 if (wdev->iftype == NL80211_IFTYPE_AP) {
2354 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2355 return s32Error;
2356 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002357
2358 u8CurrChannel = chan->hw_value;
2359
2360 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2361 priv->strRemainOnChanParams.pstrListenChan = chan;
2362 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002363 priv->strRemainOnChanParams.u32ListenDuration = duration;
2364 priv->strRemainOnChanParams.u32ListenSessionID++;
2365
2366 s32Error = host_int_remain_on_channel(priv->hWILCWFIDrv
2367 , priv->strRemainOnChanParams.u32ListenSessionID
2368 , duration
2369 , chan->hw_value
2370 , WILC_WFI_RemainOnChannelExpired
2371 , WILC_WFI_RemainOnChannelReady
2372 , (void *)priv);
2373
2374 return s32Error;
2375}
2376
2377/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002378 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002379 * @details Cancel an on-going remain-on-channel operation.
2380 * This allows the operation to be terminated prior to timeout based on
2381 * the duration value.
2382 * @param[in] struct wiphy *wiphy,
2383 * @param[in] struct net_device *dev
2384 * @param[in] u64 cookie,
2385 * @return int : Return 0 on Success
2386 * @author mdaftedar
2387 * @date 01 MAR 2012
2388 * @version 1.0
2389 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002390static int cancel_remain_on_channel(struct wiphy *wiphy,
2391 struct wireless_dev *wdev,
2392 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002394 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09002395 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002396
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002397 priv = wiphy_priv(wiphy);
2398
2399 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2400
2401 s32Error = host_int_ListenStateExpired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
2402 return s32Error;
2403}
2404/**
2405 * @brief WILC_WFI_add_wilcvendorspec
2406 * @details Adding WILC information elemet to allow two WILC devices to
2407 * identify each other and connect
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002408 * @param[in] u8 * buf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002409 * @return void
2410 * @author mdaftedar
2411 * @date 01 JAN 2014
2412 * @version 1.0
2413 */
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002414void WILC_WFI_add_wilcvendorspec(u8 *buff)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002415{
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002416 memcpy(buff, u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002417}
2418/**
2419 * @brief WILC_WFI_mgmt_tx_frame
2420 * @details
2421 *
2422 * @param[in]
2423 * @return NONE.
2424 * @author mdaftedar
2425 * @date 01 JUL 2012
2426 * @version
2427 */
2428extern linux_wlan_t *g_linux_wlan;
Dean Lee72ed4dc2015-06-12 14:11:44 +09002429extern bool bEnablePS;
Chaehyun Lim12a26a32015-09-14 12:24:28 +09002430int mgmt_tx(struct wiphy *wiphy,
2431 struct wireless_dev *wdev,
2432 struct cfg80211_mgmt_tx_params *params,
2433 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002434{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002435 struct ieee80211_channel *chan = params->chan;
2436 unsigned int wait = params->wait;
2437 const u8 *buf = params->buf;
2438 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002439 const struct ieee80211_mgmt *mgmt;
2440 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002441 struct wilc_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002442 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002443 tstrWILC_WFIDrv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002444 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002445 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002446 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002447
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002448 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002449 priv = wiphy_priv(wiphy);
2450 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2451
2452 *cookie = (unsigned long)buf;
2453 priv->u64tx_cookie = *cookie;
2454 mgmt = (const struct ieee80211_mgmt *) buf;
2455
2456 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2457
2458 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002459 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002460 if (mgmt_tx == NULL) {
2461 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
2462 return WILC_FAIL;
2463 }
Glen Leef3052582015-09-10 12:03:04 +09002464 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002465 if (mgmt_tx->buff == NULL) {
2466 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002467 kfree(mgmt_tx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002468 return WILC_FAIL;
2469 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002470 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002471 mgmt_tx->size = len;
2472
2473
2474 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2475 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2476 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
2477 host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
2478 /*Save the current channel after we tune to it*/
2479 u8CurrChannel = chan->hw_value;
2480 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002481 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002482
2483
2484 /*BugID_4847*/
2485 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2486 /*BugID_4847*/
2487 /*Only set the channel, if not a negotiation confirmation frame
2488 * (If Negotiation confirmation frame, force it
2489 * to be transmitted on the same negotiation channel)*/
2490
2491 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2492 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2493 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
2494 host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
2495 /*Save the current channel after we tune to it*/
2496 u8CurrChannel = chan->hw_value;
2497 }
2498 switch (buf[ACTION_SUBTYPE_ID]) {
2499 case GAS_INTIAL_REQ:
2500 {
2501 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2502 break;
2503 }
2504
2505 case GAS_INTIAL_RSP:
2506 {
2507 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2508 break;
2509 }
2510
2511 case PUBLIC_ACT_VENDORSPEC:
2512 {
2513 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2514 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002515 if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002516 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2517 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2518 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2519 get_random_bytes(&u8P2Plocalrandom, 1);
2520 /*Increment the number to prevent if its 0*/
2521 u8P2Plocalrandom++;
2522 }
2523 }
2524
2525 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2526 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2527 if (u8P2Plocalrandom > u8P2Precvrandom) {
2528 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2529
2530 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2531 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002532 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002533 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002534 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002535
2536 /*BugID_5460*/
2537 /*If using supplicant go intent, no need at all*/
2538 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002539 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002540 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002541 break;
2542 }
2543 }
2544
2545 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
2546 WILC_WFI_add_wilcvendorspec(&mgmt_tx->buff[len]);
2547 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2548 mgmt_tx->size = buf_len;
2549 }
2550 } else
2551 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2552 }
2553
2554 } else {
2555 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2556 }
2557
2558 break;
2559 }
2560
2561 default:
2562 {
2563 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2564 break;
2565 }
2566 }
2567
2568 }
2569
2570 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
2571 pstrWFIDrv->u64P2p_MgmtTimeout = (jiffies + msecs_to_jiffies(wait));
2572
2573 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", jiffies, pstrWFIDrv->u64P2p_MgmtTimeout);
2574
2575 }
2576
2577 g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, WILC_WFI_mgmt_tx_complete);
2578 } else {
2579 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2580 }
2581 return s32Error;
2582}
2583
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09002584int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2585 struct wireless_dev *wdev,
2586 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002587{
Chaehyun Lim27268872015-09-15 14:06:13 +09002588 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002589 tstrWILC_WFIDrv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002590
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002591 priv = wiphy_priv(wiphy);
2592 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2593
2594
2595 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
2596 pstrWFIDrv->u64P2p_MgmtTimeout = jiffies;
2597
Dean Lee72ed4dc2015-06-12 14:11:44 +09002598 if (priv->bInP2PlistenState == false) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002599 /* Bug 5504: This is just to avoid connection failure when getting stuck when the supplicant
2600 * considers the driver falsely that it is in Listen state */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002601 cfg80211_remain_on_channel_expired(priv->wdev,
2602 priv->strRemainOnChanParams.u64ListenCookie,
2603 priv->strRemainOnChanParams.pstrListenChan,
2604 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002605 }
2606
2607 return 0;
2608}
2609
2610/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002611 * @brief WILC_WFI_frame_register
2612 * @details Notify driver that a management frame type was
2613 * registered. Note that this callback may not sleep, and cannot run
2614 * concurrently with itself.
2615 * @param[in]
2616 * @return NONE.
2617 * @author mdaftedar
2618 * @date 01 JUL 2012
2619 * @version
2620 */
2621void WILC_WFI_frame_register(struct wiphy *wiphy,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002622 struct wireless_dev *wdev,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002623 u16 frame_type, bool reg)
2624{
2625
Chaehyun Lim27268872015-09-15 14:06:13 +09002626 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002627 perInterface_wlan_t *nic;
2628
2629
2630 priv = wiphy_priv(wiphy);
2631 nic = netdev_priv(priv->wdev->netdev);
2632
2633
2634
2635 /*BugID_5137*/
2636 if (!frame_type)
2637 return;
2638
2639 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2640 switch (frame_type) {
2641 case PROBE_REQ:
2642 {
2643 nic->g_struct_frame_reg[0].frame_type = frame_type;
2644 nic->g_struct_frame_reg[0].reg = reg;
2645 }
2646 break;
2647
2648 case ACTION:
2649 {
2650 nic->g_struct_frame_reg[1].frame_type = frame_type;
2651 nic->g_struct_frame_reg[1].reg = reg;
2652 }
2653 break;
2654
2655 default:
2656 {
2657 break;
2658 }
2659
2660 }
2661 /*If mac is closed, then return*/
2662 if (!g_linux_wlan->wilc1000_initialized) {
2663 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2664 return;
2665 }
2666 host_int_frame_register(priv->hWILCWFIDrv, frame_type, reg);
2667
2668
2669}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002670#endif /*WILC_P2P*/
2671
2672/**
2673 * @brief WILC_WFI_set_cqm_rssi_config
2674 * @details Configure connection quality monitor RSSI threshold.
2675 * @param[in] struct wiphy *wiphy:
2676 * @param[in] struct net_device *dev:
2677 * @param[in] s32 rssi_thold:
2678 * @param[in] u32 rssi_hyst:
2679 * @return int : Return 0 on Success
2680 * @author mdaftedar
2681 * @date 01 MAR 2012
2682 * @version 1.0
2683 */
2684static int WILC_WFI_set_cqm_rssi_config(struct wiphy *wiphy,
2685 struct net_device *dev, s32 rssi_thold, u32 rssi_hyst)
2686{
2687 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2688 return 0;
2689
2690}
2691/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002692 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002693 * @details Configure connection quality monitor RSSI threshold.
2694 * @param[in] struct wiphy *wiphy:
2695 * @param[in] struct net_device *dev
2696 * @param[in] int idx
2697 * @param[in] u8 *mac
2698 * @param[in] struct station_info *sinfo
2699 * @return int : Return 0 on Success
2700 * @author mdaftedar
2701 * @date 01 MAR 2012
2702 * @version 1.0
2703 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002704static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2705 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002706{
Chaehyun Lim27268872015-09-15 14:06:13 +09002707 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002708
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002709 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2710
2711 if (idx != 0)
2712 return -ENOENT;
2713
2714 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002715
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002716 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002717
2718 host_int_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
2719
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002720 return 0;
2721
2722}
2723
2724
2725/**
2726 * @brief WILC_WFI_set_power_mgmt
2727 * @details
2728 * @param[in]
2729 * @return int : Return 0 on Success.
2730 * @author mdaftedar
2731 * @date 01 JUL 2012
2732 * @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
2733 */
2734int WILC_WFI_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2735 bool enabled, int timeout)
2736{
Chaehyun Lim27268872015-09-15 14:06:13 +09002737 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002738
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002739 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2740
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002741 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002742 return -ENOENT;
2743
2744 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002745 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002746 PRINT_ER("Driver is NULL\n");
2747 return -EIO;
2748 }
2749
Abdul Hussain5a66bf22015-06-16 09:44:06 +00002750 if (bEnablePS)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002751 host_int_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
2752
2753
2754 return WILC_SUCCESS;
2755
2756}
2757#ifdef WILC_AP_EXTERNAL_MLME
2758/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002759 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002760 * @details Change type/configuration of virtual interface,
2761 * keep the struct wireless_dev's iftype updated.
2762 * @param[in] NONE
2763 * @return int : Return 0 on Success.
2764 * @author mdaftedar
2765 * @date 01 MAR 2012
2766 * @version 1.0
2767 */
2768void wilc1000_wlan_deinit(linux_wlan_t *nic);
2769int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic);
2770
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002771static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2772 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002773{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09002774 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09002775 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002776 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002777 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002778 u16 TID = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002779 #ifdef WILC_P2P
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002780 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002781 #endif
2782
2783 nic = netdev_priv(dev);
2784 priv = wiphy_priv(wiphy);
2785
2786 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2787 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2788 u8P2Plocalrandom = 0x01;
2789 u8P2Precvrandom = 0x00;
2790
Dean Lee72ed4dc2015-06-12 14:11:44 +09002791 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002792
2793 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Dean Lee72ed4dc2015-06-12 14:11:44 +09002794 g_obtainingIP = false;
Greg Kroah-Hartman8972d0f2015-08-14 20:04:13 -07002795 del_timer(&hDuringIpTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002796 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
2797 #endif
2798 /*BugID_5137*/
2799 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2800 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09002801 Set_machw_change_vir_if(true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002802 }
2803
2804 switch (type) {
2805 case NL80211_IFTYPE_STATION:
2806 connecting = 0;
2807 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002808
2809 /* send delba over wlan interface */
2810
2811
2812 dev->ieee80211_ptr->iftype = type;
2813 priv->wdev->iftype = type;
2814 nic->monitor_flag = 0;
2815 nic->iftype = STATION_MODE;
2816
2817 /*Remove the enteries of the previously connected clients*/
2818 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002819 #ifdef WILC_P2P
2820 interface_type = nic->iftype;
2821 nic->iftype = STATION_MODE;
2822
2823 if (g_linux_wlan->wilc1000_initialized) {
2824 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
2825 /* ensure that the message Q is empty */
2826 host_int_wait_msg_queue_idle();
2827
2828 /*BugID_5213*/
2829 /*Eliminate host interface blocking state*/
Greg Kroah-Hartman8990d852015-09-03 20:07:58 -07002830 up(&g_linux_wlan->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002831
2832 wilc1000_wlan_deinit(g_linux_wlan);
2833 wilc1000_wlan_init(dev, nic);
2834 g_wilc_initialized = 1;
2835 nic->iftype = interface_type;
2836
2837 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
2838 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
Johnny Kim218dc402015-08-13 13:41:19 +09002839 host_int_set_MacAddress(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002840 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
2841 host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
2842
2843 /*Add saved WEP keys, if any*/
2844 if (g_wep_keys_saved) {
Johnny Kim218dc402015-08-13 13:41:19 +09002845 host_int_set_WEPDefaultKeyID(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002846 g_key_wep_params.key_idx);
Johnny Kim218dc402015-08-13 13:41:19 +09002847 host_int_add_wep_key_bss_sta(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002848 g_key_wep_params.key,
2849 g_key_wep_params.key_len,
2850 g_key_wep_params.key_idx);
2851 }
2852
2853 /*No matter the driver handler passed here, it will be overwriiten*/
2854 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2855 host_int_flush_join_req(priv->hWILCWFIDrv);
2856
2857 /*Add saved PTK and GTK keys, if any*/
2858 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2859 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2860 g_key_ptk_params.key[1],
2861 g_key_ptk_params.key[2]);
2862 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2863 g_key_gtk_params.key[1],
2864 g_key_gtk_params.key[2]);
Chaehyun Lim953d4172015-09-14 12:24:05 +09002865 add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
2866 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
2867 g_add_ptk_key_params.key_idx,
2868 g_add_ptk_key_params.pairwise,
2869 g_add_ptk_key_params.mac_addr,
2870 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002871
Chaehyun Lim953d4172015-09-14 12:24:05 +09002872 add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
2873 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
2874 g_add_gtk_key_params.key_idx,
2875 g_add_gtk_key_params.pairwise,
2876 g_add_gtk_key_params.mac_addr,
2877 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002878 }
2879
2880 /*BugID_4847: registered frames in firmware are now*/
2881 /*lost due to mac close. So re-register those frames*/
2882 if (g_linux_wlan->wilc1000_initialized) {
2883 for (i = 0; i < num_reg_frame; i++) {
2884 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2885 nic->g_struct_frame_reg[i].reg);
2886 host_int_frame_register(priv->hWILCWFIDrv,
2887 nic->g_struct_frame_reg[i].frame_type,
2888 nic->g_struct_frame_reg[i].reg);
2889 }
2890 }
2891
Dean Lee72ed4dc2015-06-12 14:11:44 +09002892 bEnablePS = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002893 host_int_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
2894 }
2895 #endif
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002896 break;
2897
2898 case NL80211_IFTYPE_P2P_CLIENT:
Dean Lee72ed4dc2015-06-12 14:11:44 +09002899 bEnablePS = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002900 host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2901 connecting = 0;
2902 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002903
2904 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
2905
2906 dev->ieee80211_ptr->iftype = type;
2907 priv->wdev->iftype = type;
2908 nic->monitor_flag = 0;
2909
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002910 #ifdef WILC_P2P
2911
2912 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2913 nic->iftype = CLIENT_MODE;
2914
2915
2916 if (g_linux_wlan->wilc1000_initialized) {
2917 /* ensure that the message Q is empty */
2918 host_int_wait_msg_queue_idle();
2919
2920 wilc1000_wlan_deinit(g_linux_wlan);
2921 wilc1000_wlan_init(dev, nic);
2922 g_wilc_initialized = 1;
2923
2924 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
Johnny Kim218dc402015-08-13 13:41:19 +09002925 host_int_set_MacAddress(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002926 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
2927 host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
2928
2929 /*Add saved WEP keys, if any*/
2930 if (g_wep_keys_saved) {
Johnny Kim218dc402015-08-13 13:41:19 +09002931 host_int_set_WEPDefaultKeyID(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002932 g_key_wep_params.key_idx);
Johnny Kim218dc402015-08-13 13:41:19 +09002933 host_int_add_wep_key_bss_sta(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002934 g_key_wep_params.key,
2935 g_key_wep_params.key_len,
2936 g_key_wep_params.key_idx);
2937 }
2938
2939 /*No matter the driver handler passed here, it will be overwriiten*/
2940 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
2941 host_int_flush_join_req(priv->hWILCWFIDrv);
2942
2943 /*Add saved PTK and GTK keys, if any*/
2944 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2945 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2946 g_key_ptk_params.key[1],
2947 g_key_ptk_params.key[2]);
2948 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2949 g_key_gtk_params.key[1],
2950 g_key_gtk_params.key[2]);
Chaehyun Lim953d4172015-09-14 12:24:05 +09002951 add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
2952 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
2953 g_add_ptk_key_params.key_idx,
2954 g_add_ptk_key_params.pairwise,
2955 g_add_ptk_key_params.mac_addr,
2956 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002957
Chaehyun Lim953d4172015-09-14 12:24:05 +09002958 add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
2959 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
2960 g_add_gtk_key_params.key_idx,
2961 g_add_gtk_key_params.pairwise,
2962 g_add_gtk_key_params.mac_addr,
2963 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002964 }
2965
2966 /*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 +09002967 refresh_scan(priv, 1, true);
2968 Set_machw_change_vir_if(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002969
2970 /*BugID_4847: registered frames in firmware are now lost
2971 * due to mac close. So re-register those frames */
2972 if (g_linux_wlan->wilc1000_initialized) {
2973 for (i = 0; i < num_reg_frame; i++) {
2974 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2975 nic->g_struct_frame_reg[i].reg);
2976 host_int_frame_register(priv->hWILCWFIDrv,
2977 nic->g_struct_frame_reg[i].frame_type,
2978 nic->g_struct_frame_reg[i].reg);
2979 }
2980 }
2981 }
2982 #endif
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002983 break;
2984
2985 case NL80211_IFTYPE_AP:
Dean Lee72ed4dc2015-06-12 14:11:44 +09002986 bEnablePS = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002987 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002988 dev->ieee80211_ptr->iftype = type;
2989 priv->wdev->iftype = type;
2990 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002991 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002992
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002993 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
2994 linux_wlan_get_firmware(nic);
2995 #ifdef WILC_P2P
2996 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
2997 if (g_linux_wlan->wilc1000_initialized) {
2998 nic->iftype = AP_MODE;
2999 g_linux_wlan->wilc1000_initialized = 1;
3000 mac_close(dev);
3001 mac_open(dev);
3002
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003003 /*BugID_4847: registered frames in firmware are now lost
3004 * due to mac close. So re-register those frames */
3005 for (i = 0; i < num_reg_frame; i++) {
3006 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3007 nic->g_struct_frame_reg[i].reg);
3008 host_int_frame_register(priv->hWILCWFIDrv,
3009 nic->g_struct_frame_reg[i].frame_type,
3010 nic->g_struct_frame_reg[i].reg);
3011 }
3012 }
3013 #endif
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003014 break;
3015
3016 case NL80211_IFTYPE_P2P_GO:
3017 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
3018
3019 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Dean Lee72ed4dc2015-06-12 14:11:44 +09003020 g_obtainingIP = true;
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -07003021 mod_timer(&hDuringIpTimer, jiffies + msecs_to_jiffies(duringIP_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003022 #endif
3023 host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
3024 /*BugID_5222*/
3025 /*Delete block ack has to be the latest config packet*/
3026 /*sent before downloading new FW. This is because it blocks on*/
3027 /*hWaitResponse semaphore, which allows previous config*/
3028 /*packets to actually take action on old FW*/
3029 host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID);
Dean Lee72ed4dc2015-06-12 14:11:44 +09003030 bEnablePS = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003031 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003032 dev->ieee80211_ptr->iftype = type;
3033 priv->wdev->iftype = type;
3034
Johnny Kim8a143302015-06-10 17:06:46 +09003035 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003036
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003037 #ifdef WILC_P2P
3038 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
3039
3040
3041 #if 1
3042 nic->iftype = GO_MODE;
3043
3044 /* ensure that the message Q is empty */
3045 host_int_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003046 wilc1000_wlan_deinit(g_linux_wlan);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003047 wilc1000_wlan_init(dev, nic);
3048 g_wilc_initialized = 1;
3049
3050
3051 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
3052 host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
Johnny Kim218dc402015-08-13 13:41:19 +09003053 host_int_set_MacAddress(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003054 g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3055 host_int_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
3056
3057 /*Add saved WEP keys, if any*/
3058 if (g_wep_keys_saved) {
Johnny Kim218dc402015-08-13 13:41:19 +09003059 host_int_set_WEPDefaultKeyID(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003060 g_key_wep_params.key_idx);
Johnny Kim218dc402015-08-13 13:41:19 +09003061 host_int_add_wep_key_bss_sta(g_linux_wlan->strInterfaceInfo[0].drvHandler,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003062 g_key_wep_params.key,
3063 g_key_wep_params.key_len,
3064 g_key_wep_params.key_idx);
3065 }
3066
3067 /*No matter the driver handler passed here, it will be overwriiten*/
3068 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
3069 host_int_flush_join_req(priv->hWILCWFIDrv);
3070
3071 /*Add saved PTK and GTK keys, if any*/
3072 if (g_ptk_keys_saved && g_gtk_keys_saved) {
3073 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
3074 g_key_ptk_params.key[1],
3075 g_key_ptk_params.key[2],
3076 g_key_ptk_params.cipher);
3077 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
3078 g_key_gtk_params.key[1],
3079 g_key_gtk_params.key[2],
3080 g_key_gtk_params.cipher);
3081 #if 1
Chaehyun Lim953d4172015-09-14 12:24:05 +09003082 add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3083 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3084 g_add_ptk_key_params.key_idx,
3085 g_add_ptk_key_params.pairwise,
3086 g_add_ptk_key_params.mac_addr,
3087 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003088
Chaehyun Lim953d4172015-09-14 12:24:05 +09003089 add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy,
3090 g_linux_wlan->strInterfaceInfo[0].wilc_netdev,
3091 g_add_gtk_key_params.key_idx,
3092 g_add_gtk_key_params.pairwise,
3093 g_add_gtk_key_params.mac_addr,
3094 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003095 #endif
3096 }
3097 #endif
3098
3099 /*BugID_4847: registered frames in firmware are now*/
3100 /*lost due to mac close. So re-register those frames*/
3101 if (g_linux_wlan->wilc1000_initialized) {
3102 for (i = 0; i < num_reg_frame; i++) {
3103 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
3104 nic->g_struct_frame_reg[i].reg);
3105 host_int_frame_register(priv->hWILCWFIDrv,
3106 nic->g_struct_frame_reg[i].frame_type,
3107 nic->g_struct_frame_reg[i].reg);
3108 }
3109 }
3110 #endif
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003111 break;
3112
3113 default:
3114 PRINT_ER("Unknown interface type= %d\n", type);
3115 s32Error = -EINVAL;
3116 return s32Error;
3117 break;
3118 }
3119
3120 return s32Error;
3121}
3122
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003123/* (austin.2013-07-23)
3124 *
3125 * To support revised cfg80211_ops
3126 *
3127 * add_beacon --> start_ap
3128 * set_beacon --> change_beacon
3129 * del_beacon --> stop_ap
3130 *
3131 * beacon_parameters --> cfg80211_ap_settings
3132 * cfg80211_beacon_data
3133 *
3134 * applicable for linux kernel 3.4+
3135 */
3136
3137/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09003138 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003139 * @details Add a beacon with given parameters, @head, @interval
3140 * and @dtim_period will be valid, @tail is optional.
3141 * @param[in] wiphy
3142 * @param[in] dev The net device structure
3143 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
3144 * @return int : Return 0 on Success.
3145 * @author austin
3146 * @date 23 JUL 2013
3147 * @version 1.0
3148 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09003149static int start_ap(struct wiphy *wiphy, struct net_device *dev,
3150 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003151{
3152 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09003153 struct wilc_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003154 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003155
3156 priv = wiphy_priv(wiphy);
3157 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
3158
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303159 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 +09003160 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
3161
Chaehyun Lim80785a92015-09-14 12:24:01 +09003162 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003163
3164 if (s32Error != WILC_SUCCESS)
3165 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003166
3167 linux_wlan_set_bssid(dev, g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
3168
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003169 s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
3170 settings->beacon_interval,
3171 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003172 beacon->head_len, (u8 *)beacon->head,
3173 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003174
3175 return s32Error;
3176}
3177
3178/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003179 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003180 * @details Add a beacon with given parameters, @head, @interval
3181 * and @dtim_period will be valid, @tail is optional.
3182 * @param[in] wiphy
3183 * @param[in] dev The net device structure
3184 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
3185 * @return int : Return 0 on Success.
3186 * @author austin
3187 * @date 23 JUL 2013
3188 * @version 1.0
3189 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003190static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
3191 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003192{
Chaehyun Lim27268872015-09-15 14:06:13 +09003193 struct wilc_priv *priv;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003194 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003195
3196 priv = wiphy_priv(wiphy);
3197 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
3198
3199
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003200 s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
3201 0,
3202 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003203 beacon->head_len, (u8 *)beacon->head,
3204 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003205
3206 return s32Error;
3207}
3208
3209/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003210 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003211 * @details Remove beacon configuration and stop sending the beacon.
3212 * @param[in]
3213 * @return int : Return 0 on Success.
3214 * @author austin
3215 * @date 23 JUL 2013
3216 * @version 1.0
3217 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003218static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003219{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003220 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09003221 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003222 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003223
Leo Kim7ae43362015-09-16 18:35:59 +09003224 if (!wiphy)
3225 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003226
3227 priv = wiphy_priv(wiphy);
3228
3229 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
3230
3231 /*BugID_5188*/
3232 linux_wlan_set_bssid(dev, NullBssid);
3233
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003234 s32Error = host_int_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003235
3236 WILC_ERRORCHECK(s32Error);
3237
3238 WILC_CATCH(s32Error)
3239 {
3240 }
3241 return s32Error;
3242}
3243
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003244/**
Chaehyun Limed269552015-09-14 12:24:15 +09003245 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003246 * @details Add a new station.
3247 * @param[in]
3248 * @return int : Return 0 on Success.
3249 * @author mdaftedar
3250 * @date 01 MAR 2012
3251 * @version 1.0
3252 */
Chaehyun Limed269552015-09-14 12:24:15 +09003253static int add_station(struct wiphy *wiphy, struct net_device *dev,
3254 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003255{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003256 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09003257 struct wilc_priv *priv;
Chandra S Gorentlaa2b40412015-08-08 17:41:33 +05303258 tstrWILC_AddStaParam strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003259 perInterface_wlan_t *nic;
3260
Leo Kim7ae43362015-09-16 18:35:59 +09003261 if (!wiphy)
3262 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003263
3264 priv = wiphy_priv(wiphy);
3265 nic = netdev_priv(dev);
3266
3267 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003268 memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
3269 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003270 strStaParams.u16AssocID = params->aid;
3271 strStaParams.u8NumRates = params->supported_rates_len;
3272 strStaParams.pu8Rates = params->supported_rates;
3273
3274 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3275
3276 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],
3277 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
3278 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID);
3279 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates);
3280
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003281 if (params->ht_capa == NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09003282 strStaParams.bIsHTSupported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003283 } else {
Dean Lee72ed4dc2015-06-12 14:11:44 +09003284 strStaParams.bIsHTSupported = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003285 strStaParams.u16HTCapInfo = params->ht_capa->cap_info;
3286 strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003287 memcpy(strStaParams.au8SuppMCsSet, &params->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003288 strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info;
3289 strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info;
3290 strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info;
3291 }
3292
3293 strStaParams.u16FlagsMask = params->sta_flags_mask;
3294 strStaParams.u16FlagsSet = params->sta_flags_set;
3295
3296 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported);
3297 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo);
3298 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams);
3299 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams);
3300 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap);
3301 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap);
3302 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask);
3303 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet);
3304
3305 s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams);
3306 WILC_ERRORCHECK(s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003307 }
3308
3309 WILC_CATCH(s32Error)
3310 {
3311 }
3312 return s32Error;
3313}
3314
3315/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003316 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003317 * @details Remove a station; @mac may be NULL to remove all stations.
3318 * @param[in]
3319 * @return int : Return 0 on Success.
3320 * @author mdaftedar
3321 * @date 01 MAR 2012
3322 * @version 1.0
3323 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003324static int del_station(struct wiphy *wiphy, struct net_device *dev,
3325 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003326{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003327 const u8 *mac = params->mac;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003328 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09003329 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003330 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003331
Leo Kim7ae43362015-09-16 18:35:59 +09003332 if (!wiphy)
3333 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003334
3335 priv = wiphy_priv(wiphy);
3336 nic = netdev_priv(dev);
3337
3338 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3339 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3340
3341
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003342 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303343 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003344 s32Error = host_int_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
3345 } else {
3346 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]);
3347 }
3348
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003349 s32Error = host_int_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003350
3351 WILC_ERRORCHECK(s32Error);
3352 }
3353 WILC_CATCH(s32Error)
3354 {
3355 }
3356 return s32Error;
3357}
3358
3359/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003360 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003361 * @details Modify a given station.
3362 * @param[in]
3363 * @return int : Return 0 on Success.
3364 * @author mdaftedar
3365 * @date 01 MAR 2012
3366 * @version 1.0
3367 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003368static int change_station(struct wiphy *wiphy, struct net_device *dev,
3369 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003370{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003371 s32 s32Error = WILC_SUCCESS;
Chaehyun Lim27268872015-09-15 14:06:13 +09003372 struct wilc_priv *priv;
Chandra S Gorentlaa2b40412015-08-08 17:41:33 +05303373 tstrWILC_AddStaParam strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003374 perInterface_wlan_t *nic;
3375
3376
3377 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3378
Leo Kim7ae43362015-09-16 18:35:59 +09003379 if (!wiphy)
3380 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003381
3382 priv = wiphy_priv(wiphy);
3383 nic = netdev_priv(dev);
3384
3385 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003386 memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003387 strStaParams.u16AssocID = params->aid;
3388 strStaParams.u8NumRates = params->supported_rates_len;
3389 strStaParams.pu8Rates = params->supported_rates;
3390
3391 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],
3392 strStaParams.au8BSSID[5]);
3393 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID);
3394 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates);
3395
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003396 if (params->ht_capa == NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09003397 strStaParams.bIsHTSupported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003398 } else {
Dean Lee72ed4dc2015-06-12 14:11:44 +09003399 strStaParams.bIsHTSupported = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003400 strStaParams.u16HTCapInfo = params->ht_capa->cap_info;
3401 strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003402 memcpy(strStaParams.au8SuppMCsSet, &params->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003403 strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info;
3404 strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info;
3405 strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info;
3406
3407 }
3408
3409 strStaParams.u16FlagsMask = params->sta_flags_mask;
3410 strStaParams.u16FlagsSet = params->sta_flags_set;
3411
3412 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported);
3413 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo);
3414 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams);
3415 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams);
3416 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap);
3417 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap);
3418 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask);
3419 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet);
3420
3421 s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams);
3422 WILC_ERRORCHECK(s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003423 }
3424 WILC_CATCH(s32Error)
3425 {
3426 }
3427 return s32Error;
3428}
3429
3430
3431/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003432 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003433 * @details
3434 * @param[in]
3435 * @return int : Return 0 on Success.
3436 * @author mdaftedar
3437 * @date 01 JUL 2012
3438 * @version 1.0
3439 */
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003440struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, const char *name,
3441 unsigned char name_assign_type,
3442 enum nl80211_iftype type, u32 *flags,
3443 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003444{
3445 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003446 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003447 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003448
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003449 priv = wiphy_priv(wiphy);
3450
3451
3452
3453 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3454
3455 nic = netdev_priv(priv->wdev->netdev);
3456
3457
3458 if (type == NL80211_IFTYPE_MONITOR) {
3459 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3460 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3461 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3462 if (new_ifc != NULL) {
3463 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003464 nic = netdev_priv(priv->wdev->netdev);
3465 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003466 } else
3467 PRINT_ER("Error in initializing monitor interface\n ");
3468 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003469 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003470}
3471
3472/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003473 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003474 * @details
3475 * @param[in]
3476 * @return int : Return 0 on Success.
3477 * @author mdaftedar
3478 * @date 01 JUL 2012
3479 * @version 1.0
3480 */
Chaehyun Limb4a73352015-09-14 12:24:10 +09003481int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) /* tony for v3.8 support */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003482{
3483 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
3484 return WILC_SUCCESS;
3485}
3486
3487
3488
3489#endif /*WILC_AP_EXTERNAL_MLME*/
Chaehyun Lim08241922015-09-15 14:06:12 +09003490static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003491
Chaehyun Lim80785a92015-09-14 12:24:01 +09003492 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003493 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003494 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003495 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003496 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003497 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003498 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003499 .set_default_key = set_default_key,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003500 #ifdef WILC_AP_EXTERNAL_MLME
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003501 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003502 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003503 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003504
Chaehyun Lima13168d2015-09-14 12:24:12 +09003505 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003506 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003507 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003508 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003509 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003510 .change_station = change_station,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003511 #endif /* WILC_AP_EXTERNAL_MLME*/
Chaehyun Limf06f5622015-09-14 12:24:18 +09003512 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003513 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003514 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003515 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003516
Chaehyun Lim4d466572015-09-14 12:24:22 +09003517 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003518 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003519 .flush_pmksa = flush_pmksa,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003520#ifdef WILC_P2P
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003521 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003522 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003523 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003524 .mgmt_tx = mgmt_tx,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003525 .mgmt_frame_register = WILC_WFI_frame_register,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003526 .set_power_mgmt = WILC_WFI_set_power_mgmt,
3527 .set_cqm_rssi_config = WILC_WFI_set_cqm_rssi_config,
3528#endif
3529
3530};
3531
3532
3533
3534
3535
3536/**
3537 * @brief WILC_WFI_update_stats
3538 * @details Modify parameters for a given BSS.
3539 * @param[in]
3540 * @return int : Return 0 on Success.
3541 * @author mdaftedar
3542 * @date 01 MAR 2012
3543 * @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
3544 */
3545int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3546{
3547
Chaehyun Lim27268872015-09-15 14:06:13 +09003548 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003549
3550 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003551#if 1
3552 switch (changed) {
3553
3554 case WILC_WFI_RX_PKT:
3555 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003556 priv->netstats.rx_packets++;
3557 priv->netstats.rx_bytes += pktlen;
3558 priv->netstats.rx_time = get_jiffies_64();
3559 }
3560 break;
3561
3562 case WILC_WFI_TX_PKT:
3563 {
3564 priv->netstats.tx_packets++;
3565 priv->netstats.tx_bytes += pktlen;
3566 priv->netstats.tx_time = get_jiffies_64();
3567
3568 }
3569 break;
3570
3571 default:
3572 break;
3573 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003574#endif
3575 return 0;
3576}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003577
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003578/**
3579 * @brief WILC_WFI_CfgAlloc
3580 * @details Allocation of the wireless device structure and assigning it
3581 * to the cfg80211 operations structure.
3582 * @param[in] NONE
3583 * @return wireless_dev : Returns pointer to wireless_dev structure.
3584 * @author mdaftedar
3585 * @date 01 MAR 2012
3586 * @version 1.0
3587 */
3588struct wireless_dev *WILC_WFI_CfgAlloc(void)
3589{
3590
3591 struct wireless_dev *wdev;
3592
3593
3594 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3595 /*Allocating the wireless device structure*/
3596 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3597 if (!wdev) {
3598 PRINT_ER("Cannot allocate wireless device\n");
3599 goto _fail_;
3600 }
3601
3602 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003603 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003604 if (!wdev->wiphy) {
3605 PRINT_ER("Cannot allocate wiphy\n");
3606 goto _fail_mem_;
3607
3608 }
3609
3610 #ifdef WILC_AP_EXTERNAL_MLME
3611 /* enable 802.11n HT */
3612 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3613 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3614 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3615 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3616 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
3617 #endif
3618
3619 /*wiphy bands*/
3620 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3621
3622 return wdev;
3623
3624_fail_mem_:
3625 kfree(wdev);
3626_fail_:
3627 return NULL;
3628
3629}
3630/**
3631 * @brief WILC_WFI_WiphyRegister
3632 * @details Registering of the wiphy structure and interface modes
3633 * @param[in] NONE
3634 * @return NONE
3635 * @author mdaftedar
3636 * @date 01 MAR 2012
3637 * @version 1.0
3638 */
3639struct wireless_dev *WILC_WFI_WiphyRegister(struct net_device *net)
3640{
Chaehyun Lim27268872015-09-15 14:06:13 +09003641 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003642 struct wireless_dev *wdev;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003643 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003644
3645 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3646
3647 wdev = WILC_WFI_CfgAlloc();
3648 if (wdev == NULL) {
3649 PRINT_ER("CfgAlloc Failed\n");
3650 return NULL;
3651 }
3652
3653
3654 /*Return hardware description structure (wiphy)'s priv*/
3655 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003656 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003657
3658 /*Link the wiphy with wireless structure*/
3659 priv->wdev = wdev;
3660
3661 /*Maximum number of probed ssid to be added by user for the scan request*/
3662 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003663 /*Maximum number of pmkids to be cashed*/
3664 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3665 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003666
3667 wdev->wiphy->max_scan_ie_len = 1000;
3668
3669 /*signal strength in mBm (100*dBm) */
3670 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3671
3672 /*Set the availaible cipher suites*/
3673 wdev->wiphy->cipher_suites = cipher_suites;
3674 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003675 /*Setting default managment types: for register action frame: */
3676 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003677
3678#ifdef WILC_P2P
3679 wdev->wiphy->max_remain_on_channel_duration = 500;
3680 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3681 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3682 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003683 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003684#else
3685 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
3686#endif
3687 wdev->iftype = NL80211_IFTYPE_STATION;
3688
3689
3690
3691 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3692 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3693 wdev->wiphy->interface_modes, wdev->iftype);
3694
3695 #ifdef WILC_SDIO
3696 set_wiphy_dev(wdev->wiphy, &local_sdio_func->dev); /* tony */
3697 #endif
3698
3699 /*Register wiphy structure*/
3700 s32Error = wiphy_register(wdev->wiphy);
3701 if (s32Error) {
3702 PRINT_ER("Cannot register wiphy device\n");
3703 /*should define what action to be taken in such failure*/
3704 } else {
3705 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3706 }
3707
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003708 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003709 return wdev;
3710
3711
3712}
3713/**
3714 * @brief WILC_WFI_WiphyFree
3715 * @details Freeing allocation of the wireless device structure
3716 * @param[in] NONE
3717 * @return NONE
3718 * @author mdaftedar
3719 * @date 01 MAR 2012
3720 * @version 1.0
3721 */
3722int WILC_WFI_InitHostInt(struct net_device *net)
3723{
3724
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003725 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003726
Chaehyun Lim27268872015-09-15 14:06:13 +09003727 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003728
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003729 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3730 priv = wdev_priv(net->ieee80211_ptr);
3731 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003732 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003733 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003734 setup_timer(&hDuringIpTimer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003735 #endif
3736 }
3737 op_ifcs++;
3738 if (s32Error < 0) {
3739 PRINT_ER("Failed to creat refresh Timer\n");
3740 return s32Error;
3741 }
3742
Dean Lee72ed4dc2015-06-12 14:11:44 +09003743 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003744
Dean Lee72ed4dc2015-06-12 14:11:44 +09003745 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003746
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003747 sema_init(&(priv->hSemScanReq), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003748 s32Error = host_int_init(&priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003749 if (s32Error) {
3750 PRINT_ER("Error while initializing hostinterface\n");
3751 }
3752 return s32Error;
3753}
3754
3755/**
3756 * @brief WILC_WFI_WiphyFree
3757 * @details Freeing allocation of the wireless device structure
3758 * @param[in] NONE
3759 * @return NONE
3760 * @author mdaftedar
3761 * @date 01 MAR 2012
3762 * @version 1.0
3763 */
3764int WILC_WFI_DeInitHostInt(struct net_device *net)
3765{
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09003766 s32 s32Error = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003767
Chaehyun Lim27268872015-09-15 14:06:13 +09003768 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003769
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003770 priv = wdev_priv(net->ieee80211_ptr);
3771
Dean Lee72ed4dc2015-06-12 14:11:44 +09003772 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003773
Dean Lee72ed4dc2015-06-12 14:11:44 +09003774 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003775
3776 op_ifcs--;
3777
3778 s32Error = host_int_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003779
3780 /* Clear the Shadow scan */
3781 clear_shadow_scan(priv);
3782 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
3783 if (op_ifcs == 0) {
3784 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -07003785 del_timer_sync(&hDuringIpTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003786 }
3787 #endif
3788
3789 if (s32Error) {
3790 PRINT_ER("Error while deintializing host interface\n");
3791 }
3792 return s32Error;
3793}
3794
3795
3796/**
3797 * @brief WILC_WFI_WiphyFree
3798 * @details Freeing allocation of the wireless device structure
3799 * @param[in] NONE
3800 * @return NONE
3801 * @author mdaftedar
3802 * @date 01 MAR 2012
3803 * @version 1.0
3804 */
3805void WILC_WFI_WiphyFree(struct net_device *net)
3806{
3807
3808 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3809
3810 if (net == NULL) {
3811 PRINT_D(INIT_DBG, "net_device is NULL\n");
3812 return;
3813 }
3814
3815 if (net->ieee80211_ptr == NULL) {
3816 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3817 return;
3818 }
3819
3820 if (net->ieee80211_ptr->wiphy == NULL) {
3821 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3822 return;
3823 }
3824
3825 wiphy_unregister(net->ieee80211_ptr->wiphy);
3826
3827 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3828 wiphy_free(net->ieee80211_ptr->wiphy);
3829 kfree(net->ieee80211_ptr);
3830
3831}