blob: 49b82b4a068840c959cc599b8c9981c7709f56ea [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
Arnd Bergmann491880e2015-11-16 15:04:55 +010017#include "host_interface.h"
Leo Kim7ae43362015-09-16 18:35:59 +090018#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +090019
20#define IS_MANAGMEMENT 0x100
21#define IS_MANAGMEMENT_CALLBACK 0x080
22#define IS_MGMT_STATUS_SUCCES 0x040
23#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
24
Arnd Bergmann0e1af732015-11-16 15:04:54 +010025extern int wilc_mac_open(struct net_device *ndev);
26extern int wilc_mac_close(struct net_device *ndev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090027
Arnd Bergmann1608c402015-11-16 15:04:53 +010028static tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
29static u32 u32LastScannedNtwrksCountShadow;
Arnd Bergmann0e1af732015-11-16 15:04:54 +010030struct timer_list wilc_during_ip_timer;
Arnd Bergmann1608c402015-11-16 15:04:53 +010031static struct timer_list hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +090032static u8 op_ifcs;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090033
Arnd Bergmann0e1af732015-11-16 15:04:54 +010034u8 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090035
36#define CHAN2G(_channel, _freq, _flags) { \
37 .band = IEEE80211_BAND_2GHZ, \
38 .center_freq = (_freq), \
39 .hw_value = (_channel), \
40 .flags = (_flags), \
41 .max_antenna_gain = 0, \
42 .max_power = 30, \
43}
44
45/*Frequency range for channels*/
46static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
47 CHAN2G(1, 2412, 0),
48 CHAN2G(2, 2417, 0),
49 CHAN2G(3, 2422, 0),
50 CHAN2G(4, 2427, 0),
51 CHAN2G(5, 2432, 0),
52 CHAN2G(6, 2437, 0),
53 CHAN2G(7, 2442, 0),
54 CHAN2G(8, 2447, 0),
55 CHAN2G(9, 2452, 0),
56 CHAN2G(10, 2457, 0),
57 CHAN2G(11, 2462, 0),
58 CHAN2G(12, 2467, 0),
59 CHAN2G(13, 2472, 0),
60 CHAN2G(14, 2484, 0),
61};
62
63#define RATETAB_ENT(_rate, _hw_value, _flags) { \
64 .bitrate = (_rate), \
65 .hw_value = (_hw_value), \
66 .flags = (_flags), \
67}
68
69
70/* Table 6 in section 3.2.1.1 */
71static struct ieee80211_rate WILC_WFI_rates[] = {
72 RATETAB_ENT(10, 0, 0),
73 RATETAB_ENT(20, 1, 0),
74 RATETAB_ENT(55, 2, 0),
75 RATETAB_ENT(110, 3, 0),
76 RATETAB_ENT(60, 9, 0),
77 RATETAB_ENT(90, 6, 0),
78 RATETAB_ENT(120, 7, 0),
79 RATETAB_ENT(180, 8, 0),
80 RATETAB_ENT(240, 9, 0),
81 RATETAB_ENT(360, 10, 0),
82 RATETAB_ENT(480, 11, 0),
83 RATETAB_ENT(540, 12, 0),
84};
85
Johnny Kimc5c77ba2015-05-11 14:30:56 +090086struct p2p_mgmt_data {
87 int size;
88 u8 *buff;
89};
90
91/*Global variable used to state the current connected STA channel*/
Arnd Bergmann1608c402015-11-16 15:04:53 +010092static u8 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090093
Arnd Bergmann1608c402015-11-16 15:04:53 +010094static u8 curr_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090095
Arnd Bergmann1608c402015-11-16 15:04:53 +010096static u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
97static u8 u8P2Plocalrandom = 0x01;
98static u8 u8P2Precvrandom = 0x00;
99static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
100static bool bWilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900101
102static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
103 .channels = WILC_WFI_2ghz_channels,
104 .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels),
105 .bitrates = WILC_WFI_rates,
106 .n_bitrates = ARRAY_SIZE(WILC_WFI_rates),
107};
108
109
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900110struct add_key_params {
111 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900112 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900113 u8 *mac_addr;
114};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100115static struct add_key_params g_add_gtk_key_params;
116static struct wilc_wfi_key g_key_gtk_params;
117static struct add_key_params g_add_ptk_key_params;
118static struct wilc_wfi_key g_key_ptk_params;
119static struct wilc_wfi_wep_key g_key_wep_params;
120static bool g_ptk_keys_saved;
121static bool g_gtk_keys_saved;
122static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900123
124#define AGING_TIME (9 * 1000)
125#define duringIP_TIME 15000
126
Arnd Bergmann1608c402015-11-16 15:04:53 +0100127static void clear_shadow_scan(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900128{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900129 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900130
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900131 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700132 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900133 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
134
135 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
136 if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +0900137 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900138 astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL;
139 }
140
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100141 wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900142 astrLastScannedNtwrksShadow[i].pJoinParams = NULL;
143 }
144 u32LastScannedNtwrksCountShadow = 0;
145 }
146
147}
148
Arnd Bergmann1608c402015-11-16 15:04:53 +0100149static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900150{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900151 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900152 int rssi_v = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900153 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900154
155 for (i = 0; i < num_rssi; i++)
156 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
157
158 rssi_v /= num_rssi;
159 return rssi_v;
160}
161
Arnd Bergmann1608c402015-11-16 15:04:53 +0100162static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900163{
Chaehyun Lim27268872015-09-15 14:06:13 +0900164 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900165 struct wiphy *wiphy;
166 struct cfg80211_bss *bss = NULL;
167 int i;
168 int rssi = 0;
169
Chaehyun Lim27268872015-09-15 14:06:13 +0900170 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900171 wiphy = priv->dev->ieee80211_ptr->wiphy;
172
173 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
174 tstrNetworkInfo *pstrNetworkInfo;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900175
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900176 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
177
178
179 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900180 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900181 struct ieee80211_channel *channel;
182
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900183 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900184
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900185 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900186 channel = ieee80211_get_channel(wiphy, s32Freq);
187
188 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900189 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900190 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
191 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900192 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900193 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900194 }
195 }
196
197 }
198 }
199
200}
201
Arnd Bergmann1608c402015-11-16 15:04:53 +0100202static void reset_shadow_found(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900203{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900204 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900205
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900206 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
207 astrLastScannedNtwrksShadow[i].u8Found = 0;
208
209 }
210}
211
Arnd Bergmann1608c402015-11-16 15:04:53 +0100212static void update_scan_time(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900213{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900214 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900215
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900216 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
217 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
218 }
219}
220
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700221static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900222{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900223 unsigned long now = jiffies;
224 int i, j;
225
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900226
227 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
228 if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530229 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900230
Shraddha Barkecccfc392015-10-12 20:49:19 +0530231 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
232 astrLastScannedNtwrksShadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900233
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100234 wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900235
236 for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) {
237 astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1];
238 }
239 u32LastScannedNtwrksCountShadow--;
240 }
241 }
242
243 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow);
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700244 if (u32LastScannedNtwrksCountShadow != 0) {
245 hAgingTimer.data = arg;
246 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
247 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900248 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700249 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900250}
251
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700252static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900253{
254 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100255 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900256}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900257
Arnd Bergmann1608c402015-11-16 15:04:53 +0100258static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900259{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900260 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900261 int i;
262
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900263 if (u32LastScannedNtwrksCountShadow == 0) {
264 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700265 hAgingTimer.data = (unsigned long)pUserVoid;
266 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900267 state = -1;
268 } else {
269 /* Linear search for now */
270 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900271 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900272 pstrNetworkInfo->au8bssid, 6) == 0) {
273 state = i;
274 break;
275 }
276 }
277 }
278 return state;
279}
280
Arnd Bergmann1608c402015-11-16 15:04:53 +0100281static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900282{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900283 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900284 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900285 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900286
287 if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
288 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
289 return;
290 }
291 if (ap_found == -1) {
292 ap_index = u32LastScannedNtwrksCountShadow;
293 u32LastScannedNtwrksCountShadow++;
294
295 } else {
296 ap_index = ap_found;
297 }
298 rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
299 astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
300 if (rssi_index == NUM_RSSI) {
301 rssi_index = 0;
302 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
303 }
304 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
305
306 astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
307 astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
308
309 astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900310 memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900311 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
312
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900313 memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900314 pstrNetworkInfo->au8bssid, ETH_ALEN);
315
316 astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
317 astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
318 astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
319
320 astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
321 astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
322 if (ap_found != -1)
Chaehyun Lim49188af2015-08-11 10:32:41 +0900323 kfree(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900324 astrLastScannedNtwrksShadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900325 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900326 memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900327 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
328
329 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
330 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
331 astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
332 if (ap_found != -1)
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100333 wilc_free_join_params(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900334 astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
335
336}
337
338
339/**
340 * @brief CfgScanResult
341 * @details Callback function which returns the scan results found
342 *
343 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
344 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
345 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
346 * void* pUserVoid: Private structure associated with the wireless interface
347 * @return NONE
348 * @author mabubakr
349 * @date
350 * @version 1.0
351 */
Leo Kim1ec38152015-10-12 16:55:59 +0900352static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900353{
Chaehyun Lim27268872015-09-15 14:06:13 +0900354 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900355 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900356 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900357 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900358 struct cfg80211_bss *bss = NULL;
359
Chaehyun Lim27268872015-09-15 14:06:13 +0900360 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100361 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900362 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
363 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900364
365 if (!wiphy)
366 return;
367
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900368 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
369 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900370 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900371 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900372 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900373 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900374 PRINT_ER("wiphy signal type fial\n");
375 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900376 }
377
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900378 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900379 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900380 channel = ieee80211_get_channel(wiphy, s32Freq);
381
Leo Kim7ae43362015-09-16 18:35:59 +0900382 if (!channel)
383 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900384
385 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530386 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900387 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
388
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100389 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900390 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
391 /* max_scan_ssids */
392 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
393
394
395 priv->u32RcvdChCount++;
396
397
398
399 if (pJoinParams == NULL) {
400 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
401 }
402 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
403
404 /*P2P peers are sent to WPA supplicant and added to shadow table*/
405
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900406 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900407 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
408 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900409 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900410 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900411 }
412
413
414 } else {
415 PRINT_ER("Discovered networks exceeded the max limit\n");
416 }
417 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900418 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900419 /* So this network is discovered before, we'll just update its RSSI */
420 for (i = 0; i < priv->u32RcvdChCount; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900421 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530422 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900423
424 astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
425 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
426 break;
427 }
428 }
429 }
430 }
431 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530432 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
433 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900434 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900435
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530436 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530437 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530438 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530439 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900440
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200441 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900442
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900443 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900444 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900445 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900446 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900447 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900448 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200449 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900450
451 }
452 /*Aborting any scan operation during mac close*/
453 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200454 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900455
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530456 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900457 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458
459 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900460 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900461
Dean Lee72ed4dc2015-06-12 14:11:44 +0900462 cfg80211_scan_done(priv->pstrScanReq, false);
463 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900464 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900465 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200466 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900467 }
468 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900469}
470
471
472/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900473 * @brief CfgConnectResult
474 * @details
475 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
476 * connection response or disconnection notification.
477 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900478 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900479 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
480 * void* pUserVoid: Private data associated with wireless interface
481 * @return NONE
482 * @author mabubakr
483 * @date 01 MAR 2012
484 * @version 1.0
485 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100486int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900487
Leo Kimed3f0372015-10-12 16:56:01 +0900488static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900489 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900490 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900491 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
492 void *pUserVoid)
493{
Chaehyun Lim27268872015-09-15 14:06:13 +0900494 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900495 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900496 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900497 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900498 struct wilc *wl;
499 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900500
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100501 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900502
Chaehyun Lim27268872015-09-15 14:06:13 +0900503 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900504 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900505 nic = netdev_priv(dev);
506 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900507 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900508
509 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
510 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530511 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900512
513 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
514
515 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
516
517 if ((u8MacStatus == MAC_DISCONNECTED) &&
518 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
519 /* The case here is that our station was waiting for association response frame and has just received it containing status code
520 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
521 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100522 wilc_wlan_set_bssid(priv->dev, NullBssid);
523 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900524
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900525 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900526 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900527 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900528
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530529 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900530 }
531
532 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900533 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900534 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900535
536 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
537 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900538 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900539
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900540
541 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900542 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900543 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
544 unsigned long now = jiffies;
545
546 if (time_after(now,
547 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900548 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900549 }
550
551 break;
552 }
553 }
554
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000555 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900556 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900557 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900558
559 }
560
561 }
562
563
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530564 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900565
566 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
567
568 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
569 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
570 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
571 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
572 /* be replaced by pstrConnectInfo->u16ConnectStatus */
573 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100574 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900575 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
576 pstrDisconnectNotifInfo->u16reason, priv->dev);
577 u8P2Plocalrandom = 0x01;
578 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900579 bWilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530580 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100581 wilc_wlan_set_bssid(priv->dev, NullBssid);
582 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900583
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900584 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900585 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900586 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900587 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
588 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900589 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900590 pstrDisconnectNotifInfo->u16reason = 3;
591 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900592 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
593 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900594 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900595 pstrDisconnectNotifInfo->u16reason = 1;
596 }
597 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530598 pstrDisconnectNotifInfo->ie_len, false,
599 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900600
601 }
602
603}
604
605
606/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900607 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900608 * @details Set channel for a given wireless interface. Some devices
609 * may support multi-channel operation (by channel hopping) so cfg80211
610 * doesn't verify much. Note, however, that the passed netdev may be
611 * %NULL as well if the user requested changing the channel for the
612 * device itself, or for a monitor interface.
613 * @param[in]
614 * @return int : Return 0 on Success
615 * @author mdaftedar
616 * @date 01 MAR 2012
617 * @version 1.0
618 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900619static int set_channel(struct wiphy *wiphy,
620 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900621{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900622 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900623 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900624 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900625
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900626 priv = wiphy_priv(wiphy);
627
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900628 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
629 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900630
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900631 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100632 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900633
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900634 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900635 PRINT_ER("Error in setting channel %d\n", channelnum);
636
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900637 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900638}
639
640/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900641 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900642 * @details Request to do a scan. If returning zero, the scan request is given
643 * the driver, and will be valid until passed to cfg80211_scan_done().
644 * For scan results, call cfg80211_inform_bss(); you can call this outside
645 * the scan/scan_done bracket too.
646 * @param[in]
647 * @return int : Return 0 on Success
648 * @author mabubakr
649 * @date 01 MAR 2012
650 * @version 1.0
651 */
652
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900653static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900654{
Chaehyun Lim27268872015-09-15 14:06:13 +0900655 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900656 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900657 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900658 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900659 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900660
661 priv = wiphy_priv(wiphy);
662
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900663 priv->pstrScanReq = request;
664
665 priv->u32RcvdChCount = 0;
666
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100667 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900668
669
670 reset_shadow_found(priv);
671
Dean Lee72ed4dc2015-06-12 14:11:44 +0900672 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900673 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
674 /* max_scan_ssids */
675 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900676 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900677 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
678 }
679
680 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530681 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900682
683 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
684
685 if (request->n_ssids >= 1) {
686
687
Leo Kim607db442015-10-05 15:25:37 +0900688 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900689 strHiddenNetwork.u8ssidnum = request->n_ssids;
690
691
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900692 for (i = 0; i < request->n_ssids; i++) {
693
694 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900695 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900696 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900697 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
698 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530699 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900700 strHiddenNetwork.u8ssidnum -= 1;
701 }
702 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530703 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100704 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900705 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900706 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900707 CfgScanResult, (void *)priv, &strHiddenNetwork);
708 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530709 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100710 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900711 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900712 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900713 CfgScanResult, (void *)priv, NULL);
714 }
715
716 } else {
717 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530718 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900719 }
720
Leo Kime6e12662015-09-16 18:36:03 +0900721 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900722 s32Error = -EBUSY;
723 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
724 }
725
726 return s32Error;
727}
728
729/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900730 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900731 * @details Connect to the ESS with the specified parameters. When connected,
732 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
733 * If the connection fails for some reason, call cfg80211_connect_result()
734 * with the status from the AP.
735 * @param[in]
736 * @return int : Return 0 on Success
737 * @author mabubakr
738 * @date 01 MAR 2012
739 * @version 1.0
740 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900741static int connect(struct wiphy *wiphy, struct net_device *dev,
742 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900743{
Leo Kime6e12662015-09-16 18:36:03 +0900744 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900745 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900746 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900747 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900748 char *pcgroup_encrypt_val = NULL;
749 char *pccipher_group = NULL;
750 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900751
Chaehyun Lim27268872015-09-15 14:06:13 +0900752 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900753 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900754 tstrNetworkInfo *pstrNetworkInfo = NULL;
755
756
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100757 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900758 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900759 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900760
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100761 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900762
Johnny Kim8a143302015-06-10 17:06:46 +0900763 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 +0900764 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900765 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900766 pstrWFIDrv->p2p_connect = 1;
767 } else {
768 pstrWFIDrv->p2p_connect = 0;
769 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530770 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900771
772 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
773 if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900774 memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900775 sme->ssid,
776 sme->ssid_len) == 0) {
777 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
778 if (sme->bssid == NULL) {
779 /* BSSID is not passed from the user, so decision of matching
780 * is done by SSID only */
781 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
782 break;
783 } else {
784 /* BSSID is also passed from the user, so decision of matching
785 * should consider also this passed BSSID */
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900786 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900787 sme->bssid,
788 ETH_ALEN) == 0) {
789 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
790 break;
791 }
792 }
793 }
794 }
795
796 if (i < u32LastScannedNtwrksCountShadow) {
797 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
798
799 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
800
801 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
802 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
803 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
804 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
805 } else {
806 s32Error = -ENOENT;
807 if (u32LastScannedNtwrksCountShadow == 0)
808 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
809 else
810 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
811
812 goto done;
813 }
814
815 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900816 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
817 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900818
819 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
820 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
821
822 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
823
824 if (INFO) {
825 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
826 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
827 }
828
829 if (sme->crypto.cipher_group != NO_ENCRYPT) {
830 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
831 * we will add to it the pairwise cipher suite(s) */
832 pcwpa_version = "Default";
833 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900834 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835 u8security = ENCRYPT_ENABLED | WEP;
836 pcgroup_encrypt_val = "WEP40";
837 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
838 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
839
840 if (INFO) {
841 for (i = 0; i < sme->key_len; i++)
842 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
843 }
844 priv->WILC_WFI_wep_default = sme->key_idx;
845 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900846 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900847
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900848 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900849 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900850 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
851 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900852 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900853
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100854 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
855 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900856 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900857 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
858 pcgroup_encrypt_val = "WEP104";
859 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
860
861 priv->WILC_WFI_wep_default = sme->key_idx;
862 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900863 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900864
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900865 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900866 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900867 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
868 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900869 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900870
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100871 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
872 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900873 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900874 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900875 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
876 pcgroup_encrypt_val = "WPA2_TKIP";
877 pccipher_group = "TKIP";
878 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
879 /* tenuSecurity_t = WPA2_AES; */
880 u8security = ENCRYPT_ENABLED | WPA2 | AES;
881 pcgroup_encrypt_val = "WPA2_AES";
882 pccipher_group = "AES";
883 }
884 pcwpa_version = "WPA_VERSION_2";
885 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
886 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900887 u8security = ENCRYPT_ENABLED | WPA | TKIP;
888 pcgroup_encrypt_val = "WPA_TKIP";
889 pccipher_group = "TKIP";
890 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
891 /* tenuSecurity_t = WPA_AES; */
892 u8security = ENCRYPT_ENABLED | WPA | AES;
893 pcgroup_encrypt_val = "WPA_AES";
894 pccipher_group = "AES";
895
896 }
897 pcwpa_version = "WPA_VERSION_1";
898
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900899 } else {
900 s32Error = -ENOTSUPP;
901 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
902
903 goto done;
904 }
905
906 }
907
908 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
909 * add to it the pairwise cipher suite(s) */
910 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
911 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
912 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
913 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
914 u8security = u8security | TKIP;
915 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
916 u8security = u8security | AES;
917 }
918 }
919 }
920
921 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
922
923 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
924 switch (sme->auth_type) {
925 case NL80211_AUTHTYPE_OPEN_SYSTEM:
926 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
927 tenuAuth_type = OPEN_SYSTEM;
928 break;
929
930 case NL80211_AUTHTYPE_SHARED_KEY:
931 tenuAuth_type = SHARED_KEY;
932 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
933 break;
934
935 default:
936 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
937 }
938
939
940 /* ai: key_mgmt: enterprise case */
941 if (sme->crypto.n_akm_suites) {
942 switch (sme->crypto.akm_suites[0]) {
943 case WLAN_AKM_SUITE_8021X:
944 tenuAuth_type = IEEE8021;
945 break;
946
947 default:
948 break;
949 }
950 }
951
952
953 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
954
955 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
956 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
957
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900958 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900959
Leo Kimab16ec02015-10-29 12:05:40 +0900960 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900961 u8WLANChannel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900962
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100963 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900964
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100965 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900966 sme->ssid_len, sme->ie, sme->ie_len,
967 CfgConnectResult, (void *)priv, u8security,
968 tenuAuth_type, pstrNetworkInfo->u8channel,
969 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +0900970 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100971 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900972 s32Error = -ENOENT;
973 goto done;
974 }
975
976done:
977
978 return s32Error;
979}
980
981
982/**
Chaehyun Limb027cde2015-09-14 12:24:04 +0900983 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900984 * @details Disconnect from the BSS/ESS.
985 * @param[in]
986 * @return int : Return 0 on Success
987 * @author mdaftedar
988 * @date 01 MAR 2012
989 * @version 1.0
990 */
Chaehyun Limb027cde2015-09-14 12:24:04 +0900991static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900992{
Leo Kime6e12662015-09-16 18:36:03 +0900993 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900994 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900995 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900996 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900997
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100998 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900999 priv = wiphy_priv(wiphy);
1000
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001001 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kim441dc602015-10-12 16:55:35 +09001002 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001003 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001004 u8WLANChannel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001005 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001006
1007 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1008
1009 u8P2Plocalrandom = 0x01;
1010 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001011 bWilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001012 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001013
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001014 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001015 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001016 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1017 s32Error = -EINVAL;
1018 }
1019
1020 return s32Error;
1021}
1022
1023/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001024 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001025 * @details Add a key with the given parameters. @mac_addr will be %NULL
1026 * when adding a group key.
1027 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1028 * @return int : Return 0 on Success
1029 * @author mdaftedar
1030 * @date 01 MAR 2012
1031 * @version 1.0
1032 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001033static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1034 bool pairwise,
1035 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001036
1037{
Leo Kime6e12662015-09-16 18:36:03 +09001038 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001039 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001040 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001041 const u8 *pu8RxMic = NULL;
1042 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001043 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001044 u8 u8gmode = NO_ENCRYPT;
1045 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001046 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001047 struct wilc *wl;
1048 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001049
1050 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001051 nic = netdev_priv(netdev);
1052 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001053
1054 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1055
Johnny Kim8a143302015-06-10 17:06:46 +09001056 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001057
1058 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1059 params->key[1],
1060 params->key[2]);
1061
1062
1063 switch (params->cipher) {
1064 case WLAN_CIPHER_SUITE_WEP40:
1065 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001066 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1067
1068 priv->WILC_WFI_wep_default = key_index;
1069 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001070 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001071
1072 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1073 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1074
1075 for (i = 0; i < params->key_len; i++)
1076 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1077
1078 tenuAuth_type = OPEN_SYSTEM;
1079
1080 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1081 u8mode = ENCRYPT_ENABLED | WEP;
1082 else
1083 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1084
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001085 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 +09001086 break;
1087 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001088 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001089 priv->WILC_WFI_wep_default = key_index;
1090 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001091 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001092
1093 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1094 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1095 if (INFO) {
1096 for (i = 0; i < params->key_len; i++)
1097 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1098 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001099 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001100 }
1101
1102 break;
1103
1104 case WLAN_CIPHER_SUITE_TKIP:
1105 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001106 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1107
1108 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001109 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001110 priv->wilc_gtk[key_index]->key = NULL;
1111 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001112
1113 }
1114 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001115 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001116 priv->wilc_ptk[key_index]->key = NULL;
1117 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001118 }
1119
1120
1121
Daniel Machon19132212015-08-05 08:18:31 +02001122 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001123 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1124 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1125 else
1126 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1127
1128 priv->wilc_groupkey = u8gmode;
1129
1130 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1131
1132 pu8TxMic = params->key + 24;
1133 pu8RxMic = params->key + 16;
1134 KeyLen = params->key_len - 16;
1135 }
1136 /* 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 +05301137 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001138
Glen Leef3052582015-09-10 12:03:04 +09001139 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001140 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001141
1142 /* 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 +05301143 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001144
1145 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001146 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001147 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001148 }
1149
1150 priv->wilc_gtk[key_index]->cipher = params->cipher;
1151 priv->wilc_gtk[key_index]->key_len = params->key_len;
1152 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1153
1154 if (INFO) {
1155 for (i = 0; i < params->key_len; i++)
1156 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1157 for (i = 0; i < params->seq_len; i++)
1158 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1159 }
1160
1161
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001162 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001163 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1164
1165 } else {
1166 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]);
1167
1168 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1169 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1170 else
1171 u8pmode = priv->wilc_groupkey | AES;
1172
1173
1174 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1175
1176 pu8TxMic = params->key + 24;
1177 pu8RxMic = params->key + 16;
1178 KeyLen = params->key_len - 16;
1179 }
1180
Shraddha Barkecccfc392015-10-12 20:49:19 +05301181 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001182
Glen Leef3052582015-09-10 12:03:04 +09001183 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001184
Shraddha Barkecccfc392015-10-12 20:49:19 +05301185 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001186
1187 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001188 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001189
1190 if (INFO) {
1191 for (i = 0; i < params->key_len; i++)
1192 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1193
1194 for (i = 0; i < params->seq_len; i++)
1195 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1196 }
1197
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001198 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001199
1200 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001201 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001202
1203 priv->wilc_ptk[key_index]->cipher = params->cipher;
1204 priv->wilc_ptk[key_index]->key_len = params->key_len;
1205 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1206
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001207 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001208 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1209 }
1210 break;
1211 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001212
1213 {
1214 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001215 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001216 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1217 /* swap the tx mic by rx mic */
1218 pu8RxMic = params->key + 24;
1219 pu8TxMic = params->key + 16;
1220 KeyLen = params->key_len - 16;
1221 }
1222
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001223 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001224 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001225 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001226 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001227 if (!mac_addr) {
1228 g_add_gtk_key_params.mac_addr = NULL;
1229 } else {
Glen Leef3052582015-09-10 12:03:04 +09001230 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001231 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1232 }
1233 g_key_gtk_params.key_len = params->key_len;
1234 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001235 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001236 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1237 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001238 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001239 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1240 }
1241 g_key_gtk_params.cipher = params->cipher;
1242
1243 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1244 g_key_gtk_params.key[1],
1245 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001246 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001247 }
1248
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001249 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001250 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001251 } else {
1252 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1253 /* swap the tx mic by rx mic */
1254 pu8RxMic = params->key + 24;
1255 pu8TxMic = params->key + 16;
1256 KeyLen = params->key_len - 16;
1257 }
1258
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001259 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001260 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001261 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001262 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001263 if (!mac_addr) {
1264 g_add_ptk_key_params.mac_addr = NULL;
1265 } else {
Glen Leef3052582015-09-10 12:03:04 +09001266 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001267 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1268 }
1269 g_key_ptk_params.key_len = params->key_len;
1270 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001271 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001272 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1273 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001274 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001275 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1276 }
1277 g_key_ptk_params.cipher = params->cipher;
1278
1279 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1280 g_key_ptk_params.key[1],
1281 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001282 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001283 }
1284
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001285 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001286 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1287 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1288 if (INFO) {
1289 for (i = 0; i < params->key_len; i++)
1290 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1291 }
1292 }
1293 }
1294 break;
1295
1296 default:
1297 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1298 s32Error = -ENOTSUPP;
1299
1300 }
1301
1302 return s32Error;
1303}
1304
1305/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001306 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001307 * @details Remove a key given the @mac_addr (%NULL for a group key)
1308 * and @key_index, return -ENOENT if the key doesn't exist.
1309 * @param[in]
1310 * @return int : Return 0 on Success
1311 * @author mdaftedar
1312 * @date 01 MAR 2012
1313 * @version 1.0
1314 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001315static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1316 u8 key_index,
1317 bool pairwise,
1318 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001319{
Chaehyun Lim27268872015-09-15 14:06:13 +09001320 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001321 struct wilc *wl;
1322 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001323
1324 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001325 nic = netdev_priv(netdev);
1326 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001327
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001329 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001330 g_ptk_keys_saved = false;
1331 g_gtk_keys_saved = false;
1332 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001333
1334 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301335 kfree(g_key_wep_params.key);
1336 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001337
1338 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1339
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001340 if ((priv->wilc_gtk[key_index]) != NULL) {
1341
Shraddha Barkecccfc392015-10-12 20:49:19 +05301342 kfree(priv->wilc_gtk[key_index]->key);
1343 priv->wilc_gtk[key_index]->key = NULL;
1344 kfree(priv->wilc_gtk[key_index]->seq);
1345 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001346
Chaehyun Lim49188af2015-08-11 10:32:41 +09001347 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001348 priv->wilc_gtk[key_index] = NULL;
1349
1350 }
1351
1352 if ((priv->wilc_ptk[key_index]) != NULL) {
1353
Shraddha Barkecccfc392015-10-12 20:49:19 +05301354 kfree(priv->wilc_ptk[key_index]->key);
1355 priv->wilc_ptk[key_index]->key = NULL;
1356 kfree(priv->wilc_ptk[key_index]->seq);
1357 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001358 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001359 priv->wilc_ptk[key_index] = NULL;
1360 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001361
1362 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301363 kfree(g_key_ptk_params.key);
1364 g_key_ptk_params.key = NULL;
1365 kfree(g_key_ptk_params.seq);
1366 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001367
Shraddha Barkecccfc392015-10-12 20:49:19 +05301368 kfree(g_key_gtk_params.key);
1369 g_key_gtk_params.key = NULL;
1370 kfree(g_key_gtk_params.seq);
1371 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001372
1373 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001374 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001375 }
1376
1377 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001378 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001379 priv->WILC_WFI_wep_key_len[key_index] = 0;
1380
1381 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001382 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001383 } else {
1384 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001385 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001386 }
1387
Leo Kimaaed3292015-10-12 16:55:38 +09001388 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001389}
1390
1391/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001392 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001393 * @details Get information about the key with the given parameters.
1394 * @mac_addr will be %NULL when requesting information for a group
1395 * key. All pointers given to the @callback function need not be valid
1396 * after it returns. This function should return an error if it is
1397 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1398 * @param[in]
1399 * @return int : Return 0 on Success
1400 * @author mdaftedar
1401 * @date 01 MAR 2012
1402 * @version 1.0
1403 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001404static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1405 bool pairwise,
1406 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001407{
Chaehyun Lim27268872015-09-15 14:06:13 +09001408 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001409 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001410 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001411
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001412 priv = wiphy_priv(wiphy);
1413
1414
Alison Schofield3604af52015-10-12 13:22:44 -07001415 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001416 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1417
1418 key_params.key = priv->wilc_gtk[key_index]->key;
1419 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1420 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1421 key_params.seq = priv->wilc_gtk[key_index]->seq;
1422 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1423 if (INFO) {
1424 for (i = 0; i < key_params.key_len; i++)
1425 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1426 }
1427 } else {
1428 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1429
1430 key_params.key = priv->wilc_ptk[key_index]->key;
1431 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1432 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1433 key_params.seq = priv->wilc_ptk[key_index]->seq;
1434 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1435 }
1436
1437 callback(cookie, &key_params);
1438
Leo Kimaaed3292015-10-12 16:55:38 +09001439 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001440}
1441
1442/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001443 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001444 * @details Set the default management frame key on an interface
1445 * @param[in]
1446 * @return int : Return 0 on Success.
1447 * @author mdaftedar
1448 * @date 01 MAR 2012
1449 * @version 1.0
1450 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001451static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1452 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001453{
Chaehyun Lim27268872015-09-15 14:06:13 +09001454 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001455
1456
1457 priv = wiphy_priv(wiphy);
1458
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301459 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001460
1461 if (key_index != priv->WILC_WFI_wep_default) {
1462
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001463 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001464 }
1465
Leo Kimaaed3292015-10-12 16:55:38 +09001466 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001467}
1468
1469/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001470 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001471 * @details Get station information for the station identified by @mac
1472 * @param[in] NONE
1473 * @return int : Return 0 on Success.
1474 * @author mdaftedar
1475 * @date 01 MAR 2012
1476 * @version 1.0
1477 */
1478
Chaehyun Limf06f5622015-09-14 12:24:18 +09001479static int get_station(struct wiphy *wiphy, struct net_device *dev,
1480 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001481{
Chaehyun Lim27268872015-09-15 14:06:13 +09001482 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001483 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001484 u32 i = 0;
1485 u32 associatedsta = 0;
1486 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001487 priv = wiphy_priv(wiphy);
1488 nic = netdev_priv(dev);
1489
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001490 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1491 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1492
1493 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1494
1495 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1496
1497 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1498 associatedsta = i;
1499 break;
1500 }
1501
1502 }
1503
1504 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001505 PRINT_ER("Station required is not associated\n");
1506 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001507 }
1508
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001509 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001510
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001511 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001512 sinfo->inactive_time = 1000 * inactive_time;
1513 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1514
1515 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001516
1517 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001518 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001519
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001520 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001521
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001522 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301523 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001524 BIT(NL80211_STA_INFO_TX_PACKETS) |
1525 BIT(NL80211_STA_INFO_TX_FAILED) |
1526 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001527
Leo Kim00c8dfc2015-10-29 12:05:30 +09001528 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001529 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001530 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1531 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001532 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001533
Leo Kim5babeec2015-10-29 12:05:29 +09001534 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1535 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001536 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001537 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001538 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001539
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001540 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1541 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001542 }
Leo Kimaaed3292015-10-12 16:55:38 +09001543 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001544}
1545
1546
1547/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001548 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001549 * @details Modify parameters for a given BSS.
1550 * @param[in]
1551 * -use_cts_prot: Whether to use CTS protection
1552 * (0 = no, 1 = yes, -1 = do not change)
1553 * -use_short_preamble: Whether the use of short preambles is allowed
1554 * (0 = no, 1 = yes, -1 = do not change)
1555 * -use_short_slot_time: Whether the use of short slot time is allowed
1556 * (0 = no, 1 = yes, -1 = do not change)
1557 * -basic_rates: basic rates in IEEE 802.11 format
1558 * (or NULL for no change)
1559 * -basic_rates_len: number of basic rates
1560 * -ap_isolate: do not forward packets between connected stations
1561 * -ht_opmode: HT Operation mode
1562 * (u16 = opmode, -1 = do not change)
1563 * @return int : Return 0 on Success.
1564 * @author mdaftedar
1565 * @date 01 MAR 2012
1566 * @version 1.0
1567 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001568static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1569 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001570{
1571 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1572 return 0;
1573}
1574
1575/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001576 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001577 * @details Notify that wiphy parameters have changed;
1578 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1579 * have changed.
1580 * @return int : Return 0 on Success
1581 * @author mdaftedar
1582 * @date 01 MAR 2012
1583 * @version 1.0
1584 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001585static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001586{
Leo Kime6e12662015-09-16 18:36:03 +09001587 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001588 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001589 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590
1591 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001592
Tony Cho87c05b22015-10-12 16:56:07 +09001593 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301594 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001595
1596 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1597 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1598 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001599 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001600 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1601 }
1602 if (changed & WIPHY_PARAM_RETRY_LONG) {
1603
1604 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 +09001605 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1607
1608 }
1609 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1610 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 +09001611 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001612 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1613
1614 }
1615
1616 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1617 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1618
Tony Cho87c05b22015-10-12 16:56:07 +09001619 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001620 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1621
1622 }
1623
1624 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001625 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001626 if (s32Error)
1627 PRINT_ER("Error in setting WIPHY PARAMS\n");
1628
1629
1630 return s32Error;
1631}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001632
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001633/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001634 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001635 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1636 * devices running firmwares capable of generating the (re) association
1637 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1638 * @param[in]
1639 * @return int : Return 0 on Success
1640 * @author mdaftedar
1641 * @date 01 MAR 2012
1642 * @version 1.0
1643 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001644static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1645 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001646{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001647 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001648 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001649 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001650
Chaehyun Lim27268872015-09-15 14:06:13 +09001651 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001652
1653 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1654
1655
1656 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001657 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001658 ETH_ALEN)) {
1659 /*If bssid already exists and pmkid value needs to reset*/
1660 flag = PMKID_FOUND;
1661 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1662 break;
1663 }
1664 }
1665 if (i < WILC_MAX_NUM_PMKIDS) {
1666 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001667 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001668 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001669 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001670 PMKID_LEN);
1671 if (!(flag == PMKID_FOUND))
1672 priv->pmkid_list.numpmkid++;
1673 } else {
1674 PRINT_ER("Invalid PMKID index\n");
1675 s32Error = -EINVAL;
1676 }
1677
1678 if (!s32Error) {
1679 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001680 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001681 }
1682 return s32Error;
1683}
1684
1685/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001686 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001687 * @details Delete a cached PMKID.
1688 * @param[in]
1689 * @return int : Return 0 on Success
1690 * @author mdaftedar
1691 * @date 01 MAR 2012
1692 * @version 1.0
1693 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001694static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1695 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001696{
1697
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001698 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001699 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001700
Chaehyun Lim27268872015-09-15 14:06:13 +09001701 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001702
1703 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1704
1705 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001706 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001707 ETH_ALEN)) {
1708 /*If bssid is found, reset the values*/
1709 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001710 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001711 break;
1712 }
1713 }
1714
1715 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1716 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001717 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001718 priv->pmkid_list.pmkidlist[i + 1].bssid,
1719 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001720 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001721 priv->pmkid_list.pmkidlist[i].pmkid,
1722 PMKID_LEN);
1723 }
1724 priv->pmkid_list.numpmkid--;
1725 } else {
1726 s32Error = -EINVAL;
1727 }
1728
1729 return s32Error;
1730}
1731
1732/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001733 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001734 * @details Flush all cached PMKIDs.
1735 * @param[in]
1736 * @return int : Return 0 on Success
1737 * @author mdaftedar
1738 * @date 01 MAR 2012
1739 * @version 1.0
1740 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001741static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001742{
Chaehyun Lim27268872015-09-15 14:06:13 +09001743 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001744
1745 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1746
1747 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001748 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001749
1750 return 0;
1751}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001752
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001753
1754/**
1755 * @brief WILC_WFI_CfgParseRxAction
1756 * @details Function parses the received frames and modifies the following attributes:
1757 * -GO Intent
1758 * -Channel list
1759 * -Operating Channel
1760 *
1761 * @param[in] u8* Buffer, u32 length
1762 * @return NONE.
1763 * @author mdaftedar
1764 * @date 12 DEC 2012
1765 * @version
1766 */
1767
Arnd Bergmann1608c402015-11-16 15:04:53 +01001768static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001769{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001770 u32 index = 0;
1771 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001772
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001773 u8 op_channel_attr_index = 0;
1774 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001775
1776 while (index < len) {
1777 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001778 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001779 }
1780
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301781 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001782 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301783 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001784 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001785 index += buf[index + 1] + 3; /* ID,Length byte */
1786 }
Alison Schofield3604af52015-10-12 13:22:44 -07001787 if (u8WLANChannel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001788
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001789 /*Modify channel list attribute*/
1790 if (channel_list_attr_index) {
1791 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1792 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1793 if (buf[i] == 0x51) {
1794 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1795 buf[j] = u8WLANChannel;
1796 }
1797 break;
1798 }
1799 }
1800 }
1801 /*Modify operating channel attribute*/
1802 if (op_channel_attr_index) {
1803 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1804 buf[op_channel_attr_index + 6] = 0x51;
1805 buf[op_channel_attr_index + 7] = u8WLANChannel;
1806 }
1807 }
1808}
1809
1810/**
1811 * @brief WILC_WFI_CfgParseTxAction
1812 * @details Function parses the transmitted action frames and modifies the
1813 * GO Intent attribute
1814 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1815 * @return NONE.
1816 * @author mdaftedar
1817 * @date 12 DEC 2012
1818 * @version
1819 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001820static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001821{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001822 u32 index = 0;
1823 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001824
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001825 u8 op_channel_attr_index = 0;
1826 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001827
1828 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001829 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001830 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001831
1832 break;
1833 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001834
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301835 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001836 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301837 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001838 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001839 index += buf[index + 1] + 3; /* ID,Length byte */
1840 }
Alison Schofield3604af52015-10-12 13:22:44 -07001841 if (u8WLANChannel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001842
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001843 /*Modify channel list attribute*/
1844 if (channel_list_attr_index) {
1845 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1846 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1847 if (buf[i] == 0x51) {
1848 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1849 buf[j] = u8WLANChannel;
1850 }
1851 break;
1852 }
1853 }
1854 }
1855 /*Modify operating channel attribute*/
1856 if (op_channel_attr_index) {
1857 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1858 buf[op_channel_attr_index + 6] = 0x51;
1859 buf[op_channel_attr_index + 7] = u8WLANChannel;
1860 }
1861 }
1862}
1863
1864/* @brief WILC_WFI_p2p_rx
1865 * @details
1866 * @param[in]
1867 *
1868 * @return None
1869 * @author Mai Daftedar
1870 * @date 2 JUN 2013
1871 * @version 1.0
1872 */
1873
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001874void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001875{
1876
Chaehyun Lim27268872015-09-15 14:06:13 +09001877 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001878 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001879 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001880 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001881 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001882
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001883 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001884 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001885
1886 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001887 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001888
1889 /* The packet offset field conain info about what type of managment frame */
1890 /* we are dealing with and ack status */
1891 pkt_offset = GET_PKT_OFFSET(header);
1892
1893 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1894 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1895 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001896 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001897 return;
1898 } else {
1899 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1900 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],
1901 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001902 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001903 } else {
1904 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],
1905 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001906 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001907 }
1908 return;
1909 }
1910 } else {
1911
1912 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1913
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001914 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001915 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001916
1917 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1918 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1919
Leo Kim1229b1a2015-10-29 12:05:39 +09001920 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001921 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1922 return;
1923 }
1924 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1925
1926 switch (buff[ACTION_SUBTYPE_ID]) {
1927 case GAS_INTIAL_REQ:
1928 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1929 break;
1930
1931 case GAS_INTIAL_RSP:
1932 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1933 break;
1934
1935 case PUBLIC_ACT_VENDORSPEC:
1936 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
1937 * 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 +09001938 if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001939 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1940 if (!bWilc_ie) {
1941 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001942 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001943 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09001944 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001945 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
1946 break;
1947 }
1948 }
1949 }
1950 }
1951 if (u8P2Plocalrandom > u8P2Precvrandom) {
1952 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1953 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1954 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001955 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001956 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1957 break;
1958 }
1959 }
1960 }
1961 } else
1962 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
1963 }
1964
1965
1966 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
1967 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
1968 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001969 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001970 return;
1971 }
1972 break;
1973
1974 default:
1975 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1976 break;
1977 }
1978 }
1979 }
1980
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001981 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001982 }
1983}
1984
1985/**
1986 * @brief WILC_WFI_mgmt_tx_complete
1987 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
1988 * @param[in] priv
1989 * transmitting status
1990 * @return None
1991 * @author Amr Abdelmoghny
1992 * @date 20 MAY 2013
1993 * @version 1.0
1994 */
1995static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1996{
1997 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1998
1999
2000 kfree(pv_data->buff);
2001 kfree(pv_data);
2002}
2003
2004/**
2005 * @brief WILC_WFI_RemainOnChannelReady
2006 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2007 * @param
2008 * @return none
2009 * @author Amr abdelmoghny
2010 * @date 9 JUNE 2013
2011 * @version
2012 */
2013
2014static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2015{
Chaehyun Lim27268872015-09-15 14:06:13 +09002016 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002017
Chaehyun Lim27268872015-09-15 14:06:13 +09002018 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002019
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302020 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002021
Dean Lee72ed4dc2015-06-12 14:11:44 +09002022 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002023
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002024 cfg80211_ready_on_channel(priv->wdev,
2025 priv->strRemainOnChanParams.u64ListenCookie,
2026 priv->strRemainOnChanParams.pstrListenChan,
2027 priv->strRemainOnChanParams.u32ListenDuration,
2028 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002029}
2030
2031/**
2032 * @brief WILC_WFI_RemainOnChannelExpired
2033 * @details Callback function, called on expiration of remain-on-channel duration
2034 * @param
2035 * @return none
2036 * @author Amr abdelmoghny
2037 * @date 15 MAY 2013
2038 * @version
2039 */
2040
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002041static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002042{
Chaehyun Lim27268872015-09-15 14:06:13 +09002043 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002044
Chaehyun Lim27268872015-09-15 14:06:13 +09002045 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002046
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002047 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302048 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002049
Dean Lee72ed4dc2015-06-12 14:11:44 +09002050 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002051
2052 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002053 cfg80211_remain_on_channel_expired(priv->wdev,
2054 priv->strRemainOnChanParams.u64ListenCookie,
2055 priv->strRemainOnChanParams.pstrListenChan,
2056 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002057 } else {
2058 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2059 , priv->strRemainOnChanParams.u32ListenSessionID);
2060 }
2061}
2062
2063
2064/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002065 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002066 * @details Request the driver to remain awake on the specified
2067 * channel for the specified duration to complete an off-channel
2068 * operation (e.g., public action frame exchange). When the driver is
2069 * ready on the requested channel, it must indicate this with an event
2070 * notification by calling cfg80211_ready_on_channel().
2071 * @param[in]
2072 * @return int : Return 0 on Success
2073 * @author mdaftedar
2074 * @date 01 MAR 2012
2075 * @version 1.0
2076 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002077static int remain_on_channel(struct wiphy *wiphy,
2078 struct wireless_dev *wdev,
2079 struct ieee80211_channel *chan,
2080 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002081{
Leo Kime6e12662015-09-16 18:36:03 +09002082 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002083 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002084
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002085 priv = wiphy_priv(wiphy);
2086
2087 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2088
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002089
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002090 if (wdev->iftype == NL80211_IFTYPE_AP) {
2091 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2092 return s32Error;
2093 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002094
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002095 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002096
2097 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2098 priv->strRemainOnChanParams.pstrListenChan = chan;
2099 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002100 priv->strRemainOnChanParams.u32ListenDuration = duration;
2101 priv->strRemainOnChanParams.u32ListenSessionID++;
2102
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002103 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002104 , priv->strRemainOnChanParams.u32ListenSessionID
2105 , duration
2106 , chan->hw_value
2107 , WILC_WFI_RemainOnChannelExpired
2108 , WILC_WFI_RemainOnChannelReady
2109 , (void *)priv);
2110
2111 return s32Error;
2112}
2113
2114/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002115 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002116 * @details Cancel an on-going remain-on-channel operation.
2117 * This allows the operation to be terminated prior to timeout based on
2118 * the duration value.
2119 * @param[in] struct wiphy *wiphy,
2120 * @param[in] struct net_device *dev
2121 * @param[in] u64 cookie,
2122 * @return int : Return 0 on Success
2123 * @author mdaftedar
2124 * @date 01 MAR 2012
2125 * @version 1.0
2126 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002127static int cancel_remain_on_channel(struct wiphy *wiphy,
2128 struct wireless_dev *wdev,
2129 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002130{
Leo Kime6e12662015-09-16 18:36:03 +09002131 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002132 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002133
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002134 priv = wiphy_priv(wiphy);
2135
2136 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2137
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002138 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002139 return s32Error;
2140}
2141/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002142 * @brief WILC_WFI_mgmt_tx_frame
2143 * @details
2144 *
2145 * @param[in]
2146 * @return NONE.
2147 * @author mdaftedar
2148 * @date 01 JUL 2012
2149 * @version
2150 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002151static int mgmt_tx(struct wiphy *wiphy,
2152 struct wireless_dev *wdev,
2153 struct cfg80211_mgmt_tx_params *params,
2154 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002155{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002156 struct ieee80211_channel *chan = params->chan;
2157 unsigned int wait = params->wait;
2158 const u8 *buf = params->buf;
2159 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160 const struct ieee80211_mgmt *mgmt;
2161 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002162 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002163 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002164 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002165 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002166 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002167
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002168 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002169 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002170 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002171
2172 *cookie = (unsigned long)buf;
2173 priv->u64tx_cookie = *cookie;
2174 mgmt = (const struct ieee80211_mgmt *) buf;
2175
2176 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2177
2178 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002179 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002180 if (mgmt_tx == NULL) {
2181 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002182 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002183 }
Glen Leef3052582015-09-10 12:03:04 +09002184 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002185 if (mgmt_tx->buff == NULL) {
2186 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002187 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002188 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002189 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002190 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002191 mgmt_tx->size = len;
2192
2193
2194 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2195 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2196 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002197 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002198 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002199 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002200 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002201 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002202
2203
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002204 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002205 /*Only set the channel, if not a negotiation confirmation frame
2206 * (If Negotiation confirmation frame, force it
2207 * to be transmitted on the same negotiation channel)*/
2208
2209 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2210 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2211 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002212 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002213 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002214 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002215 }
2216 switch (buf[ACTION_SUBTYPE_ID]) {
2217 case GAS_INTIAL_REQ:
2218 {
2219 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2220 break;
2221 }
2222
2223 case GAS_INTIAL_RSP:
2224 {
2225 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2226 break;
2227 }
2228
2229 case PUBLIC_ACT_VENDORSPEC:
2230 {
2231 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2232 * 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 +09002233 if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002234 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2235 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2236 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2237 get_random_bytes(&u8P2Plocalrandom, 1);
2238 /*Increment the number to prevent if its 0*/
2239 u8P2Plocalrandom++;
2240 }
2241 }
2242
2243 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2244 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2245 if (u8P2Plocalrandom > u8P2Precvrandom) {
2246 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2247
2248 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2249 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002250 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002251 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002252 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002253
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002254 /*If using supplicant go intent, no need at all*/
2255 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002256 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002257 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002258 break;
2259 }
2260 }
2261
2262 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302263 /*
2264 * Adding WILC information element to allow two WILC devices to
2265 * identify each other and connect
2266 */
2267 memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002268 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2269 mgmt_tx->size = buf_len;
2270 }
2271 } else
2272 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2273 }
2274
2275 } else {
2276 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2277 }
2278
2279 break;
2280 }
2281
2282 default:
2283 {
2284 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2285 break;
2286 }
2287 }
2288
2289 }
2290
2291 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 +09002292 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002293
Leo Kim1229b1a2015-10-29 12:05:39 +09002294 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2295 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002296 }
2297
Glen Lee829c4772015-10-29 12:18:44 +09002298 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2299 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002300 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002301 } else {
2302 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2303 }
Leo Kimaaed3292015-10-12 16:55:38 +09002304 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002305}
2306
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002307static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2308 struct wireless_dev *wdev,
2309 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002310{
Chaehyun Lim27268872015-09-15 14:06:13 +09002311 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002312 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002313
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002314 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002315 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002316
2317
2318 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002319 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002320
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002321 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002322 cfg80211_remain_on_channel_expired(priv->wdev,
2323 priv->strRemainOnChanParams.u64ListenCookie,
2324 priv->strRemainOnChanParams.pstrListenChan,
2325 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002326 }
2327
2328 return 0;
2329}
2330
2331/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002332 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002333 * @details Notify driver that a management frame type was
2334 * registered. Note that this callback may not sleep, and cannot run
2335 * concurrently with itself.
2336 * @param[in]
2337 * @return NONE.
2338 * @author mdaftedar
2339 * @date 01 JUL 2012
2340 * @version
2341 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002342void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2343 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002344{
2345
Chaehyun Lim27268872015-09-15 14:06:13 +09002346 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002347 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002348 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002349
2350 priv = wiphy_priv(wiphy);
2351 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002352 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002353
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002354 if (!frame_type)
2355 return;
2356
2357 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2358 switch (frame_type) {
2359 case PROBE_REQ:
2360 {
2361 nic->g_struct_frame_reg[0].frame_type = frame_type;
2362 nic->g_struct_frame_reg[0].reg = reg;
2363 }
2364 break;
2365
2366 case ACTION:
2367 {
2368 nic->g_struct_frame_reg[1].frame_type = frame_type;
2369 nic->g_struct_frame_reg[1].reg = reg;
2370 }
2371 break;
2372
2373 default:
2374 {
2375 break;
2376 }
2377
2378 }
2379 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002380 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002381 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2382 return;
2383 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002384 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002385
2386
2387}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002388
2389/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002390 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002391 * @details Configure connection quality monitor RSSI threshold.
2392 * @param[in] struct wiphy *wiphy:
2393 * @param[in] struct net_device *dev:
2394 * @param[in] s32 rssi_thold:
2395 * @param[in] u32 rssi_hyst:
2396 * @return int : Return 0 on Success
2397 * @author mdaftedar
2398 * @date 01 MAR 2012
2399 * @version 1.0
2400 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002401static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2402 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002403{
2404 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2405 return 0;
2406
2407}
2408/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002409 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002410 * @details Configure connection quality monitor RSSI threshold.
2411 * @param[in] struct wiphy *wiphy:
2412 * @param[in] struct net_device *dev
2413 * @param[in] int idx
2414 * @param[in] u8 *mac
2415 * @param[in] struct station_info *sinfo
2416 * @return int : Return 0 on Success
2417 * @author mdaftedar
2418 * @date 01 MAR 2012
2419 * @version 1.0
2420 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002421static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2422 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002423{
Chaehyun Lim27268872015-09-15 14:06:13 +09002424 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002425
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002426 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2427
2428 if (idx != 0)
2429 return -ENOENT;
2430
2431 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002432
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002433 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002434
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002435 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002436
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002437 return 0;
2438
2439}
2440
2441
2442/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002443 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002444 * @details
2445 * @param[in]
2446 * @return int : Return 0 on Success.
2447 * @author mdaftedar
2448 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002449 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002450 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002451static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2452 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002453{
Chaehyun Lim27268872015-09-15 14:06:13 +09002454 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002455
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002456 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2457
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002458 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002459 return -ENOENT;
2460
2461 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002462 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002463 PRINT_ER("Driver is NULL\n");
2464 return -EIO;
2465 }
2466
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002467 if (wilc_enable_ps)
2468 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002469
2470
Leo Kime6e12662015-09-16 18:36:03 +09002471 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002472
2473}
Glen Lee108b3432015-09-16 18:53:20 +09002474
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002475/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002476 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002477 * @details Change type/configuration of virtual interface,
2478 * keep the struct wireless_dev's iftype updated.
2479 * @param[in] NONE
2480 * @return int : Return 0 on Success.
2481 * @author mdaftedar
2482 * @date 01 MAR 2012
2483 * @version 1.0
2484 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002485static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2486 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002487{
Chaehyun Lim27268872015-09-15 14:06:13 +09002488 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002489 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002490 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002491 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002492 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002493 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494
2495 nic = netdev_priv(dev);
2496 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002497 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002498
2499 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2500 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2501 u8P2Plocalrandom = 0x01;
2502 u8P2Precvrandom = 0x00;
2503
Dean Lee72ed4dc2015-06-12 14:11:44 +09002504 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002505
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002506 wilc_optaining_ip = false;
2507 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002508 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002509 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2510 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002511 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002512 }
2513
2514 switch (type) {
2515 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002516 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002517 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002518
2519 /* send delba over wlan interface */
2520
2521
2522 dev->ieee80211_ptr->iftype = type;
2523 priv->wdev->iftype = type;
2524 nic->monitor_flag = 0;
2525 nic->iftype = STATION_MODE;
2526
2527 /*Remove the enteries of the previously connected clients*/
2528 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002529 interface_type = nic->iftype;
2530 nic->iftype = STATION_MODE;
2531
Glen Lee299382c2015-10-20 17:13:56 +09002532 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002533 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2534 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002535 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002536 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002537
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002538 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002539 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002540
Glen Lee53dc0cf2015-10-20 17:13:57 +09002541 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002542 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002543 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002544 nic->iftype = interface_type;
2545
2546 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002547 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2548 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002549 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002550 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002551
2552 /*Add saved WEP keys, if any*/
2553 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002554 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002555 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002556 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002557 g_key_wep_params.key,
2558 g_key_wep_params.key_len,
2559 g_key_wep_params.key_idx);
2560 }
2561
2562 /*No matter the driver handler passed here, it will be overwriiten*/
2563 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002564 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002565
2566 /*Add saved PTK and GTK keys, if any*/
2567 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2568 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2569 g_key_ptk_params.key[1],
2570 g_key_ptk_params.key[2]);
2571 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2572 g_key_gtk_params.key[1],
2573 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002574 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2575 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002576 g_add_ptk_key_params.key_idx,
2577 g_add_ptk_key_params.pairwise,
2578 g_add_ptk_key_params.mac_addr,
2579 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002580
Glen Lee299382c2015-10-20 17:13:56 +09002581 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2582 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002583 g_add_gtk_key_params.key_idx,
2584 g_add_gtk_key_params.pairwise,
2585 g_add_gtk_key_params.mac_addr,
2586 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002587 }
2588
Glen Lee299382c2015-10-20 17:13:56 +09002589 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002590 for (i = 0; i < num_reg_frame; i++) {
2591 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2592 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002593 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594 nic->g_struct_frame_reg[i].frame_type,
2595 nic->g_struct_frame_reg[i].reg);
2596 }
2597 }
2598
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002599 wilc_enable_ps = true;
2600 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002601 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002602 break;
2603
2604 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002605 wilc_enable_ps = false;
2606 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2607 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002608 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002609
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002610 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2611 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002612
2613 dev->ieee80211_ptr->iftype = type;
2614 priv->wdev->iftype = type;
2615 nic->monitor_flag = 0;
2616
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002617 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2618 nic->iftype = CLIENT_MODE;
2619
2620
Glen Lee299382c2015-10-20 17:13:56 +09002621 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002622 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002623 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002624
Glen Lee53dc0cf2015-10-20 17:13:57 +09002625 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002626 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002627 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002628
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002629 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2630 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002631 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002632 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002633
2634 /*Add saved WEP keys, if any*/
2635 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002636 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2637 g_key_wep_params.key_idx);
2638 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2639 g_key_wep_params.key,
2640 g_key_wep_params.key_len,
2641 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002642 }
2643
2644 /*No matter the driver handler passed here, it will be overwriiten*/
2645 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002646 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002647
2648 /*Add saved PTK and GTK keys, if any*/
2649 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2650 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2651 g_key_ptk_params.key[1],
2652 g_key_ptk_params.key[2]);
2653 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2654 g_key_gtk_params.key[1],
2655 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002656 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2657 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002658 g_add_ptk_key_params.key_idx,
2659 g_add_ptk_key_params.pairwise,
2660 g_add_ptk_key_params.mac_addr,
2661 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002662
Glen Lee299382c2015-10-20 17:13:56 +09002663 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2664 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002665 g_add_gtk_key_params.key_idx,
2666 g_add_gtk_key_params.pairwise,
2667 g_add_gtk_key_params.mac_addr,
2668 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002669 }
2670
2671 /*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 +09002672 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002673 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002674
Glen Lee299382c2015-10-20 17:13:56 +09002675 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002676 for (i = 0; i < num_reg_frame; i++) {
2677 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2678 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002679 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002680 nic->g_struct_frame_reg[i].frame_type,
2681 nic->g_struct_frame_reg[i].reg);
2682 }
2683 }
2684 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002685 break;
2686
2687 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002688 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002689 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002690 dev->ieee80211_ptr->iftype = type;
2691 priv->wdev->iftype = type;
2692 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002693 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002694
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002695 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002696 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002697 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002698 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002699 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002700 wilc_mac_close(dev);
2701 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002702
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002703 for (i = 0; i < num_reg_frame; i++) {
2704 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2705 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002706 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002707 nic->g_struct_frame_reg[i].frame_type,
2708 nic->g_struct_frame_reg[i].reg);
2709 }
2710 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002711 break;
2712
2713 case NL80211_IFTYPE_P2P_GO:
2714 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2715
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002716 wilc_optaining_ip = true;
2717 mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME));
2718 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002719 /*Delete block ack has to be the latest config packet*/
2720 /*sent before downloading new FW. This is because it blocks on*/
2721 /*hWaitResponse semaphore, which allows previous config*/
2722 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002723 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2724 wl->vif[0].bssid, TID);
2725 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002726 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002727 dev->ieee80211_ptr->iftype = type;
2728 priv->wdev->iftype = type;
2729
Johnny Kim8a143302015-06-10 17:06:46 +09002730 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002731
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002732 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2733
2734
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002735 nic->iftype = GO_MODE;
2736
2737 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002738 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002739 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002740 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002741 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002742
2743
2744 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002745 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2746 wilc_set_mac_address(wl->vif[0].hif_drv,
2747 wl->vif[0].src_addr);
2748 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749
2750 /*Add saved WEP keys, if any*/
2751 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002752 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2753 g_key_wep_params.key_idx);
2754 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002755 g_key_wep_params.key,
2756 g_key_wep_params.key_len,
2757 g_key_wep_params.key_idx);
2758 }
2759
2760 /*No matter the driver handler passed here, it will be overwriiten*/
2761 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002762 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002763
2764 /*Add saved PTK and GTK keys, if any*/
2765 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2766 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2767 g_key_ptk_params.key[1],
2768 g_key_ptk_params.key[2],
2769 g_key_ptk_params.cipher);
2770 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2771 g_key_gtk_params.key[1],
2772 g_key_gtk_params.key[2],
2773 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002774 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2775 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002776 g_add_ptk_key_params.key_idx,
2777 g_add_ptk_key_params.pairwise,
2778 g_add_ptk_key_params.mac_addr,
2779 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002780
Glen Lee299382c2015-10-20 17:13:56 +09002781 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2782 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002783 g_add_gtk_key_params.key_idx,
2784 g_add_gtk_key_params.pairwise,
2785 g_add_gtk_key_params.mac_addr,
2786 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002787 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002788
Glen Lee299382c2015-10-20 17:13:56 +09002789 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790 for (i = 0; i < num_reg_frame; i++) {
2791 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2792 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002793 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002794 nic->g_struct_frame_reg[i].frame_type,
2795 nic->g_struct_frame_reg[i].reg);
2796 }
2797 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002798 break;
2799
2800 default:
2801 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002802 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002803 }
2804
Leo Kimaaed3292015-10-12 16:55:38 +09002805 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002806}
2807
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002808/* (austin.2013-07-23)
2809 *
2810 * To support revised cfg80211_ops
2811 *
2812 * add_beacon --> start_ap
2813 * set_beacon --> change_beacon
2814 * del_beacon --> stop_ap
2815 *
2816 * beacon_parameters --> cfg80211_ap_settings
2817 * cfg80211_beacon_data
2818 *
2819 * applicable for linux kernel 3.4+
2820 */
2821
2822/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002823 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002824 * @details Add a beacon with given parameters, @head, @interval
2825 * and @dtim_period will be valid, @tail is optional.
2826 * @param[in] wiphy
2827 * @param[in] dev The net device structure
2828 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2829 * @return int : Return 0 on Success.
2830 * @author austin
2831 * @date 23 JUL 2013
2832 * @version 1.0
2833 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002834static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2835 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002836{
2837 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002838 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002839 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002840 struct wilc *wl;
2841 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002842
2843 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002844 nic = netdev_priv(dev);
2845 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002846 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2847
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302848 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 +09002849 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2850
Chaehyun Lim80785a92015-09-14 12:24:01 +09002851 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002852
Leo Kime6e12662015-09-16 18:36:03 +09002853 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002855
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002856 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002857
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002858 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002859 settings->beacon_interval,
2860 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002861 beacon->head_len, (u8 *)beacon->head,
2862 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002863
2864 return s32Error;
2865}
2866
2867/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002868 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002869 * @details Add a beacon with given parameters, @head, @interval
2870 * and @dtim_period will be valid, @tail is optional.
2871 * @param[in] wiphy
2872 * @param[in] dev The net device structure
2873 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2874 * @return int : Return 0 on Success.
2875 * @author austin
2876 * @date 23 JUL 2013
2877 * @version 1.0
2878 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002879static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2880 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002881{
Chaehyun Lim27268872015-09-15 14:06:13 +09002882 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002883 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002884
2885 priv = wiphy_priv(wiphy);
2886 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2887
2888
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002889 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002890 0,
2891 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002892 beacon->head_len, (u8 *)beacon->head,
2893 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002894
2895 return s32Error;
2896}
2897
2898/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002899 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002900 * @details Remove beacon configuration and stop sending the beacon.
2901 * @param[in]
2902 * @return int : Return 0 on Success.
2903 * @author austin
2904 * @date 23 JUL 2013
2905 * @version 1.0
2906 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002907static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002908{
Leo Kime6e12662015-09-16 18:36:03 +09002909 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002910 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002911 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912
Leo Kim7ae43362015-09-16 18:35:59 +09002913 if (!wiphy)
2914 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002915
2916 priv = wiphy_priv(wiphy);
2917
2918 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2919
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002920 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002921
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002922 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002923
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002924 if (s32Error)
2925 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002926
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002927 return s32Error;
2928}
2929
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002930/**
Chaehyun Limed269552015-09-14 12:24:15 +09002931 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002932 * @details Add a new station.
2933 * @param[in]
2934 * @return int : Return 0 on Success.
2935 * @author mdaftedar
2936 * @date 01 MAR 2012
2937 * @version 1.0
2938 */
Chaehyun Limed269552015-09-14 12:24:15 +09002939static int add_station(struct wiphy *wiphy, struct net_device *dev,
2940 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002941{
Leo Kime6e12662015-09-16 18:36:03 +09002942 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002943 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002944 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002945 perInterface_wlan_t *nic;
2946
Leo Kim7ae43362015-09-16 18:35:59 +09002947 if (!wiphy)
2948 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002949
2950 priv = wiphy_priv(wiphy);
2951 nic = netdev_priv(dev);
2952
2953 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002954 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002955 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002956 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002957 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002958 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002959
2960 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2961
2962 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],
2963 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002964 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002965 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2966 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002967
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002968 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09002969 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002970 } else {
Leo Kim22520122015-10-29 12:05:45 +09002971 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002972 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002973 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002974 memcpy(strStaParams.ht_supp_mcs_set,
2975 &params->ht_capa->mcs,
2976 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002977 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002978 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002979 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002980 }
2981
Leo Kimf676e172015-10-29 12:05:52 +09002982 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002983 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002984
Leo Kim22520122015-10-29 12:05:45 +09002985 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2986 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002987 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2988 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002989 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2990 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002991 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2992 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002993 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2994 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002995 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2996 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002997 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2998 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002999 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3000 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003001
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003002 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003003 if (s32Error)
3004 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003005 }
3006
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003007 return s32Error;
3008}
3009
3010/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003011 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003012 * @details Remove a station; @mac may be NULL to remove all stations.
3013 * @param[in]
3014 * @return int : Return 0 on Success.
3015 * @author mdaftedar
3016 * @date 01 MAR 2012
3017 * @version 1.0
3018 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003019static int del_station(struct wiphy *wiphy, struct net_device *dev,
3020 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003021{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003022 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003023 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003024 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003025 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003026
Leo Kim7ae43362015-09-16 18:35:59 +09003027 if (!wiphy)
3028 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003029
3030 priv = wiphy_priv(wiphy);
3031 nic = netdev_priv(dev);
3032
3033 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3034 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3035
3036
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003037 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303038 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003039 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003040 } else {
3041 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]);
3042 }
3043
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003044 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003045
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003046 if (s32Error)
3047 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003048 }
3049 return s32Error;
3050}
3051
3052/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003053 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003054 * @details Modify a given station.
3055 * @param[in]
3056 * @return int : Return 0 on Success.
3057 * @author mdaftedar
3058 * @date 01 MAR 2012
3059 * @version 1.0
3060 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003061static int change_station(struct wiphy *wiphy, struct net_device *dev,
3062 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003063{
Leo Kime6e12662015-09-16 18:36:03 +09003064 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003065 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003066 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003067 perInterface_wlan_t *nic;
3068
3069
3070 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3071
Leo Kim7ae43362015-09-16 18:35:59 +09003072 if (!wiphy)
3073 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003074
3075 priv = wiphy_priv(wiphy);
3076 nic = netdev_priv(dev);
3077
3078 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003079 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003080 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003081 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003082 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003083
Leo Kim2353c382015-10-29 12:05:41 +09003084 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3085 strStaParams.bssid[0], strStaParams.bssid[1],
3086 strStaParams.bssid[2], strStaParams.bssid[3],
3087 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003088 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003089 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3090 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003091
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003092 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003093 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003094 } else {
Leo Kim22520122015-10-29 12:05:45 +09003095 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003096 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003097 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003098 memcpy(strStaParams.ht_supp_mcs_set,
3099 &params->ht_capa->mcs,
3100 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003101 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003102 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003103 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003104 }
3105
Leo Kimf676e172015-10-29 12:05:52 +09003106 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003107 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003108
Leo Kim22520122015-10-29 12:05:45 +09003109 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3110 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003111 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3112 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003113 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3114 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003115 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3116 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003117 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3118 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003119 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3120 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003121 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3122 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003123 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3124 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003125
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003126 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003127 if (s32Error)
3128 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003129 }
3130 return s32Error;
3131}
3132
3133
3134/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003135 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003136 * @details
3137 * @param[in]
3138 * @return int : Return 0 on Success.
3139 * @author mdaftedar
3140 * @date 01 JUL 2012
3141 * @version 1.0
3142 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003143static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3144 const char *name,
3145 unsigned char name_assign_type,
3146 enum nl80211_iftype type,
3147 u32 *flags,
3148 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003149{
3150 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003151 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003152 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003153
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003154 priv = wiphy_priv(wiphy);
3155
3156
3157
3158 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3159
3160 nic = netdev_priv(priv->wdev->netdev);
3161
3162
3163 if (type == NL80211_IFTYPE_MONITOR) {
3164 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3165 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3166 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3167 if (new_ifc != NULL) {
3168 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003169 nic = netdev_priv(priv->wdev->netdev);
3170 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003171 } else
3172 PRINT_ER("Error in initializing monitor interface\n ");
3173 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003174 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003175}
3176
3177/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003178 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003179 * @details
3180 * @param[in]
3181 * @return int : Return 0 on Success.
3182 * @author mdaftedar
3183 * @date 01 JUL 2012
3184 * @version 1.0
3185 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003186static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003187{
3188 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003189 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003190}
3191
Chaehyun Lim08241922015-09-15 14:06:12 +09003192static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003193
Chaehyun Lim80785a92015-09-14 12:24:01 +09003194 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003195 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003196 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003197 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003198 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003199 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003200 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003201 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003202 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003203 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003204 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003205
Chaehyun Lima13168d2015-09-14 12:24:12 +09003206 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003207 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003208 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003209 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003210 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003211 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003212 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003213 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003214 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003215 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003216
Chaehyun Lim4d466572015-09-14 12:24:22 +09003217 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003218 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003219 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003220 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003221 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003222 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003223 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003224 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003225 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003226 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003227
3228};
3229
3230
3231
3232
3233
3234/**
3235 * @brief WILC_WFI_update_stats
3236 * @details Modify parameters for a given BSS.
3237 * @param[in]
3238 * @return int : Return 0 on Success.
3239 * @author mdaftedar
3240 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003241 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003242 */
3243int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3244{
3245
Chaehyun Lim27268872015-09-15 14:06:13 +09003246 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003247
3248 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003249 switch (changed) {
3250
3251 case WILC_WFI_RX_PKT:
3252 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003253 priv->netstats.rx_packets++;
3254 priv->netstats.rx_bytes += pktlen;
3255 priv->netstats.rx_time = get_jiffies_64();
3256 }
3257 break;
3258
3259 case WILC_WFI_TX_PKT:
3260 {
3261 priv->netstats.tx_packets++;
3262 priv->netstats.tx_bytes += pktlen;
3263 priv->netstats.tx_time = get_jiffies_64();
3264
3265 }
3266 break;
3267
3268 default:
3269 break;
3270 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003271 return 0;
3272}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003273
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003274/**
3275 * @brief WILC_WFI_CfgAlloc
3276 * @details Allocation of the wireless device structure and assigning it
3277 * to the cfg80211 operations structure.
3278 * @param[in] NONE
3279 * @return wireless_dev : Returns pointer to wireless_dev structure.
3280 * @author mdaftedar
3281 * @date 01 MAR 2012
3282 * @version 1.0
3283 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003284static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003285{
3286
3287 struct wireless_dev *wdev;
3288
3289
3290 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3291 /*Allocating the wireless device structure*/
3292 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3293 if (!wdev) {
3294 PRINT_ER("Cannot allocate wireless device\n");
3295 goto _fail_;
3296 }
3297
3298 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003299 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003300 if (!wdev->wiphy) {
3301 PRINT_ER("Cannot allocate wiphy\n");
3302 goto _fail_mem_;
3303
3304 }
3305
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003306 /* enable 802.11n HT */
3307 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3308 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3309 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3310 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3311 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003312
3313 /*wiphy bands*/
3314 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3315
3316 return wdev;
3317
3318_fail_mem_:
3319 kfree(wdev);
3320_fail_:
3321 return NULL;
3322
3323}
3324/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003325 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003326 * @details Registering of the wiphy structure and interface modes
3327 * @param[in] NONE
3328 * @return NONE
3329 * @author mdaftedar
3330 * @date 01 MAR 2012
3331 * @version 1.0
3332 */
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003333struct wireless_dev *wilc_create_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003334{
Chaehyun Lim27268872015-09-15 14:06:13 +09003335 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003336 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003337 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003338
3339 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3340
3341 wdev = WILC_WFI_CfgAlloc();
3342 if (wdev == NULL) {
3343 PRINT_ER("CfgAlloc Failed\n");
3344 return NULL;
3345 }
3346
3347
3348 /*Return hardware description structure (wiphy)'s priv*/
3349 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003350 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003351
3352 /*Link the wiphy with wireless structure*/
3353 priv->wdev = wdev;
3354
3355 /*Maximum number of probed ssid to be added by user for the scan request*/
3356 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003357 /*Maximum number of pmkids to be cashed*/
3358 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3359 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003360
3361 wdev->wiphy->max_scan_ie_len = 1000;
3362
3363 /*signal strength in mBm (100*dBm) */
3364 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3365
3366 /*Set the availaible cipher suites*/
3367 wdev->wiphy->cipher_suites = cipher_suites;
3368 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003369 /*Setting default managment types: for register action frame: */
3370 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003371
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003372 wdev->wiphy->max_remain_on_channel_duration = 500;
3373 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3374 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3375 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003376 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003377 wdev->iftype = NL80211_IFTYPE_STATION;
3378
3379
3380
3381 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3382 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3383 wdev->wiphy->interface_modes, wdev->iftype);
3384
3385 #ifdef WILC_SDIO
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003386 set_wiphy_dev(wdev->wiphy, &wilc_sdio_func->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003387 #endif
3388
3389 /*Register wiphy structure*/
3390 s32Error = wiphy_register(wdev->wiphy);
3391 if (s32Error) {
3392 PRINT_ER("Cannot register wiphy device\n");
3393 /*should define what action to be taken in such failure*/
3394 } else {
3395 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3396 }
3397
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003398 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003399 return wdev;
3400
3401
3402}
3403/**
3404 * @brief WILC_WFI_WiphyFree
3405 * @details Freeing allocation of the wireless device structure
3406 * @param[in] NONE
3407 * @return NONE
3408 * @author mdaftedar
3409 * @date 01 MAR 2012
3410 * @version 1.0
3411 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003412int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003413{
3414
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003415 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003416
Chaehyun Lim27268872015-09-15 14:06:13 +09003417 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003418
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003419 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3420 priv = wdev_priv(net->ieee80211_ptr);
3421 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003422 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003423 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003424 }
3425 op_ifcs++;
3426 if (s32Error < 0) {
3427 PRINT_ER("Failed to creat refresh Timer\n");
3428 return s32Error;
3429 }
3430
Dean Lee72ed4dc2015-06-12 14:11:44 +09003431 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003432
Dean Lee72ed4dc2015-06-12 14:11:44 +09003433 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003434
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003435 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003436 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003437 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003438 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003439
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003440 return s32Error;
3441}
3442
3443/**
3444 * @brief WILC_WFI_WiphyFree
3445 * @details Freeing allocation of the wireless device structure
3446 * @param[in] NONE
3447 * @return NONE
3448 * @author mdaftedar
3449 * @date 01 MAR 2012
3450 * @version 1.0
3451 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003452int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003453{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003454 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003455
Chaehyun Lim27268872015-09-15 14:06:13 +09003456 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003457
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003458 priv = wdev_priv(net->ieee80211_ptr);
3459
Dean Lee72ed4dc2015-06-12 14:11:44 +09003460 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003461
Dean Lee72ed4dc2015-06-12 14:11:44 +09003462 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003463
3464 op_ifcs--;
3465
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003466 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003467
3468 /* Clear the Shadow scan */
3469 clear_shadow_scan(priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003470 if (op_ifcs == 0) {
3471 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003472 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003473 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003474
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003475 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003476 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003477
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003478 return s32Error;
3479}
3480
3481
3482/**
3483 * @brief WILC_WFI_WiphyFree
3484 * @details Freeing allocation of the wireless device structure
3485 * @param[in] NONE
3486 * @return NONE
3487 * @author mdaftedar
3488 * @date 01 MAR 2012
3489 * @version 1.0
3490 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003491void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003492{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003493 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3494
Chaehyun Lim619837a2015-09-20 15:51:10 +09003495 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003496 PRINT_D(INIT_DBG, "net_device is NULL\n");
3497 return;
3498 }
3499
Chaehyun Lim619837a2015-09-20 15:51:10 +09003500 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003501 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3502 return;
3503 }
3504
Chaehyun Lim619837a2015-09-20 15:51:10 +09003505 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003506 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3507 return;
3508 }
3509
3510 wiphy_unregister(net->ieee80211_ptr->wiphy);
3511
3512 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3513 wiphy_free(net->ieee80211_ptr->wiphy);
3514 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003515}