blob: f8fd7a895d449444e45cdd75ef4e9b5f3cb84ddc [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"
Johnny Kimc5c77ba2015-05-11 14:30:56 +090014#ifdef WILC_SDIO
Chaehyun Limcdc9cba2015-09-22 18:34:47 +090015#include "linux_wlan_sdio.h"
Johnny Kimc5c77ba2015-05-11 14:30:56 +090016#endif
Leo Kim7ae43362015-09-16 18:35:59 +090017#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +090018
19#define IS_MANAGMEMENT 0x100
20#define IS_MANAGMEMENT_CALLBACK 0x080
21#define IS_MGMT_STATUS_SUCCES 0x040
22#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
23
Arnd Bergmann0e1af732015-11-16 15:04:54 +010024extern int wilc_mac_open(struct net_device *ndev);
25extern int wilc_mac_close(struct net_device *ndev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090026
Arnd Bergmann1608c402015-11-16 15:04:53 +010027static tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
28static u32 u32LastScannedNtwrksCountShadow;
Arnd Bergmann0e1af732015-11-16 15:04:54 +010029struct timer_list wilc_during_ip_timer;
Arnd Bergmann1608c402015-11-16 15:04:53 +010030static struct timer_list hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +090031static u8 op_ifcs;
Arnd Bergmann0e1af732015-11-16 15:04:54 +010032extern u8 wilc_connected_SSID[6];
Johnny Kimc5c77ba2015-05-11 14:30:56 +090033
Arnd Bergmann0e1af732015-11-16 15:04:54 +010034u8 wilc_initialized = 1;
35extern bool wilc_optaining_ip;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090036
37#define CHAN2G(_channel, _freq, _flags) { \
38 .band = IEEE80211_BAND_2GHZ, \
39 .center_freq = (_freq), \
40 .hw_value = (_channel), \
41 .flags = (_flags), \
42 .max_antenna_gain = 0, \
43 .max_power = 30, \
44}
45
46/*Frequency range for channels*/
47static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
48 CHAN2G(1, 2412, 0),
49 CHAN2G(2, 2417, 0),
50 CHAN2G(3, 2422, 0),
51 CHAN2G(4, 2427, 0),
52 CHAN2G(5, 2432, 0),
53 CHAN2G(6, 2437, 0),
54 CHAN2G(7, 2442, 0),
55 CHAN2G(8, 2447, 0),
56 CHAN2G(9, 2452, 0),
57 CHAN2G(10, 2457, 0),
58 CHAN2G(11, 2462, 0),
59 CHAN2G(12, 2467, 0),
60 CHAN2G(13, 2472, 0),
61 CHAN2G(14, 2484, 0),
62};
63
64#define RATETAB_ENT(_rate, _hw_value, _flags) { \
65 .bitrate = (_rate), \
66 .hw_value = (_hw_value), \
67 .flags = (_flags), \
68}
69
70
71/* Table 6 in section 3.2.1.1 */
72static struct ieee80211_rate WILC_WFI_rates[] = {
73 RATETAB_ENT(10, 0, 0),
74 RATETAB_ENT(20, 1, 0),
75 RATETAB_ENT(55, 2, 0),
76 RATETAB_ENT(110, 3, 0),
77 RATETAB_ENT(60, 9, 0),
78 RATETAB_ENT(90, 6, 0),
79 RATETAB_ENT(120, 7, 0),
80 RATETAB_ENT(180, 8, 0),
81 RATETAB_ENT(240, 9, 0),
82 RATETAB_ENT(360, 10, 0),
83 RATETAB_ENT(480, 11, 0),
84 RATETAB_ENT(540, 12, 0),
85};
86
Johnny Kimc5c77ba2015-05-11 14:30:56 +090087struct p2p_mgmt_data {
88 int size;
89 u8 *buff;
90};
91
92/*Global variable used to state the current connected STA channel*/
Arnd Bergmann1608c402015-11-16 15:04:53 +010093static u8 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090094
Arnd Bergmann1608c402015-11-16 15:04:53 +010095static u8 curr_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090096
Arnd Bergmann1608c402015-11-16 15:04:53 +010097static u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
98static u8 u8P2Plocalrandom = 0x01;
99static u8 u8P2Precvrandom = 0x00;
100static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
101static bool bWilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900102
103static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
104 .channels = WILC_WFI_2ghz_channels,
105 .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels),
106 .bitrates = WILC_WFI_rates,
107 .n_bitrates = ARRAY_SIZE(WILC_WFI_rates),
108};
109
110
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900111struct add_key_params {
112 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900113 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900114 u8 *mac_addr;
115};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100116static struct add_key_params g_add_gtk_key_params;
117static struct wilc_wfi_key g_key_gtk_params;
118static struct add_key_params g_add_ptk_key_params;
119static struct wilc_wfi_key g_key_ptk_params;
120static struct wilc_wfi_wep_key g_key_wep_params;
121static bool g_ptk_keys_saved;
122static bool g_gtk_keys_saved;
123static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900124
125#define AGING_TIME (9 * 1000)
126#define duringIP_TIME 15000
127
Arnd Bergmann1608c402015-11-16 15:04:53 +0100128static void clear_shadow_scan(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900129{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900130 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900131
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900132 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700133 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900134 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
135
136 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
137 if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +0900138 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900139 astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL;
140 }
141
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100142 wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900143 astrLastScannedNtwrksShadow[i].pJoinParams = NULL;
144 }
145 u32LastScannedNtwrksCountShadow = 0;
146 }
147
148}
149
Arnd Bergmann1608c402015-11-16 15:04:53 +0100150static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900151{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900152 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900153 int rssi_v = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900154 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900155
156 for (i = 0; i < num_rssi; i++)
157 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
158
159 rssi_v /= num_rssi;
160 return rssi_v;
161}
162
Arnd Bergmann1608c402015-11-16 15:04:53 +0100163static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900164{
Chaehyun Lim27268872015-09-15 14:06:13 +0900165 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900166 struct wiphy *wiphy;
167 struct cfg80211_bss *bss = NULL;
168 int i;
169 int rssi = 0;
170
Chaehyun Lim27268872015-09-15 14:06:13 +0900171 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900172 wiphy = priv->dev->ieee80211_ptr->wiphy;
173
174 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
175 tstrNetworkInfo *pstrNetworkInfo;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900176
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900177 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
178
179
180 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900181 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900182 struct ieee80211_channel *channel;
183
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900184 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900185
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900186 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900187 channel = ieee80211_get_channel(wiphy, s32Freq);
188
189 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900190 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
192 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900193 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900194 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900195 }
196 }
197
198 }
199 }
200
201}
202
Arnd Bergmann1608c402015-11-16 15:04:53 +0100203static void reset_shadow_found(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900204{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900205 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900206
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900207 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
208 astrLastScannedNtwrksShadow[i].u8Found = 0;
209
210 }
211}
212
Arnd Bergmann1608c402015-11-16 15:04:53 +0100213static void update_scan_time(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900214{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900215 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900216
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900217 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
218 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
219 }
220}
221
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700222static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900223{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900224 unsigned long now = jiffies;
225 int i, j;
226
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900227
228 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
229 if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530230 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900231
Shraddha Barkecccfc392015-10-12 20:49:19 +0530232 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
233 astrLastScannedNtwrksShadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900234
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100235 wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900236
237 for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) {
238 astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1];
239 }
240 u32LastScannedNtwrksCountShadow--;
241 }
242 }
243
244 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow);
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700245 if (u32LastScannedNtwrksCountShadow != 0) {
246 hAgingTimer.data = arg;
247 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
248 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900249 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700250 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900251}
252
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700253static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900254{
255 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100256 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900257}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900258
Arnd Bergmann1608c402015-11-16 15:04:53 +0100259static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900260{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900261 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900262 int i;
263
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900264 if (u32LastScannedNtwrksCountShadow == 0) {
265 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700266 hAgingTimer.data = (unsigned long)pUserVoid;
267 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900268 state = -1;
269 } else {
270 /* Linear search for now */
271 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900272 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900273 pstrNetworkInfo->au8bssid, 6) == 0) {
274 state = i;
275 break;
276 }
277 }
278 }
279 return state;
280}
281
Arnd Bergmann1608c402015-11-16 15:04:53 +0100282static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900283{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900284 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900285 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900286 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900287
288 if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
289 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
290 return;
291 }
292 if (ap_found == -1) {
293 ap_index = u32LastScannedNtwrksCountShadow;
294 u32LastScannedNtwrksCountShadow++;
295
296 } else {
297 ap_index = ap_found;
298 }
299 rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
300 astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
301 if (rssi_index == NUM_RSSI) {
302 rssi_index = 0;
303 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
304 }
305 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
306
307 astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
308 astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
309
310 astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900311 memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900312 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
313
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900314 memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900315 pstrNetworkInfo->au8bssid, ETH_ALEN);
316
317 astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
318 astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
319 astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
320
321 astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
322 astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
323 if (ap_found != -1)
Chaehyun Lim49188af2015-08-11 10:32:41 +0900324 kfree(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900325 astrLastScannedNtwrksShadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900326 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900327 memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900328 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
329
330 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
331 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
332 astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
333 if (ap_found != -1)
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100334 wilc_free_join_params(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335 astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
336
337}
338
339
340/**
341 * @brief CfgScanResult
342 * @details Callback function which returns the scan results found
343 *
344 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
345 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
346 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
347 * void* pUserVoid: Private structure associated with the wireless interface
348 * @return NONE
349 * @author mabubakr
350 * @date
351 * @version 1.0
352 */
Leo Kim1ec38152015-10-12 16:55:59 +0900353static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900354{
Chaehyun Lim27268872015-09-15 14:06:13 +0900355 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900356 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900357 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900358 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900359 struct cfg80211_bss *bss = NULL;
360
Chaehyun Lim27268872015-09-15 14:06:13 +0900361 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100362 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900363 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
364 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900365
366 if (!wiphy)
367 return;
368
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900369 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
370 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900371 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900372 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900373 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900374 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900375 PRINT_ER("wiphy signal type fial\n");
376 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900377 }
378
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900379 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900380 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900381 channel = ieee80211_get_channel(wiphy, s32Freq);
382
Leo Kim7ae43362015-09-16 18:35:59 +0900383 if (!channel)
384 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900385
386 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530387 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900388 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
389
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100390 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900391 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
392 /* max_scan_ssids */
393 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
394
395
396 priv->u32RcvdChCount++;
397
398
399
400 if (pJoinParams == NULL) {
401 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
402 }
403 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
404
405 /*P2P peers are sent to WPA supplicant and added to shadow table*/
406
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900407 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900408 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
409 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900410 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900411 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900412 }
413
414
415 } else {
416 PRINT_ER("Discovered networks exceeded the max limit\n");
417 }
418 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900419 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900420 /* So this network is discovered before, we'll just update its RSSI */
421 for (i = 0; i < priv->u32RcvdChCount; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900422 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530423 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900424
425 astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
426 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
427 break;
428 }
429 }
430 }
431 }
432 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530433 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
434 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900435 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900436
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530437 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530438 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530439 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530440 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900441
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200442 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900443
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900444 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900445 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900446 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900447 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900448 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900449 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200450 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900451
452 }
453 /*Aborting any scan operation during mac close*/
454 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200455 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900456
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530457 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900458 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900459
460 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900461 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900462
Dean Lee72ed4dc2015-06-12 14:11:44 +0900463 cfg80211_scan_done(priv->pstrScanReq, false);
464 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900465 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900466 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200467 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900468 }
469 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900470}
471
472
473/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900474 * @brief CfgConnectResult
475 * @details
476 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
477 * connection response or disconnection notification.
478 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900479 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
481 * void* pUserVoid: Private data associated with wireless interface
482 * @return NONE
483 * @author mabubakr
484 * @date 01 MAR 2012
485 * @version 1.0
486 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100487int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900488
Leo Kimed3f0372015-10-12 16:56:01 +0900489static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900490 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900491 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900492 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
493 void *pUserVoid)
494{
Chaehyun Lim27268872015-09-15 14:06:13 +0900495 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900496 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900497 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900498 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900499 struct wilc *wl;
500 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900501
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100502 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900503
Chaehyun Lim27268872015-09-15 14:06:13 +0900504 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900505 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900506 nic = netdev_priv(dev);
507 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900508 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900509
510 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
511 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530512 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900513
514 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
515
516 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
517
518 if ((u8MacStatus == MAC_DISCONNECTED) &&
519 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
520 /* The case here is that our station was waiting for association response frame and has just received it containing status code
521 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
522 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100523 wilc_wlan_set_bssid(priv->dev, NullBssid);
524 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900525
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900526 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900527 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900528 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900529
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530530 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900531 }
532
533 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900534 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900535 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900536
537 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
538 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900539 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900540
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900541
542 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900543 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900544 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
545 unsigned long now = jiffies;
546
547 if (time_after(now,
548 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900549 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900550 }
551
552 break;
553 }
554 }
555
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000556 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900557 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900558 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900559
560 }
561
562 }
563
564
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530565 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900566
567 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
568
569 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
570 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
571 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
572 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
573 /* be replaced by pstrConnectInfo->u16ConnectStatus */
574 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100575 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900576 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
577 pstrDisconnectNotifInfo->u16reason, priv->dev);
578 u8P2Plocalrandom = 0x01;
579 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900580 bWilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530581 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100582 wilc_wlan_set_bssid(priv->dev, NullBssid);
583 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900584
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900585 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900586 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900587 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900588 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
589 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900590 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900591 pstrDisconnectNotifInfo->u16reason = 3;
592 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900593 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
594 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900595 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900596 pstrDisconnectNotifInfo->u16reason = 1;
597 }
598 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530599 pstrDisconnectNotifInfo->ie_len, false,
600 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900601
602 }
603
604}
605
606
607/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900608 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900609 * @details Set channel for a given wireless interface. Some devices
610 * may support multi-channel operation (by channel hopping) so cfg80211
611 * doesn't verify much. Note, however, that the passed netdev may be
612 * %NULL as well if the user requested changing the channel for the
613 * device itself, or for a monitor interface.
614 * @param[in]
615 * @return int : Return 0 on Success
616 * @author mdaftedar
617 * @date 01 MAR 2012
618 * @version 1.0
619 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900620static int set_channel(struct wiphy *wiphy,
621 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900622{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900623 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900624 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900625 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900626
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900627 priv = wiphy_priv(wiphy);
628
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900629 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
630 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900631
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900632 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100633 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900634
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900635 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900636 PRINT_ER("Error in setting channel %d\n", channelnum);
637
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900638 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900639}
640
641/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900642 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900643 * @details Request to do a scan. If returning zero, the scan request is given
644 * the driver, and will be valid until passed to cfg80211_scan_done().
645 * For scan results, call cfg80211_inform_bss(); you can call this outside
646 * the scan/scan_done bracket too.
647 * @param[in]
648 * @return int : Return 0 on Success
649 * @author mabubakr
650 * @date 01 MAR 2012
651 * @version 1.0
652 */
653
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900654static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900655{
Chaehyun Lim27268872015-09-15 14:06:13 +0900656 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900657 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900658 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900659 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900660 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900661
662 priv = wiphy_priv(wiphy);
663
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900664 priv->pstrScanReq = request;
665
666 priv->u32RcvdChCount = 0;
667
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100668 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900669
670
671 reset_shadow_found(priv);
672
Dean Lee72ed4dc2015-06-12 14:11:44 +0900673 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900674 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
675 /* max_scan_ssids */
676 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900677 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900678 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
679 }
680
681 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530682 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900683
684 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
685
686 if (request->n_ssids >= 1) {
687
688
Leo Kim607db442015-10-05 15:25:37 +0900689 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900690 strHiddenNetwork.u8ssidnum = request->n_ssids;
691
692
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900693 for (i = 0; i < request->n_ssids; i++) {
694
695 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900696 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900697 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900698 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
699 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530700 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900701 strHiddenNetwork.u8ssidnum -= 1;
702 }
703 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530704 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100705 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900706 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900707 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900708 CfgScanResult, (void *)priv, &strHiddenNetwork);
709 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530710 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100711 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900712 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900713 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900714 CfgScanResult, (void *)priv, NULL);
715 }
716
717 } else {
718 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530719 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900720 }
721
Leo Kime6e12662015-09-16 18:36:03 +0900722 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900723 s32Error = -EBUSY;
724 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
725 }
726
727 return s32Error;
728}
729
730/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900731 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900732 * @details Connect to the ESS with the specified parameters. When connected,
733 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
734 * If the connection fails for some reason, call cfg80211_connect_result()
735 * with the status from the AP.
736 * @param[in]
737 * @return int : Return 0 on Success
738 * @author mabubakr
739 * @date 01 MAR 2012
740 * @version 1.0
741 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900742static int connect(struct wiphy *wiphy, struct net_device *dev,
743 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744{
Leo Kime6e12662015-09-16 18:36:03 +0900745 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900746 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900747 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900748 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900749 char *pcgroup_encrypt_val = NULL;
750 char *pccipher_group = NULL;
751 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900752
Chaehyun Lim27268872015-09-15 14:06:13 +0900753 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900754 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900755 tstrNetworkInfo *pstrNetworkInfo = NULL;
756
757
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100758 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900759 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900760 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900761
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100762 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900763
Johnny Kim8a143302015-06-10 17:06:46 +0900764 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
Chaehyun Lim3f882892015-08-10 11:33:17 +0900765 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900766 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900767 pstrWFIDrv->p2p_connect = 1;
768 } else {
769 pstrWFIDrv->p2p_connect = 0;
770 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530771 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900772
773 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
774 if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900775 memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900776 sme->ssid,
777 sme->ssid_len) == 0) {
778 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
779 if (sme->bssid == NULL) {
780 /* BSSID is not passed from the user, so decision of matching
781 * is done by SSID only */
782 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
783 break;
784 } else {
785 /* BSSID is also passed from the user, so decision of matching
786 * should consider also this passed BSSID */
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900787 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900788 sme->bssid,
789 ETH_ALEN) == 0) {
790 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
791 break;
792 }
793 }
794 }
795 }
796
797 if (i < u32LastScannedNtwrksCountShadow) {
798 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
799
800 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
801
802 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
803 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
804 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
805 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
806 } else {
807 s32Error = -ENOENT;
808 if (u32LastScannedNtwrksCountShadow == 0)
809 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
810 else
811 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
812
813 goto done;
814 }
815
816 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900817 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
818 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900819
820 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
821 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
822
823 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
824
825 if (INFO) {
826 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
827 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
828 }
829
830 if (sme->crypto.cipher_group != NO_ENCRYPT) {
831 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
832 * we will add to it the pairwise cipher suite(s) */
833 pcwpa_version = "Default";
834 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900836 u8security = ENCRYPT_ENABLED | WEP;
837 pcgroup_encrypt_val = "WEP40";
838 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
839 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
840
841 if (INFO) {
842 for (i = 0; i < sme->key_len; i++)
843 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
844 }
845 priv->WILC_WFI_wep_default = sme->key_idx;
846 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900847 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900848
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900849 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900850 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900851 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
852 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900853 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900854
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100855 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
856 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900857 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900858 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
859 pcgroup_encrypt_val = "WEP104";
860 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
861
862 priv->WILC_WFI_wep_default = sme->key_idx;
863 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900864 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900865
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900866 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900867 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900868 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
869 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900870 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900871
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100872 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
873 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900874 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900875 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900876 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
877 pcgroup_encrypt_val = "WPA2_TKIP";
878 pccipher_group = "TKIP";
879 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
880 /* tenuSecurity_t = WPA2_AES; */
881 u8security = ENCRYPT_ENABLED | WPA2 | AES;
882 pcgroup_encrypt_val = "WPA2_AES";
883 pccipher_group = "AES";
884 }
885 pcwpa_version = "WPA_VERSION_2";
886 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
887 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900888 u8security = ENCRYPT_ENABLED | WPA | TKIP;
889 pcgroup_encrypt_val = "WPA_TKIP";
890 pccipher_group = "TKIP";
891 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
892 /* tenuSecurity_t = WPA_AES; */
893 u8security = ENCRYPT_ENABLED | WPA | AES;
894 pcgroup_encrypt_val = "WPA_AES";
895 pccipher_group = "AES";
896
897 }
898 pcwpa_version = "WPA_VERSION_1";
899
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900900 } else {
901 s32Error = -ENOTSUPP;
902 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
903
904 goto done;
905 }
906
907 }
908
909 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
910 * add to it the pairwise cipher suite(s) */
911 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
912 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
913 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
914 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
915 u8security = u8security | TKIP;
916 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
917 u8security = u8security | AES;
918 }
919 }
920 }
921
922 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
923
924 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
925 switch (sme->auth_type) {
926 case NL80211_AUTHTYPE_OPEN_SYSTEM:
927 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
928 tenuAuth_type = OPEN_SYSTEM;
929 break;
930
931 case NL80211_AUTHTYPE_SHARED_KEY:
932 tenuAuth_type = SHARED_KEY;
933 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
934 break;
935
936 default:
937 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
938 }
939
940
941 /* ai: key_mgmt: enterprise case */
942 if (sme->crypto.n_akm_suites) {
943 switch (sme->crypto.akm_suites[0]) {
944 case WLAN_AKM_SUITE_8021X:
945 tenuAuth_type = IEEE8021;
946 break;
947
948 default:
949 break;
950 }
951 }
952
953
954 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
955
956 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
957 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
958
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900959 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900960
Leo Kimab16ec02015-10-29 12:05:40 +0900961 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900962 u8WLANChannel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900963
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100964 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900965
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100966 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900967 sme->ssid_len, sme->ie, sme->ie_len,
968 CfgConnectResult, (void *)priv, u8security,
969 tenuAuth_type, pstrNetworkInfo->u8channel,
970 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +0900971 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100972 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900973 s32Error = -ENOENT;
974 goto done;
975 }
976
977done:
978
979 return s32Error;
980}
981
982
983/**
Chaehyun Limb027cde2015-09-14 12:24:04 +0900984 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900985 * @details Disconnect from the BSS/ESS.
986 * @param[in]
987 * @return int : Return 0 on Success
988 * @author mdaftedar
989 * @date 01 MAR 2012
990 * @version 1.0
991 */
Chaehyun Limb027cde2015-09-14 12:24:04 +0900992static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900993{
Leo Kime6e12662015-09-16 18:36:03 +0900994 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900995 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900996 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900997 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900998
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100999 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001000 priv = wiphy_priv(wiphy);
1001
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001002 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kim441dc602015-10-12 16:55:35 +09001003 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001004 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001005 u8WLANChannel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001006 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001007
1008 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1009
1010 u8P2Plocalrandom = 0x01;
1011 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001012 bWilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001013 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001014
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001015 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001016 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001017 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1018 s32Error = -EINVAL;
1019 }
1020
1021 return s32Error;
1022}
1023
1024/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001025 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001026 * @details Add a key with the given parameters. @mac_addr will be %NULL
1027 * when adding a group key.
1028 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1029 * @return int : Return 0 on Success
1030 * @author mdaftedar
1031 * @date 01 MAR 2012
1032 * @version 1.0
1033 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001034static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1035 bool pairwise,
1036 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001037
1038{
Leo Kime6e12662015-09-16 18:36:03 +09001039 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001040 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001041 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001042 const u8 *pu8RxMic = NULL;
1043 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001044 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001045 u8 u8gmode = NO_ENCRYPT;
1046 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001047 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001048 struct wilc *wl;
1049 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001050
1051 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001052 nic = netdev_priv(netdev);
1053 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001054
1055 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1056
Johnny Kim8a143302015-06-10 17:06:46 +09001057 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001058
1059 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1060 params->key[1],
1061 params->key[2]);
1062
1063
1064 switch (params->cipher) {
1065 case WLAN_CIPHER_SUITE_WEP40:
1066 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001067 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1068
1069 priv->WILC_WFI_wep_default = key_index;
1070 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001071 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001072
1073 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1074 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1075
1076 for (i = 0; i < params->key_len; i++)
1077 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1078
1079 tenuAuth_type = OPEN_SYSTEM;
1080
1081 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1082 u8mode = ENCRYPT_ENABLED | WEP;
1083 else
1084 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1085
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001086 wilc_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001087 break;
1088 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001089 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001090 priv->WILC_WFI_wep_default = key_index;
1091 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001092 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001093
1094 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1095 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1096 if (INFO) {
1097 for (i = 0; i < params->key_len; i++)
1098 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1099 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001100 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001101 }
1102
1103 break;
1104
1105 case WLAN_CIPHER_SUITE_TKIP:
1106 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001107 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1108
1109 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001110 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001111 priv->wilc_gtk[key_index]->key = NULL;
1112 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001113
1114 }
1115 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001116 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001117 priv->wilc_ptk[key_index]->key = NULL;
1118 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001119 }
1120
1121
1122
Daniel Machon19132212015-08-05 08:18:31 +02001123 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001124 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1125 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1126 else
1127 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1128
1129 priv->wilc_groupkey = u8gmode;
1130
1131 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1132
1133 pu8TxMic = params->key + 24;
1134 pu8RxMic = params->key + 16;
1135 KeyLen = params->key_len - 16;
1136 }
1137 /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301138 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001139
Glen Leef3052582015-09-10 12:03:04 +09001140 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001141 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001142
1143 /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301144 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001145
1146 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001147 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001148 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001149 }
1150
1151 priv->wilc_gtk[key_index]->cipher = params->cipher;
1152 priv->wilc_gtk[key_index]->key_len = params->key_len;
1153 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1154
1155 if (INFO) {
1156 for (i = 0; i < params->key_len; i++)
1157 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1158 for (i = 0; i < params->seq_len; i++)
1159 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1160 }
1161
1162
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001163 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001164 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1165
1166 } else {
1167 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]);
1168
1169 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1170 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1171 else
1172 u8pmode = priv->wilc_groupkey | AES;
1173
1174
1175 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1176
1177 pu8TxMic = params->key + 24;
1178 pu8RxMic = params->key + 16;
1179 KeyLen = params->key_len - 16;
1180 }
1181
Shraddha Barkecccfc392015-10-12 20:49:19 +05301182 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001183
Glen Leef3052582015-09-10 12:03:04 +09001184 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001185
Shraddha Barkecccfc392015-10-12 20:49:19 +05301186 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001187
1188 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001189 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001190
1191 if (INFO) {
1192 for (i = 0; i < params->key_len; i++)
1193 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1194
1195 for (i = 0; i < params->seq_len; i++)
1196 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1197 }
1198
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001199 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001200
1201 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001202 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001203
1204 priv->wilc_ptk[key_index]->cipher = params->cipher;
1205 priv->wilc_ptk[key_index]->key_len = params->key_len;
1206 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1207
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001208 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001209 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1210 }
1211 break;
1212 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001213
1214 {
1215 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001216 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001217 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1218 /* swap the tx mic by rx mic */
1219 pu8RxMic = params->key + 24;
1220 pu8TxMic = params->key + 16;
1221 KeyLen = params->key_len - 16;
1222 }
1223
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001224 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001225 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001226 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001227 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001228 if (!mac_addr) {
1229 g_add_gtk_key_params.mac_addr = NULL;
1230 } else {
Glen Leef3052582015-09-10 12:03:04 +09001231 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001232 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1233 }
1234 g_key_gtk_params.key_len = params->key_len;
1235 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001236 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001237 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1238 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001239 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001240 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1241 }
1242 g_key_gtk_params.cipher = params->cipher;
1243
1244 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1245 g_key_gtk_params.key[1],
1246 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001247 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001248 }
1249
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001250 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001251 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001252 } else {
1253 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1254 /* swap the tx mic by rx mic */
1255 pu8RxMic = params->key + 24;
1256 pu8TxMic = params->key + 16;
1257 KeyLen = params->key_len - 16;
1258 }
1259
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001260 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001261 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001262 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001263 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001264 if (!mac_addr) {
1265 g_add_ptk_key_params.mac_addr = NULL;
1266 } else {
Glen Leef3052582015-09-10 12:03:04 +09001267 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001268 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1269 }
1270 g_key_ptk_params.key_len = params->key_len;
1271 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001272 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001273 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1274 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001275 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001276 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1277 }
1278 g_key_ptk_params.cipher = params->cipher;
1279
1280 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1281 g_key_ptk_params.key[1],
1282 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001283 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001284 }
1285
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001286 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001287 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1288 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1289 if (INFO) {
1290 for (i = 0; i < params->key_len; i++)
1291 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1292 }
1293 }
1294 }
1295 break;
1296
1297 default:
1298 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1299 s32Error = -ENOTSUPP;
1300
1301 }
1302
1303 return s32Error;
1304}
1305
1306/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001307 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001308 * @details Remove a key given the @mac_addr (%NULL for a group key)
1309 * and @key_index, return -ENOENT if the key doesn't exist.
1310 * @param[in]
1311 * @return int : Return 0 on Success
1312 * @author mdaftedar
1313 * @date 01 MAR 2012
1314 * @version 1.0
1315 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001316static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1317 u8 key_index,
1318 bool pairwise,
1319 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001320{
Chaehyun Lim27268872015-09-15 14:06:13 +09001321 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001322 struct wilc *wl;
1323 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001324
1325 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001326 nic = netdev_priv(netdev);
1327 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001330 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001331 g_ptk_keys_saved = false;
1332 g_gtk_keys_saved = false;
1333 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001334
1335 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301336 kfree(g_key_wep_params.key);
1337 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338
1339 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1340
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001341 if ((priv->wilc_gtk[key_index]) != NULL) {
1342
Shraddha Barkecccfc392015-10-12 20:49:19 +05301343 kfree(priv->wilc_gtk[key_index]->key);
1344 priv->wilc_gtk[key_index]->key = NULL;
1345 kfree(priv->wilc_gtk[key_index]->seq);
1346 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001347
Chaehyun Lim49188af2015-08-11 10:32:41 +09001348 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001349 priv->wilc_gtk[key_index] = NULL;
1350
1351 }
1352
1353 if ((priv->wilc_ptk[key_index]) != NULL) {
1354
Shraddha Barkecccfc392015-10-12 20:49:19 +05301355 kfree(priv->wilc_ptk[key_index]->key);
1356 priv->wilc_ptk[key_index]->key = NULL;
1357 kfree(priv->wilc_ptk[key_index]->seq);
1358 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001359 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001360 priv->wilc_ptk[key_index] = NULL;
1361 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001362
1363 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301364 kfree(g_key_ptk_params.key);
1365 g_key_ptk_params.key = NULL;
1366 kfree(g_key_ptk_params.seq);
1367 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001368
Shraddha Barkecccfc392015-10-12 20:49:19 +05301369 kfree(g_key_gtk_params.key);
1370 g_key_gtk_params.key = NULL;
1371 kfree(g_key_gtk_params.seq);
1372 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001373
1374 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001375 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001376 }
1377
1378 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001379 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001380 priv->WILC_WFI_wep_key_len[key_index] = 0;
1381
1382 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001383 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001384 } else {
1385 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001386 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001387 }
1388
Leo Kimaaed3292015-10-12 16:55:38 +09001389 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001390}
1391
1392/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001393 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001394 * @details Get information about the key with the given parameters.
1395 * @mac_addr will be %NULL when requesting information for a group
1396 * key. All pointers given to the @callback function need not be valid
1397 * after it returns. This function should return an error if it is
1398 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1399 * @param[in]
1400 * @return int : Return 0 on Success
1401 * @author mdaftedar
1402 * @date 01 MAR 2012
1403 * @version 1.0
1404 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001405static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1406 bool pairwise,
1407 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001408{
Chaehyun Lim27268872015-09-15 14:06:13 +09001409 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001410 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001411 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001412
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001413 priv = wiphy_priv(wiphy);
1414
1415
Alison Schofield3604af52015-10-12 13:22:44 -07001416 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001417 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1418
1419 key_params.key = priv->wilc_gtk[key_index]->key;
1420 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1421 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1422 key_params.seq = priv->wilc_gtk[key_index]->seq;
1423 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1424 if (INFO) {
1425 for (i = 0; i < key_params.key_len; i++)
1426 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1427 }
1428 } else {
1429 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1430
1431 key_params.key = priv->wilc_ptk[key_index]->key;
1432 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1433 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1434 key_params.seq = priv->wilc_ptk[key_index]->seq;
1435 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1436 }
1437
1438 callback(cookie, &key_params);
1439
Leo Kimaaed3292015-10-12 16:55:38 +09001440 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001441}
1442
1443/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001444 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001445 * @details Set the default management frame key on an interface
1446 * @param[in]
1447 * @return int : Return 0 on Success.
1448 * @author mdaftedar
1449 * @date 01 MAR 2012
1450 * @version 1.0
1451 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001452static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1453 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001454{
Chaehyun Lim27268872015-09-15 14:06:13 +09001455 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001456
1457
1458 priv = wiphy_priv(wiphy);
1459
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301460 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001461
1462 if (key_index != priv->WILC_WFI_wep_default) {
1463
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001464 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001465 }
1466
Leo Kimaaed3292015-10-12 16:55:38 +09001467 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001468}
1469
1470/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001471 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001472 * @details Get station information for the station identified by @mac
1473 * @param[in] NONE
1474 * @return int : Return 0 on Success.
1475 * @author mdaftedar
1476 * @date 01 MAR 2012
1477 * @version 1.0
1478 */
1479
Chaehyun Limf06f5622015-09-14 12:24:18 +09001480static int get_station(struct wiphy *wiphy, struct net_device *dev,
1481 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001482{
Chaehyun Lim27268872015-09-15 14:06:13 +09001483 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001484 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001485 u32 i = 0;
1486 u32 associatedsta = 0;
1487 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001488 priv = wiphy_priv(wiphy);
1489 nic = netdev_priv(dev);
1490
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001491 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1492 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1493
1494 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1495
1496 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1497
1498 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1499 associatedsta = i;
1500 break;
1501 }
1502
1503 }
1504
1505 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001506 PRINT_ER("Station required is not associated\n");
1507 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001508 }
1509
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001510 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001511
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001512 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001513 sinfo->inactive_time = 1000 * inactive_time;
1514 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1515
1516 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001517
1518 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001519 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001520
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001521 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001522
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001523 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301524 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001525 BIT(NL80211_STA_INFO_TX_PACKETS) |
1526 BIT(NL80211_STA_INFO_TX_FAILED) |
1527 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001528
Leo Kim00c8dfc2015-10-29 12:05:30 +09001529 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001530 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001531 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1532 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001533 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001534
Leo Kim5babeec2015-10-29 12:05:29 +09001535 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1536 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001537 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001538 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001539 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001540
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001541 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1542 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001543 }
Leo Kimaaed3292015-10-12 16:55:38 +09001544 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001545}
1546
1547
1548/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001549 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001550 * @details Modify parameters for a given BSS.
1551 * @param[in]
1552 * -use_cts_prot: Whether to use CTS protection
1553 * (0 = no, 1 = yes, -1 = do not change)
1554 * -use_short_preamble: Whether the use of short preambles is allowed
1555 * (0 = no, 1 = yes, -1 = do not change)
1556 * -use_short_slot_time: Whether the use of short slot time is allowed
1557 * (0 = no, 1 = yes, -1 = do not change)
1558 * -basic_rates: basic rates in IEEE 802.11 format
1559 * (or NULL for no change)
1560 * -basic_rates_len: number of basic rates
1561 * -ap_isolate: do not forward packets between connected stations
1562 * -ht_opmode: HT Operation mode
1563 * (u16 = opmode, -1 = do not change)
1564 * @return int : Return 0 on Success.
1565 * @author mdaftedar
1566 * @date 01 MAR 2012
1567 * @version 1.0
1568 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001569static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1570 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001571{
1572 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1573 return 0;
1574}
1575
1576/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001577 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578 * @details Notify that wiphy parameters have changed;
1579 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1580 * have changed.
1581 * @return int : Return 0 on Success
1582 * @author mdaftedar
1583 * @date 01 MAR 2012
1584 * @version 1.0
1585 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001586static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001587{
Leo Kime6e12662015-09-16 18:36:03 +09001588 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001589 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001590 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001591
1592 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001593
Tony Cho87c05b22015-10-12 16:56:07 +09001594 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301595 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001596
1597 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1598 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1599 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001600 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001601 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1602 }
1603 if (changed & WIPHY_PARAM_RETRY_LONG) {
1604
1605 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
Tony Cho87c05b22015-10-12 16:56:07 +09001606 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001607 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1608
1609 }
1610 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1611 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
Tony Cho87c05b22015-10-12 16:56:07 +09001612 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001613 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1614
1615 }
1616
1617 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1618 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1619
Tony Cho87c05b22015-10-12 16:56:07 +09001620 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001621 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1622
1623 }
1624
1625 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001626 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001627 if (s32Error)
1628 PRINT_ER("Error in setting WIPHY PARAMS\n");
1629
1630
1631 return s32Error;
1632}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001633
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001634/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001635 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001636 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1637 * devices running firmwares capable of generating the (re) association
1638 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1639 * @param[in]
1640 * @return int : Return 0 on Success
1641 * @author mdaftedar
1642 * @date 01 MAR 2012
1643 * @version 1.0
1644 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001645static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1646 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001647{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001648 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001649 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001650 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001651
Chaehyun Lim27268872015-09-15 14:06:13 +09001652 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001653
1654 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1655
1656
1657 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001658 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001659 ETH_ALEN)) {
1660 /*If bssid already exists and pmkid value needs to reset*/
1661 flag = PMKID_FOUND;
1662 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1663 break;
1664 }
1665 }
1666 if (i < WILC_MAX_NUM_PMKIDS) {
1667 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001668 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001669 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001670 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001671 PMKID_LEN);
1672 if (!(flag == PMKID_FOUND))
1673 priv->pmkid_list.numpmkid++;
1674 } else {
1675 PRINT_ER("Invalid PMKID index\n");
1676 s32Error = -EINVAL;
1677 }
1678
1679 if (!s32Error) {
1680 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001681 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001682 }
1683 return s32Error;
1684}
1685
1686/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001687 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001688 * @details Delete a cached PMKID.
1689 * @param[in]
1690 * @return int : Return 0 on Success
1691 * @author mdaftedar
1692 * @date 01 MAR 2012
1693 * @version 1.0
1694 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001695static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1696 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001697{
1698
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001699 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001700 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001701
Chaehyun Lim27268872015-09-15 14:06:13 +09001702 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001703
1704 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1705
1706 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001707 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001708 ETH_ALEN)) {
1709 /*If bssid is found, reset the values*/
1710 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001711 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001712 break;
1713 }
1714 }
1715
1716 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1717 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001718 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001719 priv->pmkid_list.pmkidlist[i + 1].bssid,
1720 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001721 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001722 priv->pmkid_list.pmkidlist[i].pmkid,
1723 PMKID_LEN);
1724 }
1725 priv->pmkid_list.numpmkid--;
1726 } else {
1727 s32Error = -EINVAL;
1728 }
1729
1730 return s32Error;
1731}
1732
1733/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001734 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001735 * @details Flush all cached PMKIDs.
1736 * @param[in]
1737 * @return int : Return 0 on Success
1738 * @author mdaftedar
1739 * @date 01 MAR 2012
1740 * @version 1.0
1741 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001742static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001743{
Chaehyun Lim27268872015-09-15 14:06:13 +09001744 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001745
1746 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1747
1748 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001749 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001750
1751 return 0;
1752}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001753
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001754
1755/**
1756 * @brief WILC_WFI_CfgParseRxAction
1757 * @details Function parses the received frames and modifies the following attributes:
1758 * -GO Intent
1759 * -Channel list
1760 * -Operating Channel
1761 *
1762 * @param[in] u8* Buffer, u32 length
1763 * @return NONE.
1764 * @author mdaftedar
1765 * @date 12 DEC 2012
1766 * @version
1767 */
1768
Arnd Bergmann1608c402015-11-16 15:04:53 +01001769static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001770{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001771 u32 index = 0;
1772 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001773
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001774 u8 op_channel_attr_index = 0;
1775 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001776
1777 while (index < len) {
1778 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001779 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001780 }
1781
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301782 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001783 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301784 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001785 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001786 index += buf[index + 1] + 3; /* ID,Length byte */
1787 }
Alison Schofield3604af52015-10-12 13:22:44 -07001788 if (u8WLANChannel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001789
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001790 /*Modify channel list attribute*/
1791 if (channel_list_attr_index) {
1792 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1793 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1794 if (buf[i] == 0x51) {
1795 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1796 buf[j] = u8WLANChannel;
1797 }
1798 break;
1799 }
1800 }
1801 }
1802 /*Modify operating channel attribute*/
1803 if (op_channel_attr_index) {
1804 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1805 buf[op_channel_attr_index + 6] = 0x51;
1806 buf[op_channel_attr_index + 7] = u8WLANChannel;
1807 }
1808 }
1809}
1810
1811/**
1812 * @brief WILC_WFI_CfgParseTxAction
1813 * @details Function parses the transmitted action frames and modifies the
1814 * GO Intent attribute
1815 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1816 * @return NONE.
1817 * @author mdaftedar
1818 * @date 12 DEC 2012
1819 * @version
1820 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001821static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001822{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001823 u32 index = 0;
1824 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001825
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001826 u8 op_channel_attr_index = 0;
1827 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001828
1829 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001830 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001831 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001832
1833 break;
1834 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001835
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301836 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001837 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301838 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001839 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001840 index += buf[index + 1] + 3; /* ID,Length byte */
1841 }
Alison Schofield3604af52015-10-12 13:22:44 -07001842 if (u8WLANChannel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001843
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001844 /*Modify channel list attribute*/
1845 if (channel_list_attr_index) {
1846 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1847 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1848 if (buf[i] == 0x51) {
1849 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1850 buf[j] = u8WLANChannel;
1851 }
1852 break;
1853 }
1854 }
1855 }
1856 /*Modify operating channel attribute*/
1857 if (op_channel_attr_index) {
1858 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1859 buf[op_channel_attr_index + 6] = 0x51;
1860 buf[op_channel_attr_index + 7] = u8WLANChannel;
1861 }
1862 }
1863}
1864
1865/* @brief WILC_WFI_p2p_rx
1866 * @details
1867 * @param[in]
1868 *
1869 * @return None
1870 * @author Mai Daftedar
1871 * @date 2 JUN 2013
1872 * @version 1.0
1873 */
1874
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001875void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001876{
1877
Chaehyun Lim27268872015-09-15 14:06:13 +09001878 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001879 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001880 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001881 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001882 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001883
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001884 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001885 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001886
1887 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001888 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001889
1890 /* The packet offset field conain info about what type of managment frame */
1891 /* we are dealing with and ack status */
1892 pkt_offset = GET_PKT_OFFSET(header);
1893
1894 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1895 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1896 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001897 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001898 return;
1899 } else {
1900 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1901 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],
1902 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001903 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001904 } else {
1905 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],
1906 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001907 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001908 }
1909 return;
1910 }
1911 } else {
1912
1913 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1914
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001915 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001916 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001917
1918 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1919 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1920
Leo Kim1229b1a2015-10-29 12:05:39 +09001921 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001922 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1923 return;
1924 }
1925 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1926
1927 switch (buff[ACTION_SUBTYPE_ID]) {
1928 case GAS_INTIAL_REQ:
1929 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1930 break;
1931
1932 case GAS_INTIAL_RSP:
1933 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1934 break;
1935
1936 case PUBLIC_ACT_VENDORSPEC:
1937 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
1938 * 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 +09001939 if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001940 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1941 if (!bWilc_ie) {
1942 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001943 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001944 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09001945 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001946 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
1947 break;
1948 }
1949 }
1950 }
1951 }
1952 if (u8P2Plocalrandom > u8P2Precvrandom) {
1953 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1954 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1955 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001956 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001957 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1958 break;
1959 }
1960 }
1961 }
1962 } else
1963 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
1964 }
1965
1966
1967 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
1968 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
1969 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001970 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001971 return;
1972 }
1973 break;
1974
1975 default:
1976 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1977 break;
1978 }
1979 }
1980 }
1981
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001982 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001983 }
1984}
1985
1986/**
1987 * @brief WILC_WFI_mgmt_tx_complete
1988 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
1989 * @param[in] priv
1990 * transmitting status
1991 * @return None
1992 * @author Amr Abdelmoghny
1993 * @date 20 MAY 2013
1994 * @version 1.0
1995 */
1996static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1997{
1998 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1999
2000
2001 kfree(pv_data->buff);
2002 kfree(pv_data);
2003}
2004
2005/**
2006 * @brief WILC_WFI_RemainOnChannelReady
2007 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2008 * @param
2009 * @return none
2010 * @author Amr abdelmoghny
2011 * @date 9 JUNE 2013
2012 * @version
2013 */
2014
2015static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2016{
Chaehyun Lim27268872015-09-15 14:06:13 +09002017 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002018
Chaehyun Lim27268872015-09-15 14:06:13 +09002019 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002020
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302021 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002022
Dean Lee72ed4dc2015-06-12 14:11:44 +09002023 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002024
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002025 cfg80211_ready_on_channel(priv->wdev,
2026 priv->strRemainOnChanParams.u64ListenCookie,
2027 priv->strRemainOnChanParams.pstrListenChan,
2028 priv->strRemainOnChanParams.u32ListenDuration,
2029 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002030}
2031
2032/**
2033 * @brief WILC_WFI_RemainOnChannelExpired
2034 * @details Callback function, called on expiration of remain-on-channel duration
2035 * @param
2036 * @return none
2037 * @author Amr abdelmoghny
2038 * @date 15 MAY 2013
2039 * @version
2040 */
2041
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002042static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002043{
Chaehyun Lim27268872015-09-15 14:06:13 +09002044 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002045
Chaehyun Lim27268872015-09-15 14:06:13 +09002046 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002047
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002048 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302049 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002050
Dean Lee72ed4dc2015-06-12 14:11:44 +09002051 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002052
2053 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002054 cfg80211_remain_on_channel_expired(priv->wdev,
2055 priv->strRemainOnChanParams.u64ListenCookie,
2056 priv->strRemainOnChanParams.pstrListenChan,
2057 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002058 } else {
2059 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2060 , priv->strRemainOnChanParams.u32ListenSessionID);
2061 }
2062}
2063
2064
2065/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002066 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002067 * @details Request the driver to remain awake on the specified
2068 * channel for the specified duration to complete an off-channel
2069 * operation (e.g., public action frame exchange). When the driver is
2070 * ready on the requested channel, it must indicate this with an event
2071 * notification by calling cfg80211_ready_on_channel().
2072 * @param[in]
2073 * @return int : Return 0 on Success
2074 * @author mdaftedar
2075 * @date 01 MAR 2012
2076 * @version 1.0
2077 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002078static int remain_on_channel(struct wiphy *wiphy,
2079 struct wireless_dev *wdev,
2080 struct ieee80211_channel *chan,
2081 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002082{
Leo Kime6e12662015-09-16 18:36:03 +09002083 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002084 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002085
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002086 priv = wiphy_priv(wiphy);
2087
2088 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2089
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002090
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002091 if (wdev->iftype == NL80211_IFTYPE_AP) {
2092 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2093 return s32Error;
2094 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002095
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002096 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002097
2098 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2099 priv->strRemainOnChanParams.pstrListenChan = chan;
2100 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002101 priv->strRemainOnChanParams.u32ListenDuration = duration;
2102 priv->strRemainOnChanParams.u32ListenSessionID++;
2103
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002104 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002105 , priv->strRemainOnChanParams.u32ListenSessionID
2106 , duration
2107 , chan->hw_value
2108 , WILC_WFI_RemainOnChannelExpired
2109 , WILC_WFI_RemainOnChannelReady
2110 , (void *)priv);
2111
2112 return s32Error;
2113}
2114
2115/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002116 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002117 * @details Cancel an on-going remain-on-channel operation.
2118 * This allows the operation to be terminated prior to timeout based on
2119 * the duration value.
2120 * @param[in] struct wiphy *wiphy,
2121 * @param[in] struct net_device *dev
2122 * @param[in] u64 cookie,
2123 * @return int : Return 0 on Success
2124 * @author mdaftedar
2125 * @date 01 MAR 2012
2126 * @version 1.0
2127 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002128static int cancel_remain_on_channel(struct wiphy *wiphy,
2129 struct wireless_dev *wdev,
2130 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002131{
Leo Kime6e12662015-09-16 18:36:03 +09002132 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002133 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002134
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002135 priv = wiphy_priv(wiphy);
2136
2137 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2138
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002139 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002140 return s32Error;
2141}
2142/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002143 * @brief WILC_WFI_mgmt_tx_frame
2144 * @details
2145 *
2146 * @param[in]
2147 * @return NONE.
2148 * @author mdaftedar
2149 * @date 01 JUL 2012
2150 * @version
2151 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002152extern bool wilc_enable_ps;
Chaehyun Limc1560322015-09-22 18:34:51 +09002153static int mgmt_tx(struct wiphy *wiphy,
2154 struct wireless_dev *wdev,
2155 struct cfg80211_mgmt_tx_params *params,
2156 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002157{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002158 struct ieee80211_channel *chan = params->chan;
2159 unsigned int wait = params->wait;
2160 const u8 *buf = params->buf;
2161 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002162 const struct ieee80211_mgmt *mgmt;
2163 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002164 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002165 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002166 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002167 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002168 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002169
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002170 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002171 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002172 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002173
2174 *cookie = (unsigned long)buf;
2175 priv->u64tx_cookie = *cookie;
2176 mgmt = (const struct ieee80211_mgmt *) buf;
2177
2178 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2179
2180 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002181 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002182 if (mgmt_tx == NULL) {
2183 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002184 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002185 }
Glen Leef3052582015-09-10 12:03:04 +09002186 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002187 if (mgmt_tx->buff == NULL) {
2188 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002189 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002190 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002191 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002192 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002193 mgmt_tx->size = len;
2194
2195
2196 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2197 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2198 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002199 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002200 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002201 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002202 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002203 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002204
2205
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002206 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002207 /*Only set the channel, if not a negotiation confirmation frame
2208 * (If Negotiation confirmation frame, force it
2209 * to be transmitted on the same negotiation channel)*/
2210
2211 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2212 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2213 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002214 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002215 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002216 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002217 }
2218 switch (buf[ACTION_SUBTYPE_ID]) {
2219 case GAS_INTIAL_REQ:
2220 {
2221 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2222 break;
2223 }
2224
2225 case GAS_INTIAL_RSP:
2226 {
2227 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2228 break;
2229 }
2230
2231 case PUBLIC_ACT_VENDORSPEC:
2232 {
2233 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2234 * 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 +09002235 if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002236 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2237 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2238 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2239 get_random_bytes(&u8P2Plocalrandom, 1);
2240 /*Increment the number to prevent if its 0*/
2241 u8P2Plocalrandom++;
2242 }
2243 }
2244
2245 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2246 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2247 if (u8P2Plocalrandom > u8P2Precvrandom) {
2248 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2249
2250 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2251 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002252 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002253 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002254 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002255
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002256 /*If using supplicant go intent, no need at all*/
2257 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002258 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002259 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002260 break;
2261 }
2262 }
2263
2264 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302265 /*
2266 * Adding WILC information element to allow two WILC devices to
2267 * identify each other and connect
2268 */
2269 memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002270 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2271 mgmt_tx->size = buf_len;
2272 }
2273 } else
2274 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2275 }
2276
2277 } else {
2278 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2279 }
2280
2281 break;
2282 }
2283
2284 default:
2285 {
2286 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2287 break;
2288 }
2289 }
2290
2291 }
2292
2293 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
Leo Kim1229b1a2015-10-29 12:05:39 +09002294 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002295
Leo Kim1229b1a2015-10-29 12:05:39 +09002296 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2297 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002298 }
2299
Glen Lee829c4772015-10-29 12:18:44 +09002300 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2301 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002302 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002303 } else {
2304 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2305 }
Leo Kimaaed3292015-10-12 16:55:38 +09002306 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002307}
2308
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002309static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2310 struct wireless_dev *wdev,
2311 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002312{
Chaehyun Lim27268872015-09-15 14:06:13 +09002313 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002314 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002315
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002316 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002317 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002318
2319
2320 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002321 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002322
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002323 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002324 cfg80211_remain_on_channel_expired(priv->wdev,
2325 priv->strRemainOnChanParams.u64ListenCookie,
2326 priv->strRemainOnChanParams.pstrListenChan,
2327 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002328 }
2329
2330 return 0;
2331}
2332
2333/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002334 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002335 * @details Notify driver that a management frame type was
2336 * registered. Note that this callback may not sleep, and cannot run
2337 * concurrently with itself.
2338 * @param[in]
2339 * @return NONE.
2340 * @author mdaftedar
2341 * @date 01 JUL 2012
2342 * @version
2343 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002344void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2345 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002346{
2347
Chaehyun Lim27268872015-09-15 14:06:13 +09002348 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002349 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002350 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002351
2352 priv = wiphy_priv(wiphy);
2353 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002354 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002355
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002356 if (!frame_type)
2357 return;
2358
2359 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2360 switch (frame_type) {
2361 case PROBE_REQ:
2362 {
2363 nic->g_struct_frame_reg[0].frame_type = frame_type;
2364 nic->g_struct_frame_reg[0].reg = reg;
2365 }
2366 break;
2367
2368 case ACTION:
2369 {
2370 nic->g_struct_frame_reg[1].frame_type = frame_type;
2371 nic->g_struct_frame_reg[1].reg = reg;
2372 }
2373 break;
2374
2375 default:
2376 {
2377 break;
2378 }
2379
2380 }
2381 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002382 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002383 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2384 return;
2385 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002386 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002387
2388
2389}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002390
2391/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002392 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393 * @details Configure connection quality monitor RSSI threshold.
2394 * @param[in] struct wiphy *wiphy:
2395 * @param[in] struct net_device *dev:
2396 * @param[in] s32 rssi_thold:
2397 * @param[in] u32 rssi_hyst:
2398 * @return int : Return 0 on Success
2399 * @author mdaftedar
2400 * @date 01 MAR 2012
2401 * @version 1.0
2402 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002403static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2404 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002405{
2406 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2407 return 0;
2408
2409}
2410/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002411 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002412 * @details Configure connection quality monitor RSSI threshold.
2413 * @param[in] struct wiphy *wiphy:
2414 * @param[in] struct net_device *dev
2415 * @param[in] int idx
2416 * @param[in] u8 *mac
2417 * @param[in] struct station_info *sinfo
2418 * @return int : Return 0 on Success
2419 * @author mdaftedar
2420 * @date 01 MAR 2012
2421 * @version 1.0
2422 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002423static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2424 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002425{
Chaehyun Lim27268872015-09-15 14:06:13 +09002426 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002427
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002428 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2429
2430 if (idx != 0)
2431 return -ENOENT;
2432
2433 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002434
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002435 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002436
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002437 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002438
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002439 return 0;
2440
2441}
2442
2443
2444/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002445 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002446 * @details
2447 * @param[in]
2448 * @return int : Return 0 on Success.
2449 * @author mdaftedar
2450 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002451 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002452 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002453static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2454 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002455{
Chaehyun Lim27268872015-09-15 14:06:13 +09002456 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002457
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002458 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2459
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002460 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002461 return -ENOENT;
2462
2463 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002464 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002465 PRINT_ER("Driver is NULL\n");
2466 return -EIO;
2467 }
2468
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002469 if (wilc_enable_ps)
2470 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002471
2472
Leo Kime6e12662015-09-16 18:36:03 +09002473 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002474
2475}
Glen Lee108b3432015-09-16 18:53:20 +09002476
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002477/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002478 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002479 * @details Change type/configuration of virtual interface,
2480 * keep the struct wireless_dev's iftype updated.
2481 * @param[in] NONE
2482 * @return int : Return 0 on Success.
2483 * @author mdaftedar
2484 * @date 01 MAR 2012
2485 * @version 1.0
2486 */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002487int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic);
2488
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002489static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2490 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002491{
Chaehyun Lim27268872015-09-15 14:06:13 +09002492 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002493 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002494 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002495 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002496 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002497 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002498
2499 nic = netdev_priv(dev);
2500 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002501 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002502
2503 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2504 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2505 u8P2Plocalrandom = 0x01;
2506 u8P2Precvrandom = 0x00;
2507
Dean Lee72ed4dc2015-06-12 14:11:44 +09002508 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002509
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002510 wilc_optaining_ip = false;
2511 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002512 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002513 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2514 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002515 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002516 }
2517
2518 switch (type) {
2519 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002520 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002521 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002522
2523 /* send delba over wlan interface */
2524
2525
2526 dev->ieee80211_ptr->iftype = type;
2527 priv->wdev->iftype = type;
2528 nic->monitor_flag = 0;
2529 nic->iftype = STATION_MODE;
2530
2531 /*Remove the enteries of the previously connected clients*/
2532 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002533 interface_type = nic->iftype;
2534 nic->iftype = STATION_MODE;
2535
Glen Lee299382c2015-10-20 17:13:56 +09002536 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002537 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2538 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002539 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002540 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002541
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002542 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002543 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002544
Glen Lee53dc0cf2015-10-20 17:13:57 +09002545 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002546 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002547 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002548 nic->iftype = interface_type;
2549
2550 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002551 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2552 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002553 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002554 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002555
2556 /*Add saved WEP keys, if any*/
2557 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002558 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002559 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002560 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002561 g_key_wep_params.key,
2562 g_key_wep_params.key_len,
2563 g_key_wep_params.key_idx);
2564 }
2565
2566 /*No matter the driver handler passed here, it will be overwriiten*/
2567 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002568 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002569
2570 /*Add saved PTK and GTK keys, if any*/
2571 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2572 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2573 g_key_ptk_params.key[1],
2574 g_key_ptk_params.key[2]);
2575 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2576 g_key_gtk_params.key[1],
2577 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002578 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2579 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002580 g_add_ptk_key_params.key_idx,
2581 g_add_ptk_key_params.pairwise,
2582 g_add_ptk_key_params.mac_addr,
2583 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002584
Glen Lee299382c2015-10-20 17:13:56 +09002585 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2586 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002587 g_add_gtk_key_params.key_idx,
2588 g_add_gtk_key_params.pairwise,
2589 g_add_gtk_key_params.mac_addr,
2590 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002591 }
2592
Glen Lee299382c2015-10-20 17:13:56 +09002593 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594 for (i = 0; i < num_reg_frame; i++) {
2595 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2596 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002597 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002598 nic->g_struct_frame_reg[i].frame_type,
2599 nic->g_struct_frame_reg[i].reg);
2600 }
2601 }
2602
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002603 wilc_enable_ps = true;
2604 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002605 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002606 break;
2607
2608 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002609 wilc_enable_ps = false;
2610 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2611 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002612 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002613
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002614 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2615 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002616
2617 dev->ieee80211_ptr->iftype = type;
2618 priv->wdev->iftype = type;
2619 nic->monitor_flag = 0;
2620
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002621 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2622 nic->iftype = CLIENT_MODE;
2623
2624
Glen Lee299382c2015-10-20 17:13:56 +09002625 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002626 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002627 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002628
Glen Lee53dc0cf2015-10-20 17:13:57 +09002629 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002630 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002631 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002632
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002633 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2634 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002635 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002636 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002637
2638 /*Add saved WEP keys, if any*/
2639 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002640 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2641 g_key_wep_params.key_idx);
2642 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2643 g_key_wep_params.key,
2644 g_key_wep_params.key_len,
2645 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002646 }
2647
2648 /*No matter the driver handler passed here, it will be overwriiten*/
2649 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002650 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002651
2652 /*Add saved PTK and GTK keys, if any*/
2653 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2654 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2655 g_key_ptk_params.key[1],
2656 g_key_ptk_params.key[2]);
2657 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2658 g_key_gtk_params.key[1],
2659 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002660 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2661 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002662 g_add_ptk_key_params.key_idx,
2663 g_add_ptk_key_params.pairwise,
2664 g_add_ptk_key_params.mac_addr,
2665 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002666
Glen Lee299382c2015-10-20 17:13:56 +09002667 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2668 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002669 g_add_gtk_key_params.key_idx,
2670 g_add_gtk_key_params.pairwise,
2671 g_add_gtk_key_params.mac_addr,
2672 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002673 }
2674
2675 /*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 +09002676 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002677 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002678
Glen Lee299382c2015-10-20 17:13:56 +09002679 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002680 for (i = 0; i < num_reg_frame; i++) {
2681 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2682 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002683 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002684 nic->g_struct_frame_reg[i].frame_type,
2685 nic->g_struct_frame_reg[i].reg);
2686 }
2687 }
2688 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002689 break;
2690
2691 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002692 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002693 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002694 dev->ieee80211_ptr->iftype = type;
2695 priv->wdev->iftype = type;
2696 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002697 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002698
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002699 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002700 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002701 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002702 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002703 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002704 wilc_mac_close(dev);
2705 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002706
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002707 for (i = 0; i < num_reg_frame; i++) {
2708 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2709 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002710 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002711 nic->g_struct_frame_reg[i].frame_type,
2712 nic->g_struct_frame_reg[i].reg);
2713 }
2714 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002715 break;
2716
2717 case NL80211_IFTYPE_P2P_GO:
2718 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2719
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002720 wilc_optaining_ip = true;
2721 mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME));
2722 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002723 /*Delete block ack has to be the latest config packet*/
2724 /*sent before downloading new FW. This is because it blocks on*/
2725 /*hWaitResponse semaphore, which allows previous config*/
2726 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002727 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2728 wl->vif[0].bssid, TID);
2729 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002730 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002731 dev->ieee80211_ptr->iftype = type;
2732 priv->wdev->iftype = type;
2733
Johnny Kim8a143302015-06-10 17:06:46 +09002734 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002735
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002736 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2737
2738
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002739 nic->iftype = GO_MODE;
2740
2741 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002742 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002743 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002745 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002746
2747
2748 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002749 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2750 wilc_set_mac_address(wl->vif[0].hif_drv,
2751 wl->vif[0].src_addr);
2752 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002753
2754 /*Add saved WEP keys, if any*/
2755 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002756 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2757 g_key_wep_params.key_idx);
2758 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759 g_key_wep_params.key,
2760 g_key_wep_params.key_len,
2761 g_key_wep_params.key_idx);
2762 }
2763
2764 /*No matter the driver handler passed here, it will be overwriiten*/
2765 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002766 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002767
2768 /*Add saved PTK and GTK keys, if any*/
2769 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2770 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2771 g_key_ptk_params.key[1],
2772 g_key_ptk_params.key[2],
2773 g_key_ptk_params.cipher);
2774 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2775 g_key_gtk_params.key[1],
2776 g_key_gtk_params.key[2],
2777 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002778 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2779 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002780 g_add_ptk_key_params.key_idx,
2781 g_add_ptk_key_params.pairwise,
2782 g_add_ptk_key_params.mac_addr,
2783 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002784
Glen Lee299382c2015-10-20 17:13:56 +09002785 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2786 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002787 g_add_gtk_key_params.key_idx,
2788 g_add_gtk_key_params.pairwise,
2789 g_add_gtk_key_params.mac_addr,
2790 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002792
Glen Lee299382c2015-10-20 17:13:56 +09002793 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002794 for (i = 0; i < num_reg_frame; i++) {
2795 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2796 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002797 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002798 nic->g_struct_frame_reg[i].frame_type,
2799 nic->g_struct_frame_reg[i].reg);
2800 }
2801 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002802 break;
2803
2804 default:
2805 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002806 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002807 }
2808
Leo Kimaaed3292015-10-12 16:55:38 +09002809 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002810}
2811
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002812/* (austin.2013-07-23)
2813 *
2814 * To support revised cfg80211_ops
2815 *
2816 * add_beacon --> start_ap
2817 * set_beacon --> change_beacon
2818 * del_beacon --> stop_ap
2819 *
2820 * beacon_parameters --> cfg80211_ap_settings
2821 * cfg80211_beacon_data
2822 *
2823 * applicable for linux kernel 3.4+
2824 */
2825
2826/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002827 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002828 * @details Add a beacon with given parameters, @head, @interval
2829 * and @dtim_period will be valid, @tail is optional.
2830 * @param[in] wiphy
2831 * @param[in] dev The net device structure
2832 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2833 * @return int : Return 0 on Success.
2834 * @author austin
2835 * @date 23 JUL 2013
2836 * @version 1.0
2837 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002838static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2839 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002840{
2841 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002842 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002843 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002844 struct wilc *wl;
2845 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002846
2847 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002848 nic = netdev_priv(dev);
2849 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002850 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2851
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302852 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 +09002853 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2854
Chaehyun Lim80785a92015-09-14 12:24:01 +09002855 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002856
Leo Kime6e12662015-09-16 18:36:03 +09002857 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002858 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002859
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002860 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002861
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002862 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002863 settings->beacon_interval,
2864 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002865 beacon->head_len, (u8 *)beacon->head,
2866 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002867
2868 return s32Error;
2869}
2870
2871/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002872 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002873 * @details Add a beacon with given parameters, @head, @interval
2874 * and @dtim_period will be valid, @tail is optional.
2875 * @param[in] wiphy
2876 * @param[in] dev The net device structure
2877 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2878 * @return int : Return 0 on Success.
2879 * @author austin
2880 * @date 23 JUL 2013
2881 * @version 1.0
2882 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002883static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2884 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002885{
Chaehyun Lim27268872015-09-15 14:06:13 +09002886 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002887 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002888
2889 priv = wiphy_priv(wiphy);
2890 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2891
2892
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002893 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002894 0,
2895 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002896 beacon->head_len, (u8 *)beacon->head,
2897 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002898
2899 return s32Error;
2900}
2901
2902/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002903 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002904 * @details Remove beacon configuration and stop sending the beacon.
2905 * @param[in]
2906 * @return int : Return 0 on Success.
2907 * @author austin
2908 * @date 23 JUL 2013
2909 * @version 1.0
2910 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002911static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912{
Leo Kime6e12662015-09-16 18:36:03 +09002913 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002914 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002915 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002916
Leo Kim7ae43362015-09-16 18:35:59 +09002917 if (!wiphy)
2918 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002919
2920 priv = wiphy_priv(wiphy);
2921
2922 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2923
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002924 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002925
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002926 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002927
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002928 if (s32Error)
2929 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002930
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002931 return s32Error;
2932}
2933
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002934/**
Chaehyun Limed269552015-09-14 12:24:15 +09002935 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002936 * @details Add a new station.
2937 * @param[in]
2938 * @return int : Return 0 on Success.
2939 * @author mdaftedar
2940 * @date 01 MAR 2012
2941 * @version 1.0
2942 */
Chaehyun Limed269552015-09-14 12:24:15 +09002943static int add_station(struct wiphy *wiphy, struct net_device *dev,
2944 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002945{
Leo Kime6e12662015-09-16 18:36:03 +09002946 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002947 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002948 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002949 perInterface_wlan_t *nic;
2950
Leo Kim7ae43362015-09-16 18:35:59 +09002951 if (!wiphy)
2952 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002953
2954 priv = wiphy_priv(wiphy);
2955 nic = netdev_priv(dev);
2956
2957 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002958 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002959 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002960 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002961 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002962 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002963
2964 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2965
2966 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],
2967 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002968 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002969 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2970 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002971
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002972 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09002973 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002974 } else {
Leo Kim22520122015-10-29 12:05:45 +09002975 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002976 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002977 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002978 memcpy(strStaParams.ht_supp_mcs_set,
2979 &params->ht_capa->mcs,
2980 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002981 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002982 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002983 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002984 }
2985
Leo Kimf676e172015-10-29 12:05:52 +09002986 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002987 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002988
Leo Kim22520122015-10-29 12:05:45 +09002989 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2990 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002991 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2992 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002993 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2994 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002995 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2996 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002997 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2998 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002999 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3000 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003001 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3002 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003003 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3004 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003005
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003006 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003007 if (s32Error)
3008 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003009 }
3010
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003011 return s32Error;
3012}
3013
3014/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003015 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003016 * @details Remove a station; @mac may be NULL to remove all stations.
3017 * @param[in]
3018 * @return int : Return 0 on Success.
3019 * @author mdaftedar
3020 * @date 01 MAR 2012
3021 * @version 1.0
3022 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003023static int del_station(struct wiphy *wiphy, struct net_device *dev,
3024 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003025{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003026 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003027 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003028 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003029 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003030
Leo Kim7ae43362015-09-16 18:35:59 +09003031 if (!wiphy)
3032 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003033
3034 priv = wiphy_priv(wiphy);
3035 nic = netdev_priv(dev);
3036
3037 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3038 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3039
3040
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003041 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303042 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003043 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003044 } else {
3045 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]);
3046 }
3047
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003048 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003049
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003050 if (s32Error)
3051 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003052 }
3053 return s32Error;
3054}
3055
3056/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003057 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003058 * @details Modify a given station.
3059 * @param[in]
3060 * @return int : Return 0 on Success.
3061 * @author mdaftedar
3062 * @date 01 MAR 2012
3063 * @version 1.0
3064 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003065static int change_station(struct wiphy *wiphy, struct net_device *dev,
3066 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003067{
Leo Kime6e12662015-09-16 18:36:03 +09003068 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003069 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003070 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003071 perInterface_wlan_t *nic;
3072
3073
3074 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3075
Leo Kim7ae43362015-09-16 18:35:59 +09003076 if (!wiphy)
3077 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003078
3079 priv = wiphy_priv(wiphy);
3080 nic = netdev_priv(dev);
3081
3082 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003083 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003084 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003085 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003086 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003087
Leo Kim2353c382015-10-29 12:05:41 +09003088 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3089 strStaParams.bssid[0], strStaParams.bssid[1],
3090 strStaParams.bssid[2], strStaParams.bssid[3],
3091 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003092 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003093 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3094 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003095
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003096 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003097 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003098 } else {
Leo Kim22520122015-10-29 12:05:45 +09003099 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003100 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003101 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003102 memcpy(strStaParams.ht_supp_mcs_set,
3103 &params->ht_capa->mcs,
3104 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003105 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003106 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003107 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003108 }
3109
Leo Kimf676e172015-10-29 12:05:52 +09003110 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003111 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003112
Leo Kim22520122015-10-29 12:05:45 +09003113 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3114 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003115 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3116 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003117 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3118 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003119 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3120 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003121 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3122 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003123 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3124 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003125 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3126 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003127 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3128 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003129
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003130 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003131 if (s32Error)
3132 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003133 }
3134 return s32Error;
3135}
3136
3137
3138/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003139 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003140 * @details
3141 * @param[in]
3142 * @return int : Return 0 on Success.
3143 * @author mdaftedar
3144 * @date 01 JUL 2012
3145 * @version 1.0
3146 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003147static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3148 const char *name,
3149 unsigned char name_assign_type,
3150 enum nl80211_iftype type,
3151 u32 *flags,
3152 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003153{
3154 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003155 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003156 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003157
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003158 priv = wiphy_priv(wiphy);
3159
3160
3161
3162 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3163
3164 nic = netdev_priv(priv->wdev->netdev);
3165
3166
3167 if (type == NL80211_IFTYPE_MONITOR) {
3168 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3169 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3170 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3171 if (new_ifc != NULL) {
3172 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003173 nic = netdev_priv(priv->wdev->netdev);
3174 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003175 } else
3176 PRINT_ER("Error in initializing monitor interface\n ");
3177 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003178 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003179}
3180
3181/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003182 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003183 * @details
3184 * @param[in]
3185 * @return int : Return 0 on Success.
3186 * @author mdaftedar
3187 * @date 01 JUL 2012
3188 * @version 1.0
3189 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003190static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003191{
3192 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003193 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003194}
3195
Chaehyun Lim08241922015-09-15 14:06:12 +09003196static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003197
Chaehyun Lim80785a92015-09-14 12:24:01 +09003198 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003199 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003200 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003201 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003202 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003203 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003204 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003205 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003206 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003207 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003208 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003209
Chaehyun Lima13168d2015-09-14 12:24:12 +09003210 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003211 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003212 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003213 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003214 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003215 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003216 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003217 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003218 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003219 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003220
Chaehyun Lim4d466572015-09-14 12:24:22 +09003221 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003222 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003223 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003224 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003225 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003226 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003227 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003228 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003229 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003230 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003231
3232};
3233
3234
3235
3236
3237
3238/**
3239 * @brief WILC_WFI_update_stats
3240 * @details Modify parameters for a given BSS.
3241 * @param[in]
3242 * @return int : Return 0 on Success.
3243 * @author mdaftedar
3244 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003245 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003246 */
3247int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3248{
3249
Chaehyun Lim27268872015-09-15 14:06:13 +09003250 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003251
3252 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003253 switch (changed) {
3254
3255 case WILC_WFI_RX_PKT:
3256 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003257 priv->netstats.rx_packets++;
3258 priv->netstats.rx_bytes += pktlen;
3259 priv->netstats.rx_time = get_jiffies_64();
3260 }
3261 break;
3262
3263 case WILC_WFI_TX_PKT:
3264 {
3265 priv->netstats.tx_packets++;
3266 priv->netstats.tx_bytes += pktlen;
3267 priv->netstats.tx_time = get_jiffies_64();
3268
3269 }
3270 break;
3271
3272 default:
3273 break;
3274 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003275 return 0;
3276}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003277
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003278/**
3279 * @brief WILC_WFI_CfgAlloc
3280 * @details Allocation of the wireless device structure and assigning it
3281 * to the cfg80211 operations structure.
3282 * @param[in] NONE
3283 * @return wireless_dev : Returns pointer to wireless_dev structure.
3284 * @author mdaftedar
3285 * @date 01 MAR 2012
3286 * @version 1.0
3287 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003288static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003289{
3290
3291 struct wireless_dev *wdev;
3292
3293
3294 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3295 /*Allocating the wireless device structure*/
3296 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3297 if (!wdev) {
3298 PRINT_ER("Cannot allocate wireless device\n");
3299 goto _fail_;
3300 }
3301
3302 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003303 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003304 if (!wdev->wiphy) {
3305 PRINT_ER("Cannot allocate wiphy\n");
3306 goto _fail_mem_;
3307
3308 }
3309
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003310 /* enable 802.11n HT */
3311 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3312 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3313 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3314 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3315 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003316
3317 /*wiphy bands*/
3318 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3319
3320 return wdev;
3321
3322_fail_mem_:
3323 kfree(wdev);
3324_fail_:
3325 return NULL;
3326
3327}
3328/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003329 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003330 * @details Registering of the wiphy structure and interface modes
3331 * @param[in] NONE
3332 * @return NONE
3333 * @author mdaftedar
3334 * @date 01 MAR 2012
3335 * @version 1.0
3336 */
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003337struct wireless_dev *wilc_create_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003338{
Chaehyun Lim27268872015-09-15 14:06:13 +09003339 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003340 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003341 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003342
3343 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3344
3345 wdev = WILC_WFI_CfgAlloc();
3346 if (wdev == NULL) {
3347 PRINT_ER("CfgAlloc Failed\n");
3348 return NULL;
3349 }
3350
3351
3352 /*Return hardware description structure (wiphy)'s priv*/
3353 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003354 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003355
3356 /*Link the wiphy with wireless structure*/
3357 priv->wdev = wdev;
3358
3359 /*Maximum number of probed ssid to be added by user for the scan request*/
3360 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003361 /*Maximum number of pmkids to be cashed*/
3362 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3363 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003364
3365 wdev->wiphy->max_scan_ie_len = 1000;
3366
3367 /*signal strength in mBm (100*dBm) */
3368 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3369
3370 /*Set the availaible cipher suites*/
3371 wdev->wiphy->cipher_suites = cipher_suites;
3372 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003373 /*Setting default managment types: for register action frame: */
3374 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003375
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003376 wdev->wiphy->max_remain_on_channel_duration = 500;
3377 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3378 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3379 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003380 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003381 wdev->iftype = NL80211_IFTYPE_STATION;
3382
3383
3384
3385 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3386 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3387 wdev->wiphy->interface_modes, wdev->iftype);
3388
3389 #ifdef WILC_SDIO
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003390 set_wiphy_dev(wdev->wiphy, &wilc_sdio_func->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003391 #endif
3392
3393 /*Register wiphy structure*/
3394 s32Error = wiphy_register(wdev->wiphy);
3395 if (s32Error) {
3396 PRINT_ER("Cannot register wiphy device\n");
3397 /*should define what action to be taken in such failure*/
3398 } else {
3399 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3400 }
3401
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003402 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003403 return wdev;
3404
3405
3406}
3407/**
3408 * @brief WILC_WFI_WiphyFree
3409 * @details Freeing allocation of the wireless device structure
3410 * @param[in] NONE
3411 * @return NONE
3412 * @author mdaftedar
3413 * @date 01 MAR 2012
3414 * @version 1.0
3415 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003416int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003417{
3418
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003419 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003420
Chaehyun Lim27268872015-09-15 14:06:13 +09003421 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003422
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003423 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3424 priv = wdev_priv(net->ieee80211_ptr);
3425 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003426 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003427 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003428 }
3429 op_ifcs++;
3430 if (s32Error < 0) {
3431 PRINT_ER("Failed to creat refresh Timer\n");
3432 return s32Error;
3433 }
3434
Dean Lee72ed4dc2015-06-12 14:11:44 +09003435 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003436
Dean Lee72ed4dc2015-06-12 14:11:44 +09003437 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003438
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003439 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003440 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003441 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003442 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003443
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003444 return s32Error;
3445}
3446
3447/**
3448 * @brief WILC_WFI_WiphyFree
3449 * @details Freeing allocation of the wireless device structure
3450 * @param[in] NONE
3451 * @return NONE
3452 * @author mdaftedar
3453 * @date 01 MAR 2012
3454 * @version 1.0
3455 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003456int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003457{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003458 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003459
Chaehyun Lim27268872015-09-15 14:06:13 +09003460 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003461
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003462 priv = wdev_priv(net->ieee80211_ptr);
3463
Dean Lee72ed4dc2015-06-12 14:11:44 +09003464 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003465
Dean Lee72ed4dc2015-06-12 14:11:44 +09003466 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003467
3468 op_ifcs--;
3469
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003470 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003471
3472 /* Clear the Shadow scan */
3473 clear_shadow_scan(priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003474 if (op_ifcs == 0) {
3475 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003476 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003477 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003478
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003479 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003480 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003481
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003482 return s32Error;
3483}
3484
3485
3486/**
3487 * @brief WILC_WFI_WiphyFree
3488 * @details Freeing allocation of the wireless device structure
3489 * @param[in] NONE
3490 * @return NONE
3491 * @author mdaftedar
3492 * @date 01 MAR 2012
3493 * @version 1.0
3494 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003495void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003496{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003497 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3498
Chaehyun Lim619837a2015-09-20 15:51:10 +09003499 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003500 PRINT_D(INIT_DBG, "net_device is NULL\n");
3501 return;
3502 }
3503
Chaehyun Lim619837a2015-09-20 15:51:10 +09003504 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003505 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3506 return;
3507 }
3508
Chaehyun Lim619837a2015-09-20 15:51:10 +09003509 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003510 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3511 return;
3512 }
3513
3514 wiphy_unregister(net->ieee80211_ptr->wiphy);
3515
3516 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3517 wiphy_free(net->ieee80211_ptr->wiphy);
3518 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003519}