blob: cc279c654e53bdcebfcf560553b4db8994830f55 [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"
Arnd Bergmann491880e2015-11-16 15:04:55 +010014#include "host_interface.h"
Leo Kim7ae43362015-09-16 18:35:59 +090015#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +090016
Arnd Bergmann15162fb2015-11-16 15:04:57 +010017/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */
18#define NO_ENCRYPT 0
19#define ENCRYPT_ENABLED BIT(0)
20#define WEP BIT(1)
21#define WEP_EXTENDED BIT(2)
22#define WPA BIT(3)
23#define WPA2 BIT(4)
24#define AES BIT(5)
25#define TKIP BIT(6)
26
27/*Public action frame index IDs*/
28#define FRAME_TYPE_ID 0
29#define ACTION_CAT_ID 24
30#define ACTION_SUBTYPE_ID 25
31#define P2P_PUB_ACTION_SUBTYPE 30
32
33/*Public action frame Attribute IDs*/
34#define ACTION_FRAME 0xd0
35#define GO_INTENT_ATTR_ID 0x04
36#define CHANLIST_ATTR_ID 0x0b
37#define OPERCHAN_ATTR_ID 0x11
38#define PUB_ACTION_ATTR_ID 0x04
39#define P2PELEM_ATTR_ID 0xdd
40
41/*Public action subtype values*/
42#define GO_NEG_REQ 0x00
43#define GO_NEG_RSP 0x01
44#define GO_NEG_CONF 0x02
45#define P2P_INV_REQ 0x03
46#define P2P_INV_RSP 0x04
47#define PUBLIC_ACT_VENDORSPEC 0x09
48#define GAS_INTIAL_REQ 0x0a
49#define GAS_INTIAL_RSP 0x0b
50
51#define INVALID_CHANNEL 0
52
53#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
54#define SCAN_RESULT_EXPIRE (40 * HZ)
55
56static const u32 cipher_suites[] = {
57 WLAN_CIPHER_SUITE_WEP40,
58 WLAN_CIPHER_SUITE_WEP104,
59 WLAN_CIPHER_SUITE_TKIP,
60 WLAN_CIPHER_SUITE_CCMP,
61 WLAN_CIPHER_SUITE_AES_CMAC,
62};
63
64static const struct ieee80211_txrx_stypes
65 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
66 [NL80211_IFTYPE_STATION] = {
67 .tx = 0xffff,
68 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
69 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
70 },
71 [NL80211_IFTYPE_AP] = {
72 .tx = 0xffff,
73 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
74 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
75 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
76 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
77 BIT(IEEE80211_STYPE_AUTH >> 4) |
78 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
79 BIT(IEEE80211_STYPE_ACTION >> 4)
80 },
81 [NL80211_IFTYPE_P2P_CLIENT] = {
82 .tx = 0xffff,
83 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
84 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
85 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
86 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
87 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
88 BIT(IEEE80211_STYPE_AUTH >> 4) |
89 BIT(IEEE80211_STYPE_DEAUTH >> 4)
90 }
91};
92
93/* Time to stay on the channel */
94#define WILC_WFI_DWELL_PASSIVE 100
95#define WILC_WFI_DWELL_ACTIVE 40
96
97#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
98#define DEFAULT_LINK_SPEED 72
99
100
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900101#define IS_MANAGMEMENT 0x100
102#define IS_MANAGMEMENT_CALLBACK 0x080
103#define IS_MGMT_STATUS_SUCCES 0x040
104#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
105
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100106extern int wilc_mac_open(struct net_device *ndev);
107extern int wilc_mac_close(struct net_device *ndev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900108
Arnd Bergmann1608c402015-11-16 15:04:53 +0100109static tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
110static u32 u32LastScannedNtwrksCountShadow;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100111struct timer_list wilc_during_ip_timer;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100112static struct timer_list hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900113static u8 op_ifcs;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900114
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100115u8 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900116
117#define CHAN2G(_channel, _freq, _flags) { \
118 .band = IEEE80211_BAND_2GHZ, \
119 .center_freq = (_freq), \
120 .hw_value = (_channel), \
121 .flags = (_flags), \
122 .max_antenna_gain = 0, \
123 .max_power = 30, \
124}
125
126/*Frequency range for channels*/
127static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
128 CHAN2G(1, 2412, 0),
129 CHAN2G(2, 2417, 0),
130 CHAN2G(3, 2422, 0),
131 CHAN2G(4, 2427, 0),
132 CHAN2G(5, 2432, 0),
133 CHAN2G(6, 2437, 0),
134 CHAN2G(7, 2442, 0),
135 CHAN2G(8, 2447, 0),
136 CHAN2G(9, 2452, 0),
137 CHAN2G(10, 2457, 0),
138 CHAN2G(11, 2462, 0),
139 CHAN2G(12, 2467, 0),
140 CHAN2G(13, 2472, 0),
141 CHAN2G(14, 2484, 0),
142};
143
144#define RATETAB_ENT(_rate, _hw_value, _flags) { \
145 .bitrate = (_rate), \
146 .hw_value = (_hw_value), \
147 .flags = (_flags), \
148}
149
150
151/* Table 6 in section 3.2.1.1 */
152static struct ieee80211_rate WILC_WFI_rates[] = {
153 RATETAB_ENT(10, 0, 0),
154 RATETAB_ENT(20, 1, 0),
155 RATETAB_ENT(55, 2, 0),
156 RATETAB_ENT(110, 3, 0),
157 RATETAB_ENT(60, 9, 0),
158 RATETAB_ENT(90, 6, 0),
159 RATETAB_ENT(120, 7, 0),
160 RATETAB_ENT(180, 8, 0),
161 RATETAB_ENT(240, 9, 0),
162 RATETAB_ENT(360, 10, 0),
163 RATETAB_ENT(480, 11, 0),
164 RATETAB_ENT(540, 12, 0),
165};
166
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900167struct p2p_mgmt_data {
168 int size;
169 u8 *buff;
170};
171
172/*Global variable used to state the current connected STA channel*/
Arnd Bergmann1608c402015-11-16 15:04:53 +0100173static u8 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900174
Arnd Bergmann1608c402015-11-16 15:04:53 +0100175static u8 curr_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900176
Arnd Bergmann1608c402015-11-16 15:04:53 +0100177static u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
178static u8 u8P2Plocalrandom = 0x01;
179static u8 u8P2Precvrandom = 0x00;
180static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
181static bool bWilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900182
183static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
184 .channels = WILC_WFI_2ghz_channels,
185 .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels),
186 .bitrates = WILC_WFI_rates,
187 .n_bitrates = ARRAY_SIZE(WILC_WFI_rates),
188};
189
190
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191struct add_key_params {
192 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900193 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900194 u8 *mac_addr;
195};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100196static struct add_key_params g_add_gtk_key_params;
197static struct wilc_wfi_key g_key_gtk_params;
198static struct add_key_params g_add_ptk_key_params;
199static struct wilc_wfi_key g_key_ptk_params;
200static struct wilc_wfi_wep_key g_key_wep_params;
201static bool g_ptk_keys_saved;
202static bool g_gtk_keys_saved;
203static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900204
205#define AGING_TIME (9 * 1000)
206#define duringIP_TIME 15000
207
Arnd Bergmann1608c402015-11-16 15:04:53 +0100208static void clear_shadow_scan(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900209{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900210 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900211
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900212 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700213 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900214 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
215
216 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
217 if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +0900218 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900219 astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL;
220 }
221
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100222 wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900223 astrLastScannedNtwrksShadow[i].pJoinParams = NULL;
224 }
225 u32LastScannedNtwrksCountShadow = 0;
226 }
227
228}
229
Arnd Bergmann1608c402015-11-16 15:04:53 +0100230static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900231{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900232 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900233 int rssi_v = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900234 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900235
236 for (i = 0; i < num_rssi; i++)
237 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
238
239 rssi_v /= num_rssi;
240 return rssi_v;
241}
242
Arnd Bergmann1608c402015-11-16 15:04:53 +0100243static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900244{
Chaehyun Lim27268872015-09-15 14:06:13 +0900245 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900246 struct wiphy *wiphy;
247 struct cfg80211_bss *bss = NULL;
248 int i;
249 int rssi = 0;
250
Chaehyun Lim27268872015-09-15 14:06:13 +0900251 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900252 wiphy = priv->dev->ieee80211_ptr->wiphy;
253
254 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
255 tstrNetworkInfo *pstrNetworkInfo;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900256
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900257 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
258
259
260 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900261 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900262 struct ieee80211_channel *channel;
263
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900264 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900265
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900266 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900267 channel = ieee80211_get_channel(wiphy, s32Freq);
268
269 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900270 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
272 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900273 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900274 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900275 }
276 }
277
278 }
279 }
280
281}
282
Arnd Bergmann1608c402015-11-16 15:04:53 +0100283static void reset_shadow_found(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900284{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900285 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900286
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900287 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
288 astrLastScannedNtwrksShadow[i].u8Found = 0;
289
290 }
291}
292
Arnd Bergmann1608c402015-11-16 15:04:53 +0100293static void update_scan_time(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900294{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900295 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900296
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
298 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
299 }
300}
301
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700302static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900303{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900304 unsigned long now = jiffies;
305 int i, j;
306
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900307
308 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
309 if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530310 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900311
Shraddha Barkecccfc392015-10-12 20:49:19 +0530312 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
313 astrLastScannedNtwrksShadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900314
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100315 wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900316
317 for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) {
318 astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1];
319 }
320 u32LastScannedNtwrksCountShadow--;
321 }
322 }
323
324 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow);
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700325 if (u32LastScannedNtwrksCountShadow != 0) {
326 hAgingTimer.data = arg;
327 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
328 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900329 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700330 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900331}
332
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700333static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900334{
335 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100336 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900337}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900338
Arnd Bergmann1608c402015-11-16 15:04:53 +0100339static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900340{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900341 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900342 int i;
343
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900344 if (u32LastScannedNtwrksCountShadow == 0) {
345 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700346 hAgingTimer.data = (unsigned long)pUserVoid;
347 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900348 state = -1;
349 } else {
350 /* Linear search for now */
351 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900352 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900353 pstrNetworkInfo->au8bssid, 6) == 0) {
354 state = i;
355 break;
356 }
357 }
358 }
359 return state;
360}
361
Arnd Bergmann1608c402015-11-16 15:04:53 +0100362static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900363{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900364 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900365 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900366 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900367
368 if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
369 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
370 return;
371 }
372 if (ap_found == -1) {
373 ap_index = u32LastScannedNtwrksCountShadow;
374 u32LastScannedNtwrksCountShadow++;
375
376 } else {
377 ap_index = ap_found;
378 }
379 rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
380 astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
381 if (rssi_index == NUM_RSSI) {
382 rssi_index = 0;
383 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
384 }
385 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
386
387 astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
388 astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
389
390 astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900391 memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900392 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
393
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900394 memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900395 pstrNetworkInfo->au8bssid, ETH_ALEN);
396
397 astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
398 astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
399 astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
400
401 astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
402 astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
403 if (ap_found != -1)
Chaehyun Lim49188af2015-08-11 10:32:41 +0900404 kfree(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900405 astrLastScannedNtwrksShadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900406 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900407 memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900408 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
409
410 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
411 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
412 astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
413 if (ap_found != -1)
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100414 wilc_free_join_params(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900415 astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
416
417}
418
419
420/**
421 * @brief CfgScanResult
422 * @details Callback function which returns the scan results found
423 *
424 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
425 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
426 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
427 * void* pUserVoid: Private structure associated with the wireless interface
428 * @return NONE
429 * @author mabubakr
430 * @date
431 * @version 1.0
432 */
Leo Kim1ec38152015-10-12 16:55:59 +0900433static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900434{
Chaehyun Lim27268872015-09-15 14:06:13 +0900435 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900436 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900437 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900438 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900439 struct cfg80211_bss *bss = NULL;
440
Chaehyun Lim27268872015-09-15 14:06:13 +0900441 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100442 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900443 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
444 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900445
446 if (!wiphy)
447 return;
448
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900449 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
450 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900451 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900452 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900453 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900454 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900455 PRINT_ER("wiphy signal type fial\n");
456 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900457 }
458
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900459 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900460 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900461 channel = ieee80211_get_channel(wiphy, s32Freq);
462
Leo Kim7ae43362015-09-16 18:35:59 +0900463 if (!channel)
464 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900465
466 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530467 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900468 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
469
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100470 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900471 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
472 /* max_scan_ssids */
473 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
474
475
476 priv->u32RcvdChCount++;
477
478
479
480 if (pJoinParams == NULL) {
481 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
482 }
483 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
484
485 /*P2P peers are sent to WPA supplicant and added to shadow table*/
486
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900487 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900488 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
489 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900490 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900491 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900492 }
493
494
495 } else {
496 PRINT_ER("Discovered networks exceeded the max limit\n");
497 }
498 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900499 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900500 /* So this network is discovered before, we'll just update its RSSI */
501 for (i = 0; i < priv->u32RcvdChCount; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900502 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530503 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900504
505 astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
506 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
507 break;
508 }
509 }
510 }
511 }
512 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530513 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
514 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900515 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900516
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530517 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530518 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530519 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530520 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900521
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200522 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900523
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900524 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900525 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900526 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900527 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900528 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900529 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200530 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900531
532 }
533 /*Aborting any scan operation during mac close*/
534 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200535 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900536
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530537 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900538 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900539
540 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900541 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900542
Dean Lee72ed4dc2015-06-12 14:11:44 +0900543 cfg80211_scan_done(priv->pstrScanReq, false);
544 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900545 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900546 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200547 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900548 }
549 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900550}
551
552
553/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900554 * @brief CfgConnectResult
555 * @details
556 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
557 * connection response or disconnection notification.
558 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900559 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900560 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
561 * void* pUserVoid: Private data associated with wireless interface
562 * @return NONE
563 * @author mabubakr
564 * @date 01 MAR 2012
565 * @version 1.0
566 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100567int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900568
Leo Kimed3f0372015-10-12 16:56:01 +0900569static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900570 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900571 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900572 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
573 void *pUserVoid)
574{
Chaehyun Lim27268872015-09-15 14:06:13 +0900575 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900576 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900577 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900578 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900579 struct wilc *wl;
580 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900581
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100582 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900583
Chaehyun Lim27268872015-09-15 14:06:13 +0900584 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900585 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900586 nic = netdev_priv(dev);
587 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900588 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900589
590 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
591 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530592 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900593
594 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
595
596 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
597
598 if ((u8MacStatus == MAC_DISCONNECTED) &&
599 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
600 /* The case here is that our station was waiting for association response frame and has just received it containing status code
601 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
602 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100603 wilc_wlan_set_bssid(priv->dev, NullBssid);
604 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900605
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900606 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900607 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900608 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900609
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530610 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900611 }
612
613 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900614 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900615 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900616
617 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
618 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900619 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900620
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900621
622 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900623 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900624 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
625 unsigned long now = jiffies;
626
627 if (time_after(now,
628 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900629 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900630 }
631
632 break;
633 }
634 }
635
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000636 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900637 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900638 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900639
640 }
641
642 }
643
644
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530645 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900646
647 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
648
649 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
650 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
651 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
652 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
653 /* be replaced by pstrConnectInfo->u16ConnectStatus */
654 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100655 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900656 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
657 pstrDisconnectNotifInfo->u16reason, priv->dev);
658 u8P2Plocalrandom = 0x01;
659 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900660 bWilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530661 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100662 wilc_wlan_set_bssid(priv->dev, NullBssid);
663 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900664
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900665 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900666 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900667 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900668 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
669 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900670 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900671 pstrDisconnectNotifInfo->u16reason = 3;
672 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900673 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
674 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900675 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900676 pstrDisconnectNotifInfo->u16reason = 1;
677 }
678 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530679 pstrDisconnectNotifInfo->ie_len, false,
680 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900681
682 }
683
684}
685
686
687/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900688 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900689 * @details Set channel for a given wireless interface. Some devices
690 * may support multi-channel operation (by channel hopping) so cfg80211
691 * doesn't verify much. Note, however, that the passed netdev may be
692 * %NULL as well if the user requested changing the channel for the
693 * device itself, or for a monitor interface.
694 * @param[in]
695 * @return int : Return 0 on Success
696 * @author mdaftedar
697 * @date 01 MAR 2012
698 * @version 1.0
699 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900700static int set_channel(struct wiphy *wiphy,
701 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900702{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900703 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900704 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900705 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900706
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900707 priv = wiphy_priv(wiphy);
708
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900709 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
710 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900711
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900712 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100713 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900714
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900715 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900716 PRINT_ER("Error in setting channel %d\n", channelnum);
717
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900718 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900719}
720
721/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900722 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900723 * @details Request to do a scan. If returning zero, the scan request is given
724 * the driver, and will be valid until passed to cfg80211_scan_done().
725 * For scan results, call cfg80211_inform_bss(); you can call this outside
726 * the scan/scan_done bracket too.
727 * @param[in]
728 * @return int : Return 0 on Success
729 * @author mabubakr
730 * @date 01 MAR 2012
731 * @version 1.0
732 */
733
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900734static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900735{
Chaehyun Lim27268872015-09-15 14:06:13 +0900736 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900737 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900738 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900739 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900740 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900741
742 priv = wiphy_priv(wiphy);
743
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744 priv->pstrScanReq = request;
745
746 priv->u32RcvdChCount = 0;
747
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100748 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900749
750
751 reset_shadow_found(priv);
752
Dean Lee72ed4dc2015-06-12 14:11:44 +0900753 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900754 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
755 /* max_scan_ssids */
756 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900757 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900758 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
759 }
760
761 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530762 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900763
764 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
765
766 if (request->n_ssids >= 1) {
767
768
Leo Kim607db442015-10-05 15:25:37 +0900769 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900770 strHiddenNetwork.u8ssidnum = request->n_ssids;
771
772
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900773 for (i = 0; i < request->n_ssids; i++) {
774
775 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900776 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900777 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900778 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
779 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530780 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900781 strHiddenNetwork.u8ssidnum -= 1;
782 }
783 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530784 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100785 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900786 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900787 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900788 CfgScanResult, (void *)priv, &strHiddenNetwork);
789 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530790 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100791 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900792 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900793 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900794 CfgScanResult, (void *)priv, NULL);
795 }
796
797 } else {
798 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530799 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900800 }
801
Leo Kime6e12662015-09-16 18:36:03 +0900802 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900803 s32Error = -EBUSY;
804 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
805 }
806
807 return s32Error;
808}
809
810/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900811 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900812 * @details Connect to the ESS with the specified parameters. When connected,
813 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
814 * If the connection fails for some reason, call cfg80211_connect_result()
815 * with the status from the AP.
816 * @param[in]
817 * @return int : Return 0 on Success
818 * @author mabubakr
819 * @date 01 MAR 2012
820 * @version 1.0
821 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900822static int connect(struct wiphy *wiphy, struct net_device *dev,
823 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900824{
Leo Kime6e12662015-09-16 18:36:03 +0900825 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900826 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900827 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900828 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900829 char *pcgroup_encrypt_val = NULL;
830 char *pccipher_group = NULL;
831 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900832
Chaehyun Lim27268872015-09-15 14:06:13 +0900833 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900834 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835 tstrNetworkInfo *pstrNetworkInfo = NULL;
836
837
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100838 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900839 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900840 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900841
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100842 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900843
Johnny Kim8a143302015-06-10 17:06:46 +0900844 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 +0900845 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900846 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900847 pstrWFIDrv->p2p_connect = 1;
848 } else {
849 pstrWFIDrv->p2p_connect = 0;
850 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530851 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900852
853 for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
854 if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900855 memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900856 sme->ssid,
857 sme->ssid_len) == 0) {
858 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
859 if (sme->bssid == NULL) {
860 /* BSSID is not passed from the user, so decision of matching
861 * is done by SSID only */
862 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
863 break;
864 } else {
865 /* BSSID is also passed from the user, so decision of matching
866 * should consider also this passed BSSID */
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900867 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900868 sme->bssid,
869 ETH_ALEN) == 0) {
870 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
871 break;
872 }
873 }
874 }
875 }
876
877 if (i < u32LastScannedNtwrksCountShadow) {
878 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
879
880 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
881
882 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
883 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
884 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
885 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
886 } else {
887 s32Error = -ENOENT;
888 if (u32LastScannedNtwrksCountShadow == 0)
889 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
890 else
891 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
892
893 goto done;
894 }
895
896 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900897 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
898 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900899
900 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
901 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
902
903 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
904
905 if (INFO) {
906 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
907 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
908 }
909
910 if (sme->crypto.cipher_group != NO_ENCRYPT) {
911 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
912 * we will add to it the pairwise cipher suite(s) */
913 pcwpa_version = "Default";
914 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900915 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900916 u8security = ENCRYPT_ENABLED | WEP;
917 pcgroup_encrypt_val = "WEP40";
918 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
919 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
920
921 if (INFO) {
922 for (i = 0; i < sme->key_len; i++)
923 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
924 }
925 priv->WILC_WFI_wep_default = sme->key_idx;
926 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900927 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900928
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900929 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900930 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900931 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
932 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900933 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900934
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100935 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
936 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900937 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900938 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
939 pcgroup_encrypt_val = "WEP104";
940 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
941
942 priv->WILC_WFI_wep_default = sme->key_idx;
943 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900944 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900945
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900946 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900947 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900948 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
949 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900950 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900951
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100952 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
953 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900954 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900955 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900956 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
957 pcgroup_encrypt_val = "WPA2_TKIP";
958 pccipher_group = "TKIP";
959 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
960 /* tenuSecurity_t = WPA2_AES; */
961 u8security = ENCRYPT_ENABLED | WPA2 | AES;
962 pcgroup_encrypt_val = "WPA2_AES";
963 pccipher_group = "AES";
964 }
965 pcwpa_version = "WPA_VERSION_2";
966 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
967 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900968 u8security = ENCRYPT_ENABLED | WPA | TKIP;
969 pcgroup_encrypt_val = "WPA_TKIP";
970 pccipher_group = "TKIP";
971 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
972 /* tenuSecurity_t = WPA_AES; */
973 u8security = ENCRYPT_ENABLED | WPA | AES;
974 pcgroup_encrypt_val = "WPA_AES";
975 pccipher_group = "AES";
976
977 }
978 pcwpa_version = "WPA_VERSION_1";
979
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900980 } else {
981 s32Error = -ENOTSUPP;
982 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
983
984 goto done;
985 }
986
987 }
988
989 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
990 * add to it the pairwise cipher suite(s) */
991 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
992 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
993 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
994 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
995 u8security = u8security | TKIP;
996 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
997 u8security = u8security | AES;
998 }
999 }
1000 }
1001
1002 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
1003
1004 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
1005 switch (sme->auth_type) {
1006 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1007 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
1008 tenuAuth_type = OPEN_SYSTEM;
1009 break;
1010
1011 case NL80211_AUTHTYPE_SHARED_KEY:
1012 tenuAuth_type = SHARED_KEY;
1013 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
1014 break;
1015
1016 default:
1017 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1018 }
1019
1020
1021 /* ai: key_mgmt: enterprise case */
1022 if (sme->crypto.n_akm_suites) {
1023 switch (sme->crypto.akm_suites[0]) {
1024 case WLAN_AKM_SUITE_8021X:
1025 tenuAuth_type = IEEE8021;
1026 break;
1027
1028 default:
1029 break;
1030 }
1031 }
1032
1033
1034 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1035
1036 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1037 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1038
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001039 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001040
Leo Kimab16ec02015-10-29 12:05:40 +09001041 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001042 u8WLANChannel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001043
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001044 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001045
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001046 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001047 sme->ssid_len, sme->ie, sme->ie_len,
1048 CfgConnectResult, (void *)priv, u8security,
1049 tenuAuth_type, pstrNetworkInfo->u8channel,
1050 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001051 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001052 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001053 s32Error = -ENOENT;
1054 goto done;
1055 }
1056
1057done:
1058
1059 return s32Error;
1060}
1061
1062
1063/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001064 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001065 * @details Disconnect from the BSS/ESS.
1066 * @param[in]
1067 * @return int : Return 0 on Success
1068 * @author mdaftedar
1069 * @date 01 MAR 2012
1070 * @version 1.0
1071 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001072static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001073{
Leo Kime6e12662015-09-16 18:36:03 +09001074 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001075 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001076 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001077 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001078
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001079 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001080 priv = wiphy_priv(wiphy);
1081
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001082 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kim441dc602015-10-12 16:55:35 +09001083 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001084 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001085 u8WLANChannel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001086 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001087
1088 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1089
1090 u8P2Plocalrandom = 0x01;
1091 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001092 bWilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001093 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001094
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001095 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001096 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001097 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1098 s32Error = -EINVAL;
1099 }
1100
1101 return s32Error;
1102}
1103
1104/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001105 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001106 * @details Add a key with the given parameters. @mac_addr will be %NULL
1107 * when adding a group key.
1108 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1109 * @return int : Return 0 on Success
1110 * @author mdaftedar
1111 * @date 01 MAR 2012
1112 * @version 1.0
1113 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001114static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1115 bool pairwise,
1116 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001117
1118{
Leo Kime6e12662015-09-16 18:36:03 +09001119 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001120 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001121 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001122 const u8 *pu8RxMic = NULL;
1123 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001124 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001125 u8 u8gmode = NO_ENCRYPT;
1126 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001127 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001128 struct wilc *wl;
1129 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001130
1131 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001132 nic = netdev_priv(netdev);
1133 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001134
1135 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1136
Johnny Kim8a143302015-06-10 17:06:46 +09001137 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001138
1139 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1140 params->key[1],
1141 params->key[2]);
1142
1143
1144 switch (params->cipher) {
1145 case WLAN_CIPHER_SUITE_WEP40:
1146 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001147 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1148
1149 priv->WILC_WFI_wep_default = key_index;
1150 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001151 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001152
1153 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1154 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1155
1156 for (i = 0; i < params->key_len; i++)
1157 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1158
1159 tenuAuth_type = OPEN_SYSTEM;
1160
1161 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1162 u8mode = ENCRYPT_ENABLED | WEP;
1163 else
1164 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1165
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001166 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 +09001167 break;
1168 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001169 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001170 priv->WILC_WFI_wep_default = key_index;
1171 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001172 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001173
1174 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1175 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1176 if (INFO) {
1177 for (i = 0; i < params->key_len; i++)
1178 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1179 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001180 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001181 }
1182
1183 break;
1184
1185 case WLAN_CIPHER_SUITE_TKIP:
1186 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001187 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1188
1189 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001190 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001191 priv->wilc_gtk[key_index]->key = NULL;
1192 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001193
1194 }
1195 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001196 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001197 priv->wilc_ptk[key_index]->key = NULL;
1198 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001199 }
1200
1201
1202
Daniel Machon19132212015-08-05 08:18:31 +02001203 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001204 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1205 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1206 else
1207 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1208
1209 priv->wilc_groupkey = u8gmode;
1210
1211 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1212
1213 pu8TxMic = params->key + 24;
1214 pu8RxMic = params->key + 16;
1215 KeyLen = params->key_len - 16;
1216 }
1217 /* 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 +05301218 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001219
Glen Leef3052582015-09-10 12:03:04 +09001220 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001221 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001222
1223 /* 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 +05301224 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001225
1226 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001227 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001228 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001229 }
1230
1231 priv->wilc_gtk[key_index]->cipher = params->cipher;
1232 priv->wilc_gtk[key_index]->key_len = params->key_len;
1233 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1234
1235 if (INFO) {
1236 for (i = 0; i < params->key_len; i++)
1237 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1238 for (i = 0; i < params->seq_len; i++)
1239 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1240 }
1241
1242
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001243 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001244 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1245
1246 } else {
1247 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]);
1248
1249 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1250 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1251 else
1252 u8pmode = priv->wilc_groupkey | AES;
1253
1254
1255 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1256
1257 pu8TxMic = params->key + 24;
1258 pu8RxMic = params->key + 16;
1259 KeyLen = params->key_len - 16;
1260 }
1261
Shraddha Barkecccfc392015-10-12 20:49:19 +05301262 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001263
Glen Leef3052582015-09-10 12:03:04 +09001264 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001265
Shraddha Barkecccfc392015-10-12 20:49:19 +05301266 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001267
1268 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001269 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001270
1271 if (INFO) {
1272 for (i = 0; i < params->key_len; i++)
1273 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1274
1275 for (i = 0; i < params->seq_len; i++)
1276 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1277 }
1278
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001279 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001280
1281 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001282 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001283
1284 priv->wilc_ptk[key_index]->cipher = params->cipher;
1285 priv->wilc_ptk[key_index]->key_len = params->key_len;
1286 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1287
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001288 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001289 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1290 }
1291 break;
1292 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001293
1294 {
1295 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001296 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001297 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1298 /* swap the tx mic by rx mic */
1299 pu8RxMic = params->key + 24;
1300 pu8TxMic = params->key + 16;
1301 KeyLen = params->key_len - 16;
1302 }
1303
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001304 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001305 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001306 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001307 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001308 if (!mac_addr) {
1309 g_add_gtk_key_params.mac_addr = NULL;
1310 } else {
Glen Leef3052582015-09-10 12:03:04 +09001311 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001312 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1313 }
1314 g_key_gtk_params.key_len = params->key_len;
1315 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001316 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001317 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1318 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001319 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001320 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1321 }
1322 g_key_gtk_params.cipher = params->cipher;
1323
1324 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1325 g_key_gtk_params.key[1],
1326 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001327 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328 }
1329
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001330 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001331 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001332 } else {
1333 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1334 /* swap the tx mic by rx mic */
1335 pu8RxMic = params->key + 24;
1336 pu8TxMic = params->key + 16;
1337 KeyLen = params->key_len - 16;
1338 }
1339
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001340 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001341 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001342 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001343 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001344 if (!mac_addr) {
1345 g_add_ptk_key_params.mac_addr = NULL;
1346 } else {
Glen Leef3052582015-09-10 12:03:04 +09001347 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001348 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1349 }
1350 g_key_ptk_params.key_len = params->key_len;
1351 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001352 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001353 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1354 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001355 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001356 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1357 }
1358 g_key_ptk_params.cipher = params->cipher;
1359
1360 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1361 g_key_ptk_params.key[1],
1362 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001363 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001364 }
1365
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001366 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001367 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1368 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1369 if (INFO) {
1370 for (i = 0; i < params->key_len; i++)
1371 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1372 }
1373 }
1374 }
1375 break;
1376
1377 default:
1378 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1379 s32Error = -ENOTSUPP;
1380
1381 }
1382
1383 return s32Error;
1384}
1385
1386/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001387 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001388 * @details Remove a key given the @mac_addr (%NULL for a group key)
1389 * and @key_index, return -ENOENT if the key doesn't exist.
1390 * @param[in]
1391 * @return int : Return 0 on Success
1392 * @author mdaftedar
1393 * @date 01 MAR 2012
1394 * @version 1.0
1395 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001396static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1397 u8 key_index,
1398 bool pairwise,
1399 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001400{
Chaehyun Lim27268872015-09-15 14:06:13 +09001401 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001402 struct wilc *wl;
1403 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001404
1405 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001406 nic = netdev_priv(netdev);
1407 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001408
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001409 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001410 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001411 g_ptk_keys_saved = false;
1412 g_gtk_keys_saved = false;
1413 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001414
1415 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301416 kfree(g_key_wep_params.key);
1417 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001418
1419 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1420
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001421 if ((priv->wilc_gtk[key_index]) != NULL) {
1422
Shraddha Barkecccfc392015-10-12 20:49:19 +05301423 kfree(priv->wilc_gtk[key_index]->key);
1424 priv->wilc_gtk[key_index]->key = NULL;
1425 kfree(priv->wilc_gtk[key_index]->seq);
1426 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001427
Chaehyun Lim49188af2015-08-11 10:32:41 +09001428 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001429 priv->wilc_gtk[key_index] = NULL;
1430
1431 }
1432
1433 if ((priv->wilc_ptk[key_index]) != NULL) {
1434
Shraddha Barkecccfc392015-10-12 20:49:19 +05301435 kfree(priv->wilc_ptk[key_index]->key);
1436 priv->wilc_ptk[key_index]->key = NULL;
1437 kfree(priv->wilc_ptk[key_index]->seq);
1438 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001439 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001440 priv->wilc_ptk[key_index] = NULL;
1441 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001442
1443 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301444 kfree(g_key_ptk_params.key);
1445 g_key_ptk_params.key = NULL;
1446 kfree(g_key_ptk_params.seq);
1447 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001448
Shraddha Barkecccfc392015-10-12 20:49:19 +05301449 kfree(g_key_gtk_params.key);
1450 g_key_gtk_params.key = NULL;
1451 kfree(g_key_gtk_params.seq);
1452 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001453
1454 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001455 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001456 }
1457
1458 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001459 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001460 priv->WILC_WFI_wep_key_len[key_index] = 0;
1461
1462 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001463 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001464 } else {
1465 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001466 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001467 }
1468
Leo Kimaaed3292015-10-12 16:55:38 +09001469 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001470}
1471
1472/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001473 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001474 * @details Get information about the key with the given parameters.
1475 * @mac_addr will be %NULL when requesting information for a group
1476 * key. All pointers given to the @callback function need not be valid
1477 * after it returns. This function should return an error if it is
1478 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1479 * @param[in]
1480 * @return int : Return 0 on Success
1481 * @author mdaftedar
1482 * @date 01 MAR 2012
1483 * @version 1.0
1484 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001485static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1486 bool pairwise,
1487 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001488{
Chaehyun Lim27268872015-09-15 14:06:13 +09001489 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001490 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001491 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001492
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001493 priv = wiphy_priv(wiphy);
1494
1495
Alison Schofield3604af52015-10-12 13:22:44 -07001496 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001497 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1498
1499 key_params.key = priv->wilc_gtk[key_index]->key;
1500 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1501 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1502 key_params.seq = priv->wilc_gtk[key_index]->seq;
1503 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1504 if (INFO) {
1505 for (i = 0; i < key_params.key_len; i++)
1506 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1507 }
1508 } else {
1509 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1510
1511 key_params.key = priv->wilc_ptk[key_index]->key;
1512 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1513 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1514 key_params.seq = priv->wilc_ptk[key_index]->seq;
1515 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1516 }
1517
1518 callback(cookie, &key_params);
1519
Leo Kimaaed3292015-10-12 16:55:38 +09001520 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001521}
1522
1523/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001524 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001525 * @details Set the default management frame key on an interface
1526 * @param[in]
1527 * @return int : Return 0 on Success.
1528 * @author mdaftedar
1529 * @date 01 MAR 2012
1530 * @version 1.0
1531 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001532static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1533 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001534{
Chaehyun Lim27268872015-09-15 14:06:13 +09001535 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001536
1537
1538 priv = wiphy_priv(wiphy);
1539
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301540 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001541
1542 if (key_index != priv->WILC_WFI_wep_default) {
1543
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001544 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001545 }
1546
Leo Kimaaed3292015-10-12 16:55:38 +09001547 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001548}
1549
1550/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001551 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001552 * @details Get station information for the station identified by @mac
1553 * @param[in] NONE
1554 * @return int : Return 0 on Success.
1555 * @author mdaftedar
1556 * @date 01 MAR 2012
1557 * @version 1.0
1558 */
1559
Chaehyun Limf06f5622015-09-14 12:24:18 +09001560static int get_station(struct wiphy *wiphy, struct net_device *dev,
1561 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001562{
Chaehyun Lim27268872015-09-15 14:06:13 +09001563 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001564 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001565 u32 i = 0;
1566 u32 associatedsta = 0;
1567 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001568 priv = wiphy_priv(wiphy);
1569 nic = netdev_priv(dev);
1570
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001571 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1572 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1573
1574 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1575
1576 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1577
1578 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1579 associatedsta = i;
1580 break;
1581 }
1582
1583 }
1584
1585 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001586 PRINT_ER("Station required is not associated\n");
1587 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001588 }
1589
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001591
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001592 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001593 sinfo->inactive_time = 1000 * inactive_time;
1594 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1595
1596 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001597
1598 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001599 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001600
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001601 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001602
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001603 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301604 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001605 BIT(NL80211_STA_INFO_TX_PACKETS) |
1606 BIT(NL80211_STA_INFO_TX_FAILED) |
1607 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001608
Leo Kim00c8dfc2015-10-29 12:05:30 +09001609 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001610 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001611 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1612 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001613 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001614
Leo Kim5babeec2015-10-29 12:05:29 +09001615 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1616 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001617 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001618 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001619 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001620
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001621 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1622 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001623 }
Leo Kimaaed3292015-10-12 16:55:38 +09001624 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001625}
1626
1627
1628/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001629 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001630 * @details Modify parameters for a given BSS.
1631 * @param[in]
1632 * -use_cts_prot: Whether to use CTS protection
1633 * (0 = no, 1 = yes, -1 = do not change)
1634 * -use_short_preamble: Whether the use of short preambles is allowed
1635 * (0 = no, 1 = yes, -1 = do not change)
1636 * -use_short_slot_time: Whether the use of short slot time is allowed
1637 * (0 = no, 1 = yes, -1 = do not change)
1638 * -basic_rates: basic rates in IEEE 802.11 format
1639 * (or NULL for no change)
1640 * -basic_rates_len: number of basic rates
1641 * -ap_isolate: do not forward packets between connected stations
1642 * -ht_opmode: HT Operation mode
1643 * (u16 = opmode, -1 = do not change)
1644 * @return int : Return 0 on Success.
1645 * @author mdaftedar
1646 * @date 01 MAR 2012
1647 * @version 1.0
1648 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001649static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1650 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001651{
1652 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1653 return 0;
1654}
1655
1656/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001657 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001658 * @details Notify that wiphy parameters have changed;
1659 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1660 * have changed.
1661 * @return int : Return 0 on Success
1662 * @author mdaftedar
1663 * @date 01 MAR 2012
1664 * @version 1.0
1665 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001666static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001667{
Leo Kime6e12662015-09-16 18:36:03 +09001668 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001669 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001670 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001671
1672 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001673
Tony Cho87c05b22015-10-12 16:56:07 +09001674 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301675 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001676
1677 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1678 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1679 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001680 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001681 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1682 }
1683 if (changed & WIPHY_PARAM_RETRY_LONG) {
1684
1685 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 +09001686 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001687 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1688
1689 }
1690 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1691 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 +09001692 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001693 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1694
1695 }
1696
1697 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1698 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1699
Tony Cho87c05b22015-10-12 16:56:07 +09001700 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001701 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1702
1703 }
1704
1705 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001706 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001707 if (s32Error)
1708 PRINT_ER("Error in setting WIPHY PARAMS\n");
1709
1710
1711 return s32Error;
1712}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001713
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001714/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001715 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001716 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1717 * devices running firmwares capable of generating the (re) association
1718 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1719 * @param[in]
1720 * @return int : Return 0 on Success
1721 * @author mdaftedar
1722 * @date 01 MAR 2012
1723 * @version 1.0
1724 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001725static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1726 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001727{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001728 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001729 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001730 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001731
Chaehyun Lim27268872015-09-15 14:06:13 +09001732 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001733
1734 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1735
1736
1737 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001738 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001739 ETH_ALEN)) {
1740 /*If bssid already exists and pmkid value needs to reset*/
1741 flag = PMKID_FOUND;
1742 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1743 break;
1744 }
1745 }
1746 if (i < WILC_MAX_NUM_PMKIDS) {
1747 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001748 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001749 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001750 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001751 PMKID_LEN);
1752 if (!(flag == PMKID_FOUND))
1753 priv->pmkid_list.numpmkid++;
1754 } else {
1755 PRINT_ER("Invalid PMKID index\n");
1756 s32Error = -EINVAL;
1757 }
1758
1759 if (!s32Error) {
1760 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001761 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001762 }
1763 return s32Error;
1764}
1765
1766/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001767 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001768 * @details Delete a cached PMKID.
1769 * @param[in]
1770 * @return int : Return 0 on Success
1771 * @author mdaftedar
1772 * @date 01 MAR 2012
1773 * @version 1.0
1774 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001775static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1776 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001777{
1778
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001779 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001780 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001781
Chaehyun Lim27268872015-09-15 14:06:13 +09001782 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001783
1784 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1785
1786 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001787 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001788 ETH_ALEN)) {
1789 /*If bssid is found, reset the values*/
1790 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001791 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001792 break;
1793 }
1794 }
1795
1796 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1797 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001798 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001799 priv->pmkid_list.pmkidlist[i + 1].bssid,
1800 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001801 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001802 priv->pmkid_list.pmkidlist[i].pmkid,
1803 PMKID_LEN);
1804 }
1805 priv->pmkid_list.numpmkid--;
1806 } else {
1807 s32Error = -EINVAL;
1808 }
1809
1810 return s32Error;
1811}
1812
1813/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001814 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001815 * @details Flush all cached PMKIDs.
1816 * @param[in]
1817 * @return int : Return 0 on Success
1818 * @author mdaftedar
1819 * @date 01 MAR 2012
1820 * @version 1.0
1821 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001822static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001823{
Chaehyun Lim27268872015-09-15 14:06:13 +09001824 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001825
1826 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1827
1828 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001829 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001830
1831 return 0;
1832}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001833
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001834
1835/**
1836 * @brief WILC_WFI_CfgParseRxAction
1837 * @details Function parses the received frames and modifies the following attributes:
1838 * -GO Intent
1839 * -Channel list
1840 * -Operating Channel
1841 *
1842 * @param[in] u8* Buffer, u32 length
1843 * @return NONE.
1844 * @author mdaftedar
1845 * @date 12 DEC 2012
1846 * @version
1847 */
1848
Arnd Bergmann1608c402015-11-16 15:04:53 +01001849static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001850{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001851 u32 index = 0;
1852 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001853
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001854 u8 op_channel_attr_index = 0;
1855 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001856
1857 while (index < len) {
1858 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001859 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001860 }
1861
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301862 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001863 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301864 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001865 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001866 index += buf[index + 1] + 3; /* ID,Length byte */
1867 }
Alison Schofield3604af52015-10-12 13:22:44 -07001868 if (u8WLANChannel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001869
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001870 /*Modify channel list attribute*/
1871 if (channel_list_attr_index) {
1872 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1873 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1874 if (buf[i] == 0x51) {
1875 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1876 buf[j] = u8WLANChannel;
1877 }
1878 break;
1879 }
1880 }
1881 }
1882 /*Modify operating channel attribute*/
1883 if (op_channel_attr_index) {
1884 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1885 buf[op_channel_attr_index + 6] = 0x51;
1886 buf[op_channel_attr_index + 7] = u8WLANChannel;
1887 }
1888 }
1889}
1890
1891/**
1892 * @brief WILC_WFI_CfgParseTxAction
1893 * @details Function parses the transmitted action frames and modifies the
1894 * GO Intent attribute
1895 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1896 * @return NONE.
1897 * @author mdaftedar
1898 * @date 12 DEC 2012
1899 * @version
1900 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001901static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001902{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001903 u32 index = 0;
1904 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001905
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001906 u8 op_channel_attr_index = 0;
1907 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001908
1909 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001910 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001911 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001912
1913 break;
1914 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001915
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301916 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001917 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301918 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001919 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001920 index += buf[index + 1] + 3; /* ID,Length byte */
1921 }
Alison Schofield3604af52015-10-12 13:22:44 -07001922 if (u8WLANChannel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001923
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001924 /*Modify channel list attribute*/
1925 if (channel_list_attr_index) {
1926 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1927 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1928 if (buf[i] == 0x51) {
1929 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1930 buf[j] = u8WLANChannel;
1931 }
1932 break;
1933 }
1934 }
1935 }
1936 /*Modify operating channel attribute*/
1937 if (op_channel_attr_index) {
1938 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1939 buf[op_channel_attr_index + 6] = 0x51;
1940 buf[op_channel_attr_index + 7] = u8WLANChannel;
1941 }
1942 }
1943}
1944
1945/* @brief WILC_WFI_p2p_rx
1946 * @details
1947 * @param[in]
1948 *
1949 * @return None
1950 * @author Mai Daftedar
1951 * @date 2 JUN 2013
1952 * @version 1.0
1953 */
1954
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001955void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001956{
1957
Chaehyun Lim27268872015-09-15 14:06:13 +09001958 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001959 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001960 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001961 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001962 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001963
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001964 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001965 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001966
1967 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001968 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001969
1970 /* The packet offset field conain info about what type of managment frame */
1971 /* we are dealing with and ack status */
1972 pkt_offset = GET_PKT_OFFSET(header);
1973
1974 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1975 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1976 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001977 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001978 return;
1979 } else {
1980 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1981 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],
1982 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001983 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001984 } else {
1985 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],
1986 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001987 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001988 }
1989 return;
1990 }
1991 } else {
1992
1993 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1994
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001995 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001996 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001997
1998 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1999 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
2000
Leo Kim1229b1a2015-10-29 12:05:39 +09002001 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002002 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
2003 return;
2004 }
2005 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2006
2007 switch (buff[ACTION_SUBTYPE_ID]) {
2008 case GAS_INTIAL_REQ:
2009 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
2010 break;
2011
2012 case GAS_INTIAL_RSP:
2013 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
2014 break;
2015
2016 case PUBLIC_ACT_VENDORSPEC:
2017 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2018 * 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 +09002019 if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002020 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2021 if (!bWilc_ie) {
2022 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002023 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002024 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09002025 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002026 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
2027 break;
2028 }
2029 }
2030 }
2031 }
2032 if (u8P2Plocalrandom > u8P2Precvrandom) {
2033 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2034 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2035 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002036 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002037 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2038 break;
2039 }
2040 }
2041 }
2042 } else
2043 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2044 }
2045
2046
2047 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2048 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2049 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002050 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002051 return;
2052 }
2053 break;
2054
2055 default:
2056 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2057 break;
2058 }
2059 }
2060 }
2061
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002062 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002063 }
2064}
2065
2066/**
2067 * @brief WILC_WFI_mgmt_tx_complete
2068 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2069 * @param[in] priv
2070 * transmitting status
2071 * @return None
2072 * @author Amr Abdelmoghny
2073 * @date 20 MAY 2013
2074 * @version 1.0
2075 */
2076static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2077{
2078 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2079
2080
2081 kfree(pv_data->buff);
2082 kfree(pv_data);
2083}
2084
2085/**
2086 * @brief WILC_WFI_RemainOnChannelReady
2087 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2088 * @param
2089 * @return none
2090 * @author Amr abdelmoghny
2091 * @date 9 JUNE 2013
2092 * @version
2093 */
2094
2095static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2096{
Chaehyun Lim27268872015-09-15 14:06:13 +09002097 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002098
Chaehyun Lim27268872015-09-15 14:06:13 +09002099 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002100
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302101 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002102
Dean Lee72ed4dc2015-06-12 14:11:44 +09002103 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002104
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002105 cfg80211_ready_on_channel(priv->wdev,
2106 priv->strRemainOnChanParams.u64ListenCookie,
2107 priv->strRemainOnChanParams.pstrListenChan,
2108 priv->strRemainOnChanParams.u32ListenDuration,
2109 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002110}
2111
2112/**
2113 * @brief WILC_WFI_RemainOnChannelExpired
2114 * @details Callback function, called on expiration of remain-on-channel duration
2115 * @param
2116 * @return none
2117 * @author Amr abdelmoghny
2118 * @date 15 MAY 2013
2119 * @version
2120 */
2121
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002122static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002123{
Chaehyun Lim27268872015-09-15 14:06:13 +09002124 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002125
Chaehyun Lim27268872015-09-15 14:06:13 +09002126 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002127
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002128 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302129 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002130
Dean Lee72ed4dc2015-06-12 14:11:44 +09002131 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002132
2133 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002134 cfg80211_remain_on_channel_expired(priv->wdev,
2135 priv->strRemainOnChanParams.u64ListenCookie,
2136 priv->strRemainOnChanParams.pstrListenChan,
2137 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002138 } else {
2139 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2140 , priv->strRemainOnChanParams.u32ListenSessionID);
2141 }
2142}
2143
2144
2145/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002146 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002147 * @details Request the driver to remain awake on the specified
2148 * channel for the specified duration to complete an off-channel
2149 * operation (e.g., public action frame exchange). When the driver is
2150 * ready on the requested channel, it must indicate this with an event
2151 * notification by calling cfg80211_ready_on_channel().
2152 * @param[in]
2153 * @return int : Return 0 on Success
2154 * @author mdaftedar
2155 * @date 01 MAR 2012
2156 * @version 1.0
2157 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002158static int remain_on_channel(struct wiphy *wiphy,
2159 struct wireless_dev *wdev,
2160 struct ieee80211_channel *chan,
2161 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002162{
Leo Kime6e12662015-09-16 18:36:03 +09002163 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002164 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002165
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002166 priv = wiphy_priv(wiphy);
2167
2168 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2169
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002170
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002171 if (wdev->iftype == NL80211_IFTYPE_AP) {
2172 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2173 return s32Error;
2174 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002175
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002176 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002177
2178 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2179 priv->strRemainOnChanParams.pstrListenChan = chan;
2180 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002181 priv->strRemainOnChanParams.u32ListenDuration = duration;
2182 priv->strRemainOnChanParams.u32ListenSessionID++;
2183
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002184 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002185 , priv->strRemainOnChanParams.u32ListenSessionID
2186 , duration
2187 , chan->hw_value
2188 , WILC_WFI_RemainOnChannelExpired
2189 , WILC_WFI_RemainOnChannelReady
2190 , (void *)priv);
2191
2192 return s32Error;
2193}
2194
2195/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002196 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002197 * @details Cancel an on-going remain-on-channel operation.
2198 * This allows the operation to be terminated prior to timeout based on
2199 * the duration value.
2200 * @param[in] struct wiphy *wiphy,
2201 * @param[in] struct net_device *dev
2202 * @param[in] u64 cookie,
2203 * @return int : Return 0 on Success
2204 * @author mdaftedar
2205 * @date 01 MAR 2012
2206 * @version 1.0
2207 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002208static int cancel_remain_on_channel(struct wiphy *wiphy,
2209 struct wireless_dev *wdev,
2210 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002211{
Leo Kime6e12662015-09-16 18:36:03 +09002212 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002213 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002214
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002215 priv = wiphy_priv(wiphy);
2216
2217 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2218
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002219 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002220 return s32Error;
2221}
2222/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002223 * @brief WILC_WFI_mgmt_tx_frame
2224 * @details
2225 *
2226 * @param[in]
2227 * @return NONE.
2228 * @author mdaftedar
2229 * @date 01 JUL 2012
2230 * @version
2231 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002232static int mgmt_tx(struct wiphy *wiphy,
2233 struct wireless_dev *wdev,
2234 struct cfg80211_mgmt_tx_params *params,
2235 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002236{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002237 struct ieee80211_channel *chan = params->chan;
2238 unsigned int wait = params->wait;
2239 const u8 *buf = params->buf;
2240 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002241 const struct ieee80211_mgmt *mgmt;
2242 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002243 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002244 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002245 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002246 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002247 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002248
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002249 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002250 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002251 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002252
2253 *cookie = (unsigned long)buf;
2254 priv->u64tx_cookie = *cookie;
2255 mgmt = (const struct ieee80211_mgmt *) buf;
2256
2257 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2258
2259 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002260 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002261 if (mgmt_tx == NULL) {
2262 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002263 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002264 }
Glen Leef3052582015-09-10 12:03:04 +09002265 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002266 if (mgmt_tx->buff == NULL) {
2267 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002268 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002269 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002270 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002271 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002272 mgmt_tx->size = len;
2273
2274
2275 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2276 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2277 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002278 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002279 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002280 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002281 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002282 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002283
2284
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002285 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002286 /*Only set the channel, if not a negotiation confirmation frame
2287 * (If Negotiation confirmation frame, force it
2288 * to be transmitted on the same negotiation channel)*/
2289
2290 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2291 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2292 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002293 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002294 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002295 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002296 }
2297 switch (buf[ACTION_SUBTYPE_ID]) {
2298 case GAS_INTIAL_REQ:
2299 {
2300 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2301 break;
2302 }
2303
2304 case GAS_INTIAL_RSP:
2305 {
2306 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2307 break;
2308 }
2309
2310 case PUBLIC_ACT_VENDORSPEC:
2311 {
2312 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2313 * 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 +09002314 if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002315 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2316 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2317 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2318 get_random_bytes(&u8P2Plocalrandom, 1);
2319 /*Increment the number to prevent if its 0*/
2320 u8P2Plocalrandom++;
2321 }
2322 }
2323
2324 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2325 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2326 if (u8P2Plocalrandom > u8P2Precvrandom) {
2327 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2328
2329 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2330 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002331 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002332 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002333 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002334
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002335 /*If using supplicant go intent, no need at all*/
2336 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002337 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002338 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002339 break;
2340 }
2341 }
2342
2343 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302344 /*
2345 * Adding WILC information element to allow two WILC devices to
2346 * identify each other and connect
2347 */
2348 memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002349 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2350 mgmt_tx->size = buf_len;
2351 }
2352 } else
2353 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2354 }
2355
2356 } else {
2357 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2358 }
2359
2360 break;
2361 }
2362
2363 default:
2364 {
2365 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2366 break;
2367 }
2368 }
2369
2370 }
2371
2372 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 +09002373 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002374
Leo Kim1229b1a2015-10-29 12:05:39 +09002375 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2376 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002377 }
2378
Glen Lee829c4772015-10-29 12:18:44 +09002379 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2380 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002381 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002382 } else {
2383 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2384 }
Leo Kimaaed3292015-10-12 16:55:38 +09002385 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002386}
2387
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002388static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2389 struct wireless_dev *wdev,
2390 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002391{
Chaehyun Lim27268872015-09-15 14:06:13 +09002392 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002393 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002394
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002395 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002396 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002397
2398
2399 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002400 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002401
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002402 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002403 cfg80211_remain_on_channel_expired(priv->wdev,
2404 priv->strRemainOnChanParams.u64ListenCookie,
2405 priv->strRemainOnChanParams.pstrListenChan,
2406 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002407 }
2408
2409 return 0;
2410}
2411
2412/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002413 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002414 * @details Notify driver that a management frame type was
2415 * registered. Note that this callback may not sleep, and cannot run
2416 * concurrently with itself.
2417 * @param[in]
2418 * @return NONE.
2419 * @author mdaftedar
2420 * @date 01 JUL 2012
2421 * @version
2422 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002423void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2424 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002425{
2426
Chaehyun Lim27268872015-09-15 14:06:13 +09002427 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002428 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002429 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002430
2431 priv = wiphy_priv(wiphy);
2432 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002433 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002434
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002435 if (!frame_type)
2436 return;
2437
2438 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2439 switch (frame_type) {
2440 case PROBE_REQ:
2441 {
2442 nic->g_struct_frame_reg[0].frame_type = frame_type;
2443 nic->g_struct_frame_reg[0].reg = reg;
2444 }
2445 break;
2446
2447 case ACTION:
2448 {
2449 nic->g_struct_frame_reg[1].frame_type = frame_type;
2450 nic->g_struct_frame_reg[1].reg = reg;
2451 }
2452 break;
2453
2454 default:
2455 {
2456 break;
2457 }
2458
2459 }
2460 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002461 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002462 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2463 return;
2464 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002465 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002466
2467
2468}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002469
2470/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002471 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002472 * @details Configure connection quality monitor RSSI threshold.
2473 * @param[in] struct wiphy *wiphy:
2474 * @param[in] struct net_device *dev:
2475 * @param[in] s32 rssi_thold:
2476 * @param[in] u32 rssi_hyst:
2477 * @return int : Return 0 on Success
2478 * @author mdaftedar
2479 * @date 01 MAR 2012
2480 * @version 1.0
2481 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002482static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2483 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002484{
2485 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2486 return 0;
2487
2488}
2489/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002490 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002491 * @details Configure connection quality monitor RSSI threshold.
2492 * @param[in] struct wiphy *wiphy:
2493 * @param[in] struct net_device *dev
2494 * @param[in] int idx
2495 * @param[in] u8 *mac
2496 * @param[in] struct station_info *sinfo
2497 * @return int : Return 0 on Success
2498 * @author mdaftedar
2499 * @date 01 MAR 2012
2500 * @version 1.0
2501 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002502static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2503 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002504{
Chaehyun Lim27268872015-09-15 14:06:13 +09002505 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002506
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002507 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2508
2509 if (idx != 0)
2510 return -ENOENT;
2511
2512 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002513
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002514 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002515
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002516 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002517
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002518 return 0;
2519
2520}
2521
2522
2523/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002524 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002525 * @details
2526 * @param[in]
2527 * @return int : Return 0 on Success.
2528 * @author mdaftedar
2529 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002530 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002531 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002532static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2533 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002534{
Chaehyun Lim27268872015-09-15 14:06:13 +09002535 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002536
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002537 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2538
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002539 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002540 return -ENOENT;
2541
2542 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002543 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002544 PRINT_ER("Driver is NULL\n");
2545 return -EIO;
2546 }
2547
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002548 if (wilc_enable_ps)
2549 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002550
2551
Leo Kime6e12662015-09-16 18:36:03 +09002552 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002553
2554}
Glen Lee108b3432015-09-16 18:53:20 +09002555
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002556/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002557 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002558 * @details Change type/configuration of virtual interface,
2559 * keep the struct wireless_dev's iftype updated.
2560 * @param[in] NONE
2561 * @return int : Return 0 on Success.
2562 * @author mdaftedar
2563 * @date 01 MAR 2012
2564 * @version 1.0
2565 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002566static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2567 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002568{
Chaehyun Lim27268872015-09-15 14:06:13 +09002569 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002570 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002571 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002572 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002573 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002574 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002575
2576 nic = netdev_priv(dev);
2577 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002578 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002579
2580 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2581 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2582 u8P2Plocalrandom = 0x01;
2583 u8P2Precvrandom = 0x00;
2584
Dean Lee72ed4dc2015-06-12 14:11:44 +09002585 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002586
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002587 wilc_optaining_ip = false;
2588 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002589 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002590 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2591 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002592 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002593 }
2594
2595 switch (type) {
2596 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002597 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002598 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002599
2600 /* send delba over wlan interface */
2601
2602
2603 dev->ieee80211_ptr->iftype = type;
2604 priv->wdev->iftype = type;
2605 nic->monitor_flag = 0;
2606 nic->iftype = STATION_MODE;
2607
2608 /*Remove the enteries of the previously connected clients*/
2609 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002610 interface_type = nic->iftype;
2611 nic->iftype = STATION_MODE;
2612
Glen Lee299382c2015-10-20 17:13:56 +09002613 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002614 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2615 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002616 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002617 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002618
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002619 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002620 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002621
Glen Lee53dc0cf2015-10-20 17:13:57 +09002622 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002623 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002624 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002625 nic->iftype = interface_type;
2626
2627 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002628 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2629 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002630 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002631 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002632
2633 /*Add saved WEP keys, if any*/
2634 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002635 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002636 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002637 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002638 g_key_wep_params.key,
2639 g_key_wep_params.key_len,
2640 g_key_wep_params.key_idx);
2641 }
2642
2643 /*No matter the driver handler passed here, it will be overwriiten*/
2644 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002645 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002646
2647 /*Add saved PTK and GTK keys, if any*/
2648 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2649 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2650 g_key_ptk_params.key[1],
2651 g_key_ptk_params.key[2]);
2652 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2653 g_key_gtk_params.key[1],
2654 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002655 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2656 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002657 g_add_ptk_key_params.key_idx,
2658 g_add_ptk_key_params.pairwise,
2659 g_add_ptk_key_params.mac_addr,
2660 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002661
Glen Lee299382c2015-10-20 17:13:56 +09002662 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2663 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002664 g_add_gtk_key_params.key_idx,
2665 g_add_gtk_key_params.pairwise,
2666 g_add_gtk_key_params.mac_addr,
2667 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002668 }
2669
Glen Lee299382c2015-10-20 17:13:56 +09002670 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002671 for (i = 0; i < num_reg_frame; i++) {
2672 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2673 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002674 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002675 nic->g_struct_frame_reg[i].frame_type,
2676 nic->g_struct_frame_reg[i].reg);
2677 }
2678 }
2679
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002680 wilc_enable_ps = true;
2681 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002682 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683 break;
2684
2685 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002686 wilc_enable_ps = false;
2687 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2688 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002689 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002690
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002691 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2692 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002693
2694 dev->ieee80211_ptr->iftype = type;
2695 priv->wdev->iftype = type;
2696 nic->monitor_flag = 0;
2697
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002698 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2699 nic->iftype = CLIENT_MODE;
2700
2701
Glen Lee299382c2015-10-20 17:13:56 +09002702 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002703 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002704 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002705
Glen Lee53dc0cf2015-10-20 17:13:57 +09002706 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002707 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002708 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002709
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002710 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2711 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002712 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002713 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002714
2715 /*Add saved WEP keys, if any*/
2716 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002717 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2718 g_key_wep_params.key_idx);
2719 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2720 g_key_wep_params.key,
2721 g_key_wep_params.key_len,
2722 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002723 }
2724
2725 /*No matter the driver handler passed here, it will be overwriiten*/
2726 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002727 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002728
2729 /*Add saved PTK and GTK keys, if any*/
2730 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2731 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2732 g_key_ptk_params.key[1],
2733 g_key_ptk_params.key[2]);
2734 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2735 g_key_gtk_params.key[1],
2736 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002737 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2738 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002739 g_add_ptk_key_params.key_idx,
2740 g_add_ptk_key_params.pairwise,
2741 g_add_ptk_key_params.mac_addr,
2742 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002743
Glen Lee299382c2015-10-20 17:13:56 +09002744 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2745 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002746 g_add_gtk_key_params.key_idx,
2747 g_add_gtk_key_params.pairwise,
2748 g_add_gtk_key_params.mac_addr,
2749 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002750 }
2751
2752 /*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 +09002753 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002754 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002755
Glen Lee299382c2015-10-20 17:13:56 +09002756 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002757 for (i = 0; i < num_reg_frame; i++) {
2758 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2759 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002760 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002761 nic->g_struct_frame_reg[i].frame_type,
2762 nic->g_struct_frame_reg[i].reg);
2763 }
2764 }
2765 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766 break;
2767
2768 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002769 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002770 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002771 dev->ieee80211_ptr->iftype = type;
2772 priv->wdev->iftype = type;
2773 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002774 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002775
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002776 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002777 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002778 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002779 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002780 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002781 wilc_mac_close(dev);
2782 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002783
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002784 for (i = 0; i < num_reg_frame; i++) {
2785 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2786 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002787 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002788 nic->g_struct_frame_reg[i].frame_type,
2789 nic->g_struct_frame_reg[i].reg);
2790 }
2791 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002792 break;
2793
2794 case NL80211_IFTYPE_P2P_GO:
2795 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2796
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002797 wilc_optaining_ip = true;
2798 mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME));
2799 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002800 /*Delete block ack has to be the latest config packet*/
2801 /*sent before downloading new FW. This is because it blocks on*/
2802 /*hWaitResponse semaphore, which allows previous config*/
2803 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002804 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2805 wl->vif[0].bssid, TID);
2806 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002807 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002808 dev->ieee80211_ptr->iftype = type;
2809 priv->wdev->iftype = type;
2810
Johnny Kim8a143302015-06-10 17:06:46 +09002811 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002812
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002813 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2814
2815
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002816 nic->iftype = GO_MODE;
2817
2818 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002819 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002820 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002821 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002822 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002823
2824
2825 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002826 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2827 wilc_set_mac_address(wl->vif[0].hif_drv,
2828 wl->vif[0].src_addr);
2829 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002830
2831 /*Add saved WEP keys, if any*/
2832 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002833 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2834 g_key_wep_params.key_idx);
2835 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002836 g_key_wep_params.key,
2837 g_key_wep_params.key_len,
2838 g_key_wep_params.key_idx);
2839 }
2840
2841 /*No matter the driver handler passed here, it will be overwriiten*/
2842 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002843 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002844
2845 /*Add saved PTK and GTK keys, if any*/
2846 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2847 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2848 g_key_ptk_params.key[1],
2849 g_key_ptk_params.key[2],
2850 g_key_ptk_params.cipher);
2851 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2852 g_key_gtk_params.key[1],
2853 g_key_gtk_params.key[2],
2854 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002855 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2856 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002857 g_add_ptk_key_params.key_idx,
2858 g_add_ptk_key_params.pairwise,
2859 g_add_ptk_key_params.mac_addr,
2860 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002861
Glen Lee299382c2015-10-20 17:13:56 +09002862 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2863 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002864 g_add_gtk_key_params.key_idx,
2865 g_add_gtk_key_params.pairwise,
2866 g_add_gtk_key_params.mac_addr,
2867 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002868 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002869
Glen Lee299382c2015-10-20 17:13:56 +09002870 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002871 for (i = 0; i < num_reg_frame; i++) {
2872 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2873 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002874 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002875 nic->g_struct_frame_reg[i].frame_type,
2876 nic->g_struct_frame_reg[i].reg);
2877 }
2878 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002879 break;
2880
2881 default:
2882 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002883 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002884 }
2885
Leo Kimaaed3292015-10-12 16:55:38 +09002886 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002887}
2888
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002889/* (austin.2013-07-23)
2890 *
2891 * To support revised cfg80211_ops
2892 *
2893 * add_beacon --> start_ap
2894 * set_beacon --> change_beacon
2895 * del_beacon --> stop_ap
2896 *
2897 * beacon_parameters --> cfg80211_ap_settings
2898 * cfg80211_beacon_data
2899 *
2900 * applicable for linux kernel 3.4+
2901 */
2902
2903/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002904 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002905 * @details Add a beacon with given parameters, @head, @interval
2906 * and @dtim_period will be valid, @tail is optional.
2907 * @param[in] wiphy
2908 * @param[in] dev The net device structure
2909 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2910 * @return int : Return 0 on Success.
2911 * @author austin
2912 * @date 23 JUL 2013
2913 * @version 1.0
2914 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002915static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2916 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002917{
2918 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002919 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002920 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002921 struct wilc *wl;
2922 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002923
2924 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002925 nic = netdev_priv(dev);
2926 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002927 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2928
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302929 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 +09002930 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2931
Chaehyun Lim80785a92015-09-14 12:24:01 +09002932 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002933
Leo Kime6e12662015-09-16 18:36:03 +09002934 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002935 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002936
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002937 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002938
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002939 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002940 settings->beacon_interval,
2941 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002942 beacon->head_len, (u8 *)beacon->head,
2943 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002944
2945 return s32Error;
2946}
2947
2948/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002949 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002950 * @details Add a beacon with given parameters, @head, @interval
2951 * and @dtim_period will be valid, @tail is optional.
2952 * @param[in] wiphy
2953 * @param[in] dev The net device structure
2954 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2955 * @return int : Return 0 on Success.
2956 * @author austin
2957 * @date 23 JUL 2013
2958 * @version 1.0
2959 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002960static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2961 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002962{
Chaehyun Lim27268872015-09-15 14:06:13 +09002963 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002964 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002965
2966 priv = wiphy_priv(wiphy);
2967 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2968
2969
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002970 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002971 0,
2972 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002973 beacon->head_len, (u8 *)beacon->head,
2974 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002975
2976 return s32Error;
2977}
2978
2979/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002980 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002981 * @details Remove beacon configuration and stop sending the beacon.
2982 * @param[in]
2983 * @return int : Return 0 on Success.
2984 * @author austin
2985 * @date 23 JUL 2013
2986 * @version 1.0
2987 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002988static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002989{
Leo Kime6e12662015-09-16 18:36:03 +09002990 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002991 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002992 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002993
Leo Kim7ae43362015-09-16 18:35:59 +09002994 if (!wiphy)
2995 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002996
2997 priv = wiphy_priv(wiphy);
2998
2999 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
3000
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003001 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003002
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003003 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003004
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003005 if (s32Error)
3006 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003007
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003008 return s32Error;
3009}
3010
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003011/**
Chaehyun Limed269552015-09-14 12:24:15 +09003012 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003013 * @details Add a new station.
3014 * @param[in]
3015 * @return int : Return 0 on Success.
3016 * @author mdaftedar
3017 * @date 01 MAR 2012
3018 * @version 1.0
3019 */
Chaehyun Limed269552015-09-14 12:24:15 +09003020static int add_station(struct wiphy *wiphy, struct net_device *dev,
3021 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003022{
Leo Kime6e12662015-09-16 18:36:03 +09003023 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003024 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003025 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003026 perInterface_wlan_t *nic;
3027
Leo Kim7ae43362015-09-16 18:35:59 +09003028 if (!wiphy)
3029 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003030
3031 priv = wiphy_priv(wiphy);
3032 nic = netdev_priv(dev);
3033
3034 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003035 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003036 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003037 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003038 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003039 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003040
3041 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3042
3043 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],
3044 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003045 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003046 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3047 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003048
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003049 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003050 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003051 } else {
Leo Kim22520122015-10-29 12:05:45 +09003052 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003053 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003054 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003055 memcpy(strStaParams.ht_supp_mcs_set,
3056 &params->ht_capa->mcs,
3057 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003058 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003059 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003060 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003061 }
3062
Leo Kimf676e172015-10-29 12:05:52 +09003063 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003064 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003065
Leo Kim22520122015-10-29 12:05:45 +09003066 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3067 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003068 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3069 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003070 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3071 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003072 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3073 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003074 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3075 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003076 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3077 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003078 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3079 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003080 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3081 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003082
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003083 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003084 if (s32Error)
3085 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003086 }
3087
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003088 return s32Error;
3089}
3090
3091/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003092 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003093 * @details Remove a station; @mac may be NULL to remove all stations.
3094 * @param[in]
3095 * @return int : Return 0 on Success.
3096 * @author mdaftedar
3097 * @date 01 MAR 2012
3098 * @version 1.0
3099 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003100static int del_station(struct wiphy *wiphy, struct net_device *dev,
3101 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003102{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003103 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003104 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003105 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003106 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003107
Leo Kim7ae43362015-09-16 18:35:59 +09003108 if (!wiphy)
3109 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003110
3111 priv = wiphy_priv(wiphy);
3112 nic = netdev_priv(dev);
3113
3114 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3115 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3116
3117
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003118 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303119 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003120 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003121 } else {
3122 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]);
3123 }
3124
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003125 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003126
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003127 if (s32Error)
3128 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003129 }
3130 return s32Error;
3131}
3132
3133/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003134 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003135 * @details Modify a given station.
3136 * @param[in]
3137 * @return int : Return 0 on Success.
3138 * @author mdaftedar
3139 * @date 01 MAR 2012
3140 * @version 1.0
3141 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003142static int change_station(struct wiphy *wiphy, struct net_device *dev,
3143 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003144{
Leo Kime6e12662015-09-16 18:36:03 +09003145 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003146 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003147 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003148 perInterface_wlan_t *nic;
3149
3150
3151 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3152
Leo Kim7ae43362015-09-16 18:35:59 +09003153 if (!wiphy)
3154 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003155
3156 priv = wiphy_priv(wiphy);
3157 nic = netdev_priv(dev);
3158
3159 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003160 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003161 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003162 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003163 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003164
Leo Kim2353c382015-10-29 12:05:41 +09003165 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3166 strStaParams.bssid[0], strStaParams.bssid[1],
3167 strStaParams.bssid[2], strStaParams.bssid[3],
3168 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003169 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003170 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3171 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003172
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003173 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003174 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003175 } else {
Leo Kim22520122015-10-29 12:05:45 +09003176 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003177 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003178 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003179 memcpy(strStaParams.ht_supp_mcs_set,
3180 &params->ht_capa->mcs,
3181 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003182 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003183 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003184 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003185 }
3186
Leo Kimf676e172015-10-29 12:05:52 +09003187 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003188 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003189
Leo Kim22520122015-10-29 12:05:45 +09003190 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3191 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003192 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3193 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003194 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3195 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003196 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3197 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003198 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3199 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003200 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3201 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003202 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3203 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003204 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3205 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003206
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003207 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003208 if (s32Error)
3209 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003210 }
3211 return s32Error;
3212}
3213
3214
3215/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003216 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003217 * @details
3218 * @param[in]
3219 * @return int : Return 0 on Success.
3220 * @author mdaftedar
3221 * @date 01 JUL 2012
3222 * @version 1.0
3223 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003224static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3225 const char *name,
3226 unsigned char name_assign_type,
3227 enum nl80211_iftype type,
3228 u32 *flags,
3229 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003230{
3231 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003232 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003233 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003234
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003235 priv = wiphy_priv(wiphy);
3236
3237
3238
3239 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3240
3241 nic = netdev_priv(priv->wdev->netdev);
3242
3243
3244 if (type == NL80211_IFTYPE_MONITOR) {
3245 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3246 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3247 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3248 if (new_ifc != NULL) {
3249 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003250 nic = netdev_priv(priv->wdev->netdev);
3251 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003252 } else
3253 PRINT_ER("Error in initializing monitor interface\n ");
3254 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003255 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003256}
3257
3258/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003259 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003260 * @details
3261 * @param[in]
3262 * @return int : Return 0 on Success.
3263 * @author mdaftedar
3264 * @date 01 JUL 2012
3265 * @version 1.0
3266 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003267static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003268{
3269 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003270 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003271}
3272
Chaehyun Lim08241922015-09-15 14:06:12 +09003273static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003274
Chaehyun Lim80785a92015-09-14 12:24:01 +09003275 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003276 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003277 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003278 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003279 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003280 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003281 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003282 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003283 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003284 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003285 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003286
Chaehyun Lima13168d2015-09-14 12:24:12 +09003287 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003288 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003289 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003290 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003291 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003292 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003293 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003294 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003295 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003296 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003297
Chaehyun Lim4d466572015-09-14 12:24:22 +09003298 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003299 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003300 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003301 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003302 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003303 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003304 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003305 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003306 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003307 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003308
3309};
3310
3311
3312
3313
3314
3315/**
3316 * @brief WILC_WFI_update_stats
3317 * @details Modify parameters for a given BSS.
3318 * @param[in]
3319 * @return int : Return 0 on Success.
3320 * @author mdaftedar
3321 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003322 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003323 */
3324int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3325{
3326
Chaehyun Lim27268872015-09-15 14:06:13 +09003327 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003328
3329 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003330 switch (changed) {
3331
3332 case WILC_WFI_RX_PKT:
3333 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003334 priv->netstats.rx_packets++;
3335 priv->netstats.rx_bytes += pktlen;
3336 priv->netstats.rx_time = get_jiffies_64();
3337 }
3338 break;
3339
3340 case WILC_WFI_TX_PKT:
3341 {
3342 priv->netstats.tx_packets++;
3343 priv->netstats.tx_bytes += pktlen;
3344 priv->netstats.tx_time = get_jiffies_64();
3345
3346 }
3347 break;
3348
3349 default:
3350 break;
3351 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003352 return 0;
3353}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003354
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003355/**
3356 * @brief WILC_WFI_CfgAlloc
3357 * @details Allocation of the wireless device structure and assigning it
3358 * to the cfg80211 operations structure.
3359 * @param[in] NONE
3360 * @return wireless_dev : Returns pointer to wireless_dev structure.
3361 * @author mdaftedar
3362 * @date 01 MAR 2012
3363 * @version 1.0
3364 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003365static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003366{
3367
3368 struct wireless_dev *wdev;
3369
3370
3371 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3372 /*Allocating the wireless device structure*/
3373 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3374 if (!wdev) {
3375 PRINT_ER("Cannot allocate wireless device\n");
3376 goto _fail_;
3377 }
3378
3379 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003380 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003381 if (!wdev->wiphy) {
3382 PRINT_ER("Cannot allocate wiphy\n");
3383 goto _fail_mem_;
3384
3385 }
3386
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003387 /* enable 802.11n HT */
3388 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3389 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3390 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3391 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3392 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003393
3394 /*wiphy bands*/
3395 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3396
3397 return wdev;
3398
3399_fail_mem_:
3400 kfree(wdev);
3401_fail_:
3402 return NULL;
3403
3404}
3405/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003406 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003407 * @details Registering of the wiphy structure and interface modes
3408 * @param[in] NONE
3409 * @return NONE
3410 * @author mdaftedar
3411 * @date 01 MAR 2012
3412 * @version 1.0
3413 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003414struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003415{
Chaehyun Lim27268872015-09-15 14:06:13 +09003416 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003417 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003418 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003419
3420 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3421
3422 wdev = WILC_WFI_CfgAlloc();
3423 if (wdev == NULL) {
3424 PRINT_ER("CfgAlloc Failed\n");
3425 return NULL;
3426 }
3427
3428
3429 /*Return hardware description structure (wiphy)'s priv*/
3430 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003431 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003432
3433 /*Link the wiphy with wireless structure*/
3434 priv->wdev = wdev;
3435
3436 /*Maximum number of probed ssid to be added by user for the scan request*/
3437 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003438 /*Maximum number of pmkids to be cashed*/
3439 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3440 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003441
3442 wdev->wiphy->max_scan_ie_len = 1000;
3443
3444 /*signal strength in mBm (100*dBm) */
3445 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3446
3447 /*Set the availaible cipher suites*/
3448 wdev->wiphy->cipher_suites = cipher_suites;
3449 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003450 /*Setting default managment types: for register action frame: */
3451 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003452
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003453 wdev->wiphy->max_remain_on_channel_duration = 500;
3454 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3455 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3456 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003457 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003458 wdev->iftype = NL80211_IFTYPE_STATION;
3459
3460
3461
3462 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3463 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3464 wdev->wiphy->interface_modes, wdev->iftype);
3465
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003466 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003467
3468 /*Register wiphy structure*/
3469 s32Error = wiphy_register(wdev->wiphy);
3470 if (s32Error) {
3471 PRINT_ER("Cannot register wiphy device\n");
3472 /*should define what action to be taken in such failure*/
3473 } else {
3474 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3475 }
3476
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003477 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003478 return wdev;
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 Limdd4b6a82015-09-20 15:51:25 +09003491int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003492{
3493
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003494 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003495
Chaehyun Lim27268872015-09-15 14:06:13 +09003496 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003497
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003498 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3499 priv = wdev_priv(net->ieee80211_ptr);
3500 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003501 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003502 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003503 }
3504 op_ifcs++;
3505 if (s32Error < 0) {
3506 PRINT_ER("Failed to creat refresh Timer\n");
3507 return s32Error;
3508 }
3509
Dean Lee72ed4dc2015-06-12 14:11:44 +09003510 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003511
Dean Lee72ed4dc2015-06-12 14:11:44 +09003512 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003513
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003514 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003515 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003516 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003517 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003518
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003519 return s32Error;
3520}
3521
3522/**
3523 * @brief WILC_WFI_WiphyFree
3524 * @details Freeing allocation of the wireless device structure
3525 * @param[in] NONE
3526 * @return NONE
3527 * @author mdaftedar
3528 * @date 01 MAR 2012
3529 * @version 1.0
3530 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003531int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003532{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003533 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003534
Chaehyun Lim27268872015-09-15 14:06:13 +09003535 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003536
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003537 priv = wdev_priv(net->ieee80211_ptr);
3538
Dean Lee72ed4dc2015-06-12 14:11:44 +09003539 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003540
Dean Lee72ed4dc2015-06-12 14:11:44 +09003541 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003542
3543 op_ifcs--;
3544
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003545 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003546
3547 /* Clear the Shadow scan */
3548 clear_shadow_scan(priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003549 if (op_ifcs == 0) {
3550 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003551 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003552 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003553
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003554 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003555 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003556
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003557 return s32Error;
3558}
3559
3560
3561/**
3562 * @brief WILC_WFI_WiphyFree
3563 * @details Freeing allocation of the wireless device structure
3564 * @param[in] NONE
3565 * @return NONE
3566 * @author mdaftedar
3567 * @date 01 MAR 2012
3568 * @version 1.0
3569 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003570void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003571{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003572 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3573
Chaehyun Lim619837a2015-09-20 15:51:10 +09003574 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003575 PRINT_D(INIT_DBG, "net_device is NULL\n");
3576 return;
3577 }
3578
Chaehyun Lim619837a2015-09-20 15:51:10 +09003579 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003580 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3581 return;
3582 }
3583
Chaehyun Lim619837a2015-09-20 15:51:10 +09003584 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003585 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3586 return;
3587 }
3588
3589 wiphy_unregister(net->ieee80211_ptr->wiphy);
3590
3591 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3592 wiphy_free(net->ieee80211_ptr->wiphy);
3593 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003594}