staging: wilc1000: add ops tx power in cfg80211
[linux-2.6-block.git] / drivers / staging / wilc1000 / wilc_wfi_cfgoperations.c
CommitLineData
c5c77ba1 1#include "wilc_wfi_cfgoperations.h"
491880eb 2#include "host_interface.h"
7ae43363 3#include <linux/errno.h>
c5c77ba1 4
15162fbc
AB
5#define NO_ENCRYPT 0
6#define ENCRYPT_ENABLED BIT(0)
7#define WEP BIT(1)
8#define WEP_EXTENDED BIT(2)
9#define WPA BIT(3)
10#define WPA2 BIT(4)
11#define AES BIT(5)
12#define TKIP BIT(6)
13
15162fbc
AB
14#define FRAME_TYPE_ID 0
15#define ACTION_CAT_ID 24
16#define ACTION_SUBTYPE_ID 25
17#define P2P_PUB_ACTION_SUBTYPE 30
18
15162fbc
AB
19#define ACTION_FRAME 0xd0
20#define GO_INTENT_ATTR_ID 0x04
21#define CHANLIST_ATTR_ID 0x0b
22#define OPERCHAN_ATTR_ID 0x11
23#define PUB_ACTION_ATTR_ID 0x04
24#define P2PELEM_ATTR_ID 0xdd
25
15162fbc
AB
26#define GO_NEG_REQ 0x00
27#define GO_NEG_RSP 0x01
28#define GO_NEG_CONF 0x02
29#define P2P_INV_REQ 0x03
30#define P2P_INV_RSP 0x04
31#define PUBLIC_ACT_VENDORSPEC 0x09
32#define GAS_INTIAL_REQ 0x0a
33#define GAS_INTIAL_RSP 0x0b
34
35#define INVALID_CHANNEL 0
36
37#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
38#define SCAN_RESULT_EXPIRE (40 * HZ)
39
40static const u32 cipher_suites[] = {
41 WLAN_CIPHER_SUITE_WEP40,
42 WLAN_CIPHER_SUITE_WEP104,
43 WLAN_CIPHER_SUITE_TKIP,
44 WLAN_CIPHER_SUITE_CCMP,
45 WLAN_CIPHER_SUITE_AES_CMAC,
46};
47
48static const struct ieee80211_txrx_stypes
49 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
50 [NL80211_IFTYPE_STATION] = {
51 .tx = 0xffff,
52 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
53 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
54 },
55 [NL80211_IFTYPE_AP] = {
56 .tx = 0xffff,
57 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
58 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
59 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
60 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
61 BIT(IEEE80211_STYPE_AUTH >> 4) |
62 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
63 BIT(IEEE80211_STYPE_ACTION >> 4)
64 },
65 [NL80211_IFTYPE_P2P_CLIENT] = {
66 .tx = 0xffff,
67 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
68 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
69 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
70 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
71 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
72 BIT(IEEE80211_STYPE_AUTH >> 4) |
73 BIT(IEEE80211_STYPE_DEAUTH >> 4)
74 }
75};
76
73584a40
GL
77static const struct wiphy_wowlan_support wowlan_support = {
78 .flags = WIPHY_WOWLAN_ANY
79};
80
15162fbc
AB
81#define WILC_WFI_DWELL_PASSIVE 100
82#define WILC_WFI_DWELL_ACTIVE 40
83
84#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
85#define DEFAULT_LINK_SPEED 72
86
87
c5c77ba1
JK
88#define IS_MANAGMEMENT 0x100
89#define IS_MANAGMEMENT_CALLBACK 0x080
90#define IS_MGMT_STATUS_SUCCES 0x040
91#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
92
0e1af73d
AB
93extern int wilc_mac_open(struct net_device *ndev);
94extern int wilc_mac_close(struct net_device *ndev);
c5c77ba1 95
f1ab117d 96static tstrNetworkInfo last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
771fbae4 97static u32 last_scanned_cnt;
0e1af73d 98struct timer_list wilc_during_ip_timer;
1608c403 99static struct timer_list hAgingTimer;
63d03e47 100static u8 op_ifcs;
c5c77ba1 101
0e1af73d 102u8 wilc_initialized = 1;
c5c77ba1
JK
103
104#define CHAN2G(_channel, _freq, _flags) { \
105 .band = IEEE80211_BAND_2GHZ, \
106 .center_freq = (_freq), \
107 .hw_value = (_channel), \
108 .flags = (_flags), \
109 .max_antenna_gain = 0, \
110 .max_power = 30, \
111}
112
2736f476 113static struct ieee80211_channel ieee80211_2ghz_channels[] = {
c5c77ba1
JK
114 CHAN2G(1, 2412, 0),
115 CHAN2G(2, 2417, 0),
116 CHAN2G(3, 2422, 0),
117 CHAN2G(4, 2427, 0),
118 CHAN2G(5, 2432, 0),
119 CHAN2G(6, 2437, 0),
120 CHAN2G(7, 2442, 0),
121 CHAN2G(8, 2447, 0),
122 CHAN2G(9, 2452, 0),
123 CHAN2G(10, 2457, 0),
124 CHAN2G(11, 2462, 0),
125 CHAN2G(12, 2467, 0),
126 CHAN2G(13, 2472, 0),
127 CHAN2G(14, 2484, 0),
128};
129
130#define RATETAB_ENT(_rate, _hw_value, _flags) { \
131 .bitrate = (_rate), \
132 .hw_value = (_hw_value), \
133 .flags = (_flags), \
134}
135
8d48b5ba 136static struct ieee80211_rate ieee80211_bitrates[] = {
c5c77ba1
JK
137 RATETAB_ENT(10, 0, 0),
138 RATETAB_ENT(20, 1, 0),
139 RATETAB_ENT(55, 2, 0),
140 RATETAB_ENT(110, 3, 0),
141 RATETAB_ENT(60, 9, 0),
142 RATETAB_ENT(90, 6, 0),
143 RATETAB_ENT(120, 7, 0),
144 RATETAB_ENT(180, 8, 0),
145 RATETAB_ENT(240, 9, 0),
146 RATETAB_ENT(360, 10, 0),
147 RATETAB_ENT(480, 11, 0),
148 RATETAB_ENT(540, 12, 0),
149};
150
c5c77ba1
JK
151struct p2p_mgmt_data {
152 int size;
153 u8 *buff;
154};
155
0bd8274f 156static u8 wlan_channel = INVALID_CHANNEL;
1608c403 157static u8 curr_channel;
881eb5d8 158static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
583d972c 159static u8 p2p_local_random = 0x01;
b84a3ac4 160static u8 p2p_recv_random = 0x00;
8668594a 161static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
a25d5186 162static bool wilc_ie;
c5c77ba1
JK
163
164static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
2736f476
LK
165 .channels = ieee80211_2ghz_channels,
166 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
8d48b5ba
LK
167 .bitrates = ieee80211_bitrates,
168 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
c5c77ba1
JK
169};
170
171
c5c77ba1
JK
172struct add_key_params {
173 u8 key_idx;
c5c77ba1 174 bool pairwise;
c5c77ba1
JK
175 u8 *mac_addr;
176};
1608c403
AB
177static struct add_key_params g_add_gtk_key_params;
178static struct wilc_wfi_key g_key_gtk_params;
179static struct add_key_params g_add_ptk_key_params;
180static struct wilc_wfi_key g_key_ptk_params;
181static struct wilc_wfi_wep_key g_key_wep_params;
182static bool g_ptk_keys_saved;
183static bool g_gtk_keys_saved;
184static bool g_wep_keys_saved;
c5c77ba1
JK
185
186#define AGING_TIME (9 * 1000)
7e872df9 187#define during_ip_time 15000
c5c77ba1 188
d14991af 189static void clear_shadow_scan(void)
c5c77ba1 190{
c5c77ba1 191 int i;
8dfaafd6 192
c5c77ba1 193 if (op_ifcs == 0) {
4183e979 194 del_timer_sync(&hAgingTimer);
c5c77ba1
JK
195 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
196
771fbae4 197 for (i = 0; i < last_scanned_cnt; i++) {
f1ab117d
LK
198 if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
199 kfree(last_scanned_shadow[i].pu8IEs);
200 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
c5c77ba1
JK
201 }
202
a5f9943c 203 kfree(last_scanned_shadow[i].pJoinParams);
f1ab117d 204 last_scanned_shadow[i].pJoinParams = NULL;
c5c77ba1 205 }
771fbae4 206 last_scanned_cnt = 0;
c5c77ba1 207 }
c5c77ba1
JK
208}
209
0b8bea1c 210static u32 get_rssi_avg(tstrNetworkInfo *network_info)
c5c77ba1 211{
51e825f7 212 u8 i;
c5c77ba1 213 int rssi_v = 0;
0b8bea1c 214 u8 num_rssi = (network_info->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index);
c5c77ba1
JK
215
216 for (i = 0; i < num_rssi; i++)
0b8bea1c 217 rssi_v += network_info->strRssi.as8RSSI[i];
c5c77ba1
JK
218
219 rssi_v /= num_rssi;
220 return rssi_v;
221}
222
48ee7bad 223static void refresh_scan(void *user_void, u8 all, bool direct_scan)
c5c77ba1 224{
2726887c 225 struct wilc_priv *priv;
c5c77ba1
JK
226 struct wiphy *wiphy;
227 struct cfg80211_bss *bss = NULL;
228 int i;
229 int rssi = 0;
230
84df0e6d 231 priv = (struct wilc_priv *)user_void;
c5c77ba1
JK
232 wiphy = priv->dev->ieee80211_ptr->wiphy;
233
771fbae4 234 for (i = 0; i < last_scanned_cnt; i++) {
ce3b1b5a 235 tstrNetworkInfo *network_info;
8dfaafd6 236
ce3b1b5a 237 network_info = &last_scanned_shadow[i];
c5c77ba1 238
ce3b1b5a 239 if (!network_info->u8Found || all) {
c6f5e3a6 240 s32 freq;
c5c77ba1
JK
241 struct ieee80211_channel *channel;
242
ce3b1b5a 243 if (network_info) {
c6f5e3a6
LK
244 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
245 channel = ieee80211_get_channel(wiphy, freq);
c5c77ba1 246
ce3b1b5a
LK
247 rssi = get_rssi_avg(network_info);
248 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
48ee7bad 249 direct_scan) {
ce3b1b5a
LK
250 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
251 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
252 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
c5c77ba1 253 cfg80211_put_bss(wiphy, bss);
c5c77ba1
JK
254 }
255 }
c5c77ba1
JK
256 }
257 }
c5c77ba1
JK
258}
259
12b0138b 260static void reset_shadow_found(void)
c5c77ba1 261{
c5c77ba1 262 int i;
8dfaafd6 263
771fbae4 264 for (i = 0; i < last_scanned_cnt; i++)
f1ab117d 265 last_scanned_shadow[i].u8Found = 0;
c5c77ba1
JK
266}
267
5e51d8ba 268static void update_scan_time(void)
c5c77ba1 269{
c5c77ba1 270 int i;
8dfaafd6 271
771fbae4 272 for (i = 0; i < last_scanned_cnt; i++)
f1ab117d 273 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
c5c77ba1
JK
274}
275
93dee8ee 276static void remove_network_from_shadow(unsigned long arg)
c5c77ba1 277{
c5c77ba1
JK
278 unsigned long now = jiffies;
279 int i, j;
280
c5c77ba1 281
771fbae4 282 for (i = 0; i < last_scanned_cnt; i++) {
f1ab117d
LK
283 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
284 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
c5c77ba1 285
f1ab117d
LK
286 kfree(last_scanned_shadow[i].pu8IEs);
287 last_scanned_shadow[i].pu8IEs = NULL;
c5c77ba1 288
a5f9943c 289 kfree(last_scanned_shadow[i].pJoinParams);
c5c77ba1 290
771fbae4 291 for (j = i; (j < last_scanned_cnt - 1); j++)
f1ab117d 292 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
771fbae4
LK
293
294 last_scanned_cnt--;
c5c77ba1
JK
295 }
296 }
297
771fbae4
LK
298 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
299 last_scanned_cnt);
300 if (last_scanned_cnt != 0) {
9eb06643
GKH
301 hAgingTimer.data = arg;
302 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
303 } else {
c5c77ba1 304 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
9eb06643 305 }
c5c77ba1
JK
306}
307
93dee8ee 308static void clear_duringIP(unsigned long arg)
c5c77ba1
JK
309{
310 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
0e1af73d 311 wilc_optaining_ip = false;
c5c77ba1 312}
c5c77ba1 313
157814f0
LK
314static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo,
315 void *user_void)
c5c77ba1 316{
a74cc6b8 317 int state = -1;
c5c77ba1
JK
318 int i;
319
771fbae4 320 if (last_scanned_cnt == 0) {
c5c77ba1 321 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
157814f0 322 hAgingTimer.data = (unsigned long)user_void;
9eb06643 323 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
c5c77ba1
JK
324 state = -1;
325 } else {
771fbae4 326 for (i = 0; i < last_scanned_cnt; i++) {
f1ab117d
LK
327 if (memcmp(last_scanned_shadow[i].au8bssid,
328 pstrNetworkInfo->au8bssid, 6) == 0) {
c5c77ba1
JK
329 state = i;
330 break;
331 }
332 }
333 }
334 return state;
335}
336
5c4cf0dd
LK
337static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo,
338 void *user_void, void *pJoinParams)
c5c77ba1 339{
5c4cf0dd 340 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
fbc2fe16 341 u32 ap_index = 0;
51e825f7 342 u8 rssi_index = 0;
c5c77ba1 343
771fbae4 344 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
c5c77ba1
JK
345 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
346 return;
347 }
348 if (ap_found == -1) {
771fbae4
LK
349 ap_index = last_scanned_cnt;
350 last_scanned_cnt++;
c5c77ba1
JK
351 } else {
352 ap_index = ap_found;
353 }
f1ab117d
LK
354 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
355 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
c5c77ba1
JK
356 if (rssi_index == NUM_RSSI) {
357 rssi_index = 0;
f1ab117d 358 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
c5c77ba1 359 }
f1ab117d
LK
360 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
361 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
362 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
363 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
364 memcpy(last_scanned_shadow[ap_index].au8ssid,
365 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
366 memcpy(last_scanned_shadow[ap_index].au8bssid,
367 pstrNetworkInfo->au8bssid, ETH_ALEN);
368 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
369 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
370 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
371 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
372 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
c5c77ba1 373 if (ap_found != -1)
f1ab117d
LK
374 kfree(last_scanned_shadow[ap_index].pu8IEs);
375 last_scanned_shadow[ap_index].pu8IEs =
a89f7c55 376 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);
f1ab117d
LK
377 memcpy(last_scanned_shadow[ap_index].pu8IEs,
378 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
379 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
380 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
381 last_scanned_shadow[ap_index].u8Found = 1;
c5c77ba1 382 if (ap_found != -1)
a5f9943c 383 kfree(last_scanned_shadow[ap_index].pJoinParams);
f1ab117d 384 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
c5c77ba1
JK
385}
386
1a4c8ce7 387static void CfgScanResult(enum scan_event scan_event,
0551a72e 388 tstrNetworkInfo *network_info,
30cd10c4 389 void *user_void,
bdd3460f 390 void *join_params)
c5c77ba1 391{
2726887c 392 struct wilc_priv *priv;
c5c77ba1 393 struct wiphy *wiphy;
fb4ec9ca 394 s32 s32Freq;
c5c77ba1 395 struct ieee80211_channel *channel;
c5c77ba1
JK
396 struct cfg80211_bss *bss = NULL;
397
30cd10c4 398 priv = (struct wilc_priv *)user_void;
7e4e87d3 399 if (priv->bCfgScanning) {
1a4c8ce7 400 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
c5c77ba1 401 wiphy = priv->dev->ieee80211_ptr->wiphy;
7ae43363
LK
402
403 if (!wiphy)
404 return;
405
0551a72e
LK
406 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
407 (((s32)network_info->s8rssi * 100) < 0 ||
408 ((s32)network_info->s8rssi * 100) > 100)) {
24db713f
LK
409 PRINT_ER("wiphy signal type fial\n");
410 return;
c5c77ba1
JK
411 }
412
0551a72e
LK
413 if (network_info) {
414 s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
c5c77ba1
JK
415 channel = ieee80211_get_channel(wiphy, s32Freq);
416
7ae43363
LK
417 if (!channel)
418 return;
c5c77ba1
JK
419
420 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
0551a72e
LK
421 "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
422 network_info->u16CapInfo, network_info->u16BeaconPeriod);
c5c77ba1 423
0551a72e 424 if (network_info->bNewNetwork) {
a89f7c55 425 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
0551a72e 426 PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
c5c77ba1
JK
427 priv->u32RcvdChCount++;
428
bdd3460f 429 if (!join_params)
c5c77ba1 430 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
bdd3460f 431 add_network_to_shadow(network_info, priv, join_params);
c5c77ba1 432
0551a72e
LK
433 if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
434 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
435 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
436 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
c5c77ba1 437 cfg80211_put_bss(wiphy, bss);
c5c77ba1
JK
438 }
439
440
441 } else {
442 PRINT_ER("Discovered networks exceeded the max limit\n");
443 }
444 } else {
4e4467fd 445 u32 i;
a89f7c55 446
c5c77ba1 447 for (i = 0; i < priv->u32RcvdChCount; i++) {
0551a72e 448 if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
f1ab117d 449 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
c5c77ba1 450
0551a72e 451 last_scanned_shadow[i].s8rssi = network_info->s8rssi;
f1ab117d 452 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
c5c77ba1
JK
453 break;
454 }
455 }
456 }
457 }
1a4c8ce7 458 } else if (scan_event == SCAN_EVENT_DONE) {
17aacd43
CG
459 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
460 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
72ed4dc7 461 refresh_scan(priv, 1, false);
c5c77ba1 462
78174ada 463 if (priv->u32RcvdChCount > 0)
17aacd43 464 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
78174ada 465 else
17aacd43 466 PRINT_D(CFG80211_DBG, "No networks found\n");
c5c77ba1 467
83383ea3 468 down(&(priv->hSemScanReq));
c5c77ba1 469
369a1d3b 470 if (priv->pstrScanReq) {
72ed4dc7 471 cfg80211_scan_done(priv->pstrScanReq, false);
c5c77ba1 472 priv->u32RcvdChCount = 0;
72ed4dc7 473 priv->bCfgScanning = false;
b1413b60 474 priv->pstrScanReq = NULL;
c5c77ba1 475 }
83383ea3 476 up(&(priv->hSemScanReq));
1a4c8ce7 477 } else if (scan_event == SCAN_EVENT_ABORTED) {
83383ea3 478 down(&(priv->hSemScanReq));
c5c77ba1 479
17aacd43 480 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
369a1d3b 481 if (priv->pstrScanReq) {
5e51d8ba 482 update_scan_time();
72ed4dc7 483 refresh_scan(priv, 1, false);
c5c77ba1 484
72ed4dc7
DL
485 cfg80211_scan_done(priv->pstrScanReq, false);
486 priv->bCfgScanning = false;
b1413b60 487 priv->pstrScanReq = NULL;
c5c77ba1 488 }
83383ea3 489 up(&(priv->hSemScanReq));
c5c77ba1
JK
490 }
491 }
c5c77ba1
JK
492}
493
0e1af73d 494int wilc_connecting;
c5c77ba1 495
ed3f0379 496static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
c5c77ba1 497 tstrConnectInfo *pstrConnectInfo,
63d03e47 498 u8 u8MacStatus,
c5c77ba1
JK
499 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
500 void *pUserVoid)
501{
2726887c 502 struct wilc_priv *priv;
c5c77ba1 503 struct net_device *dev;
441dc609 504 struct host_if_drv *pstrWFIDrv;
63d03e47 505 u8 NullBssid[ETH_ALEN] = {0};
c1ec2c12 506 struct wilc *wl;
a4cac481 507 struct wilc_vif *vif;
8dfaafd6 508
0e1af73d 509 wilc_connecting = 0;
c5c77ba1 510
2726887c 511 priv = (struct wilc_priv *)pUserVoid;
c5c77ba1 512 dev = priv->dev;
a4cac481
GL
513 vif = netdev_priv(dev);
514 wl = vif->wilc;
441dc609 515 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1
JK
516
517 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
baba7c74 518 u16 u16ConnectStatus;
c5c77ba1
JK
519
520 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
521
522 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
523
524 if ((u8MacStatus == MAC_DISCONNECTED) &&
525 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
c5c77ba1 526 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
ba615f1e
GL
527 wilc_wlan_set_bssid(priv->dev, NullBssid,
528 STATION_MODE);
e554a305 529 eth_zero_addr(wilc_connected_ssid);
c5c77ba1 530
ab16ec0b 531 if (!pstrWFIDrv->p2p_connect)
0bd8274f 532 wlan_channel = INVALID_CHANNEL;
c5c77ba1 533
17aacd43 534 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
c5c77ba1
JK
535 }
536
537 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
72ed4dc7 538 bool bNeedScanRefresh = false;
4e4467fd 539 u32 i;
c5c77ba1
JK
540
541 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
542 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
d00d2ba3 543 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
c5c77ba1 544
c5c77ba1 545
771fbae4 546 for (i = 0; i < last_scanned_cnt; i++) {
f1ab117d
LK
547 if (memcmp(last_scanned_shadow[i].au8bssid,
548 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
c5c77ba1
JK
549 unsigned long now = jiffies;
550
551 if (time_after(now,
f1ab117d 552 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
72ed4dc7 553 bNeedScanRefresh = true;
c5c77ba1
JK
554 }
555
556 break;
557 }
558 }
559
a89f7c55 560 if (bNeedScanRefresh)
72ed4dc7 561 refresh_scan(priv, 1, true);
c5c77ba1
JK
562 }
563
564
52db7520 565 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
c5c77ba1
JK
566
567 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
568
569 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
570 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
571 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
a89f7c55 572 u16ConnectStatus, GFP_KERNEL);
c5c77ba1 573 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
0e1af73d 574 wilc_optaining_ip = false;
c5c77ba1
JK
575 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
576 pstrDisconnectNotifInfo->u16reason, priv->dev);
583d972c 577 p2p_local_random = 0x01;
b84a3ac4 578 p2p_recv_random = 0x00;
a25d5186 579 wilc_ie = false;
bcf02653 580 eth_zero_addr(priv->au8AssociatedBss);
ba615f1e 581 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
e554a305 582 eth_zero_addr(wilc_connected_ssid);
c5c77ba1 583
ab16ec0b 584 if (!pstrWFIDrv->p2p_connect)
0bd8274f 585 wlan_channel = INVALID_CHANNEL;
1f435d2e 586 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
c5c77ba1 587 pstrDisconnectNotifInfo->u16reason = 3;
1f435d2e 588 } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
c5c77ba1
JK
589 pstrDisconnectNotifInfo->u16reason = 1;
590 }
591 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
e26bb71d
SM
592 pstrDisconnectNotifInfo->ie_len, false,
593 GFP_KERNEL);
c5c77ba1 594 }
c5c77ba1
JK
595}
596
80785a9a
CL
597static int set_channel(struct wiphy *wiphy,
598 struct cfg80211_chan_def *chandef)
c5c77ba1 599{
4e4467fd 600 u32 channelnum = 0;
2726887c 601 struct wilc_priv *priv;
dd739ea5 602 int result = 0;
cf60106b 603 struct wilc_vif *vif;
8dfaafd6 604
c5c77ba1 605 priv = wiphy_priv(wiphy);
cf60106b 606 vif = netdev_priv(priv->dev);
c5c77ba1 607
c5c77ba1
JK
608 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
609 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
c5c77ba1 610
866a2c24 611 curr_channel = channelnum;
fbf5379b 612 result = wilc_set_mac_chnl_num(vif, channelnum);
c5c77ba1 613
dd739ea5 614 if (result != 0)
c5c77ba1
JK
615 PRINT_ER("Error in setting channel %d\n", channelnum);
616
dd739ea5 617 return result;
c5c77ba1
JK
618}
619
0e30d06d 620static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
c5c77ba1 621{
2726887c 622 struct wilc_priv *priv;
4e4467fd 623 u32 i;
e6e12661 624 s32 s32Error = 0;
63d03e47 625 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
607db447 626 struct hidden_network strHiddenNetwork;
cf60106b 627 struct wilc_vif *vif;
c5c77ba1
JK
628
629 priv = wiphy_priv(wiphy);
cf60106b 630 vif = netdev_priv(priv->dev);
c5c77ba1 631
c5c77ba1
JK
632 priv->pstrScanReq = request;
633
634 priv->u32RcvdChCount = 0;
635
12b0138b 636 reset_shadow_found();
c5c77ba1 637
72ed4dc7 638 priv->bCfgScanning = true;
a89f7c55 639 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
c5c77ba1 640 for (i = 0; i < request->n_channels; i++) {
63d03e47 641 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
c5c77ba1
JK
642 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
643 }
644
645 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
52db7520 646 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
c5c77ba1
JK
647
648 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
649
650 if (request->n_ssids >= 1) {
245a1865 651 strHiddenNetwork.net_info = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
40e05e86 652 strHiddenNetwork.n_ssids = request->n_ssids;
c5c77ba1
JK
653
654
c5c77ba1 655 for (i = 0; i < request->n_ssids; i++) {
369a1d3b
LK
656 if (request->ssids[i].ssid &&
657 request->ssids[i].ssid_len != 0) {
245a1865
CL
658 strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
659 memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
660 strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
c5c77ba1 661 } else {
17aacd43 662 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
40e05e86 663 strHiddenNetwork.n_ssids -= 1;
c5c77ba1
JK
664 }
665 }
17aacd43 666 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
fbf5379b
GL
667 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
668 au8ScanChanList,
669 request->n_channels,
670 (const u8 *)request->ie,
671 request->ie_len, CfgScanResult,
672 (void *)priv, &strHiddenNetwork);
c5c77ba1 673 } else {
17aacd43 674 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
fbf5379b
GL
675 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
676 au8ScanChanList,
677 request->n_channels,
678 (const u8 *)request->ie,
679 request->ie_len, CfgScanResult,
680 (void *)priv, NULL);
c5c77ba1 681 }
c5c77ba1
JK
682 } else {
683 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
17aacd43 684 " channels\n");
c5c77ba1
JK
685 }
686
e6e12661 687 if (s32Error != 0) {
c5c77ba1
JK
688 s32Error = -EBUSY;
689 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
690 }
691
692 return s32Error;
693}
694
4ffbcdb6
CL
695static int connect(struct wiphy *wiphy, struct net_device *dev,
696 struct cfg80211_connect_params *sme)
c5c77ba1 697{
e6e12661 698 s32 s32Error = 0;
4e4467fd 699 u32 i;
63d03e47 700 u8 u8security = NO_ENCRYPT;
841dfc42 701 enum AUTHTYPE tenuAuth_type = ANY;
576917ad
DL
702 char *pcgroup_encrypt_val = NULL;
703 char *pccipher_group = NULL;
704 char *pcwpa_version = NULL;
c5c77ba1 705
2726887c 706 struct wilc_priv *priv;
441dc609 707 struct host_if_drv *pstrWFIDrv;
c5c77ba1 708 tstrNetworkInfo *pstrNetworkInfo = NULL;
cf60106b 709 struct wilc_vif *vif;
c5c77ba1 710
0e1af73d 711 wilc_connecting = 1;
c5c77ba1 712 priv = wiphy_priv(wiphy);
cf60106b 713 vif = netdev_priv(priv->dev);
441dc609 714 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
c5c77ba1 715
8a14330f 716 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
3f882895 717 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
c5c77ba1 718 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
ab16ec0b
LK
719 pstrWFIDrv->p2p_connect = 1;
720 } else {
721 pstrWFIDrv->p2p_connect = 0;
722 }
17aacd43 723 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
c5c77ba1 724
771fbae4 725 for (i = 0; i < last_scanned_cnt; i++) {
f1ab117d
LK
726 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
727 memcmp(last_scanned_shadow[i].au8ssid,
728 sme->ssid,
729 sme->ssid_len) == 0) {
c5c77ba1 730 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
369a1d3b 731 if (!sme->bssid) {
c5c77ba1
JK
732 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
733 break;
734 } else {
f1ab117d
LK
735 if (memcmp(last_scanned_shadow[i].au8bssid,
736 sme->bssid,
737 ETH_ALEN) == 0) {
c5c77ba1
JK
738 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
739 break;
740 }
741 }
742 }
743 }
744
771fbae4 745 if (i < last_scanned_cnt) {
c5c77ba1
JK
746 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
747
f1ab117d 748 pstrNetworkInfo = &last_scanned_shadow[i];
c5c77ba1
JK
749
750 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
751 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
752 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
753 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
754 } else {
755 s32Error = -ENOENT;
771fbae4 756 if (last_scanned_cnt == 0)
c5c77ba1
JK
757 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
758 else
759 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
430e640d
GL
760 wilc_connecting = 0;
761 return s32Error;
c5c77ba1
JK
762 }
763
764 priv->WILC_WFI_wep_default = 0;
2cc46837
CL
765 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
766 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
c5c77ba1
JK
767
768 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
769 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
770
771 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
772
773 if (INFO) {
774 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
775 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
776 }
777
778 if (sme->crypto.cipher_group != NO_ENCRYPT) {
c5c77ba1
JK
779 pcwpa_version = "Default";
780 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
c5c77ba1 781 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
c5c77ba1
JK
782 u8security = ENCRYPT_ENABLED | WEP;
783 pcgroup_encrypt_val = "WEP40";
784 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
785 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
786
787 if (INFO) {
788 for (i = 0; i < sme->key_len; i++)
789 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
790 }
791 priv->WILC_WFI_wep_default = sme->key_idx;
792 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
d00d2ba3 793 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
c5c77ba1 794
c5c77ba1 795 g_key_wep_params.key_len = sme->key_len;
f3052587 796 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
c5c77ba1
JK
797 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
798 g_key_wep_params.key_idx = sme->key_idx;
72ed4dc7 799 g_wep_keys_saved = true;
c5c77ba1 800
fbf5379b
GL
801 wilc_set_wep_default_keyid(vif, sme->key_idx);
802 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
803 sme->key_idx);
c5c77ba1 804 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
c5c77ba1
JK
805 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
806 pcgroup_encrypt_val = "WEP104";
807 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
808
809 priv->WILC_WFI_wep_default = sme->key_idx;
810 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
d00d2ba3 811 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
c5c77ba1 812
c5c77ba1 813 g_key_wep_params.key_len = sme->key_len;
f3052587 814 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
c5c77ba1
JK
815 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
816 g_key_wep_params.key_idx = sme->key_idx;
72ed4dc7 817 g_wep_keys_saved = true;
c5c77ba1 818
fbf5379b
GL
819 wilc_set_wep_default_keyid(vif, sme->key_idx);
820 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
821 sme->key_idx);
c5c77ba1 822 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
c5c77ba1 823 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
824 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
825 pcgroup_encrypt_val = "WPA2_TKIP";
826 pccipher_group = "TKIP";
a89f7c55 827 } else {
c5c77ba1
JK
828 u8security = ENCRYPT_ENABLED | WPA2 | AES;
829 pcgroup_encrypt_val = "WPA2_AES";
830 pccipher_group = "AES";
831 }
832 pcwpa_version = "WPA_VERSION_2";
833 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
834 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
835 u8security = ENCRYPT_ENABLED | WPA | TKIP;
836 pcgroup_encrypt_val = "WPA_TKIP";
837 pccipher_group = "TKIP";
a89f7c55 838 } else {
c5c77ba1
JK
839 u8security = ENCRYPT_ENABLED | WPA | AES;
840 pcgroup_encrypt_val = "WPA_AES";
841 pccipher_group = "AES";
c5c77ba1
JK
842 }
843 pcwpa_version = "WPA_VERSION_1";
844
c5c77ba1
JK
845 } else {
846 s32Error = -ENOTSUPP;
847 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
430e640d
GL
848 wilc_connecting = 0;
849 return s32Error;
c5c77ba1 850 }
c5c77ba1
JK
851 }
852
c5c77ba1
JK
853 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
854 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
855 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
856 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
857 u8security = u8security | TKIP;
a89f7c55 858 } else {
c5c77ba1
JK
859 u8security = u8security | AES;
860 }
861 }
862 }
863
864 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
865
866 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
867 switch (sme->auth_type) {
868 case NL80211_AUTHTYPE_OPEN_SYSTEM:
869 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
870 tenuAuth_type = OPEN_SYSTEM;
871 break;
872
873 case NL80211_AUTHTYPE_SHARED_KEY:
874 tenuAuth_type = SHARED_KEY;
875 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
876 break;
877
878 default:
879 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
880 }
881
c5c77ba1
JK
882 if (sme->crypto.n_akm_suites) {
883 switch (sme->crypto.akm_suites[0]) {
884 case WLAN_AKM_SUITE_8021X:
885 tenuAuth_type = IEEE8021;
886 break;
887
888 default:
889 break;
890 }
891 }
892
893
894 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
895
896 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
897 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
898
866a2c24 899 curr_channel = pstrNetworkInfo->u8channel;
c5c77ba1 900
ab16ec0b 901 if (!pstrWFIDrv->p2p_connect)
0bd8274f 902 wlan_channel = pstrNetworkInfo->u8channel;
c5c77ba1 903
ba615f1e 904 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid, STATION_MODE);
c5c77ba1 905
fbf5379b
GL
906 s32Error = wilc_set_join_req(vif, pstrNetworkInfo->au8bssid, sme->ssid,
907 sme->ssid_len, sme->ie, sme->ie_len,
908 CfgConnectResult, (void *)priv,
909 u8security, tenuAuth_type,
910 pstrNetworkInfo->u8channel,
911 pstrNetworkInfo->pJoinParams);
e6e12661 912 if (s32Error != 0) {
0e1af73d 913 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
c5c77ba1 914 s32Error = -ENOENT;
430e640d
GL
915 wilc_connecting = 0;
916 return s32Error;
c5c77ba1
JK
917 }
918
c5c77ba1
JK
919 return s32Error;
920}
921
b027cde9 922static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
c5c77ba1 923{
e6e12661 924 s32 s32Error = 0;
2726887c 925 struct wilc_priv *priv;
441dc609 926 struct host_if_drv *pstrWFIDrv;
cf60106b 927 struct wilc_vif *vif;
51e825f7 928 u8 NullBssid[ETH_ALEN] = {0};
8dfaafd6 929
0e1af73d 930 wilc_connecting = 0;
c5c77ba1 931 priv = wiphy_priv(wiphy);
cf60106b 932 vif = netdev_priv(priv->dev);
c5c77ba1 933
441dc609 934 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
ab16ec0b 935 if (!pstrWFIDrv->p2p_connect)
0bd8274f 936 wlan_channel = INVALID_CHANNEL;
ba615f1e 937 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
c5c77ba1
JK
938
939 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
940
583d972c 941 p2p_local_random = 0x01;
b84a3ac4 942 p2p_recv_random = 0x00;
a25d5186 943 wilc_ie = false;
1229b1ab 944 pstrWFIDrv->p2p_timeout = 0;
c5c77ba1 945
fbf5379b 946 s32Error = wilc_disconnect(vif, reason_code);
e6e12661 947 if (s32Error != 0) {
c5c77ba1
JK
948 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
949 s32Error = -EINVAL;
950 }
951
952 return s32Error;
953}
954
953d417a
CL
955static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
956 bool pairwise,
957 const u8 *mac_addr, struct key_params *params)
c5c77ba1
JK
958
959{
e6e12661 960 s32 s32Error = 0, KeyLen = params->key_len;
4e4467fd 961 u32 i;
2726887c 962 struct wilc_priv *priv;
057d1e97
AB
963 const u8 *pu8RxMic = NULL;
964 const u8 *pu8TxMic = NULL;
63d03e47 965 u8 u8mode = NO_ENCRYPT;
63d03e47
GKH
966 u8 u8gmode = NO_ENCRYPT;
967 u8 u8pmode = NO_ENCRYPT;
841dfc42 968 enum AUTHTYPE tenuAuth_type = ANY;
76469200 969 struct wilc *wl;
a4cac481 970 struct wilc_vif *vif;
c5c77ba1
JK
971
972 priv = wiphy_priv(wiphy);
a4cac481
GL
973 vif = netdev_priv(netdev);
974 wl = vif->wilc;
c5c77ba1
JK
975
976 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
977
8a14330f 978 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
c5c77ba1
JK
979
980 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
981 params->key[1],
982 params->key[2]);
983
984
985 switch (params->cipher) {
986 case WLAN_CIPHER_SUITE_WEP40:
987 case WLAN_CIPHER_SUITE_WEP104:
c5c77ba1 988 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
c5c77ba1
JK
989 priv->WILC_WFI_wep_default = key_index;
990 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
d00d2ba3 991 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
c5c77ba1
JK
992
993 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
994 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
995
996 for (i = 0; i < params->key_len; i++)
997 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
998
999 tenuAuth_type = OPEN_SYSTEM;
1000
1001 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1002 u8mode = ENCRYPT_ENABLED | WEP;
1003 else
1004 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1005
fbf5379b
GL
1006 wilc_add_wep_key_bss_ap(vif, params->key,
1007 params->key_len, key_index,
1008 u8mode, tenuAuth_type);
c5c77ba1
JK
1009 break;
1010 }
1a646e7e 1011 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
c5c77ba1
JK
1012 priv->WILC_WFI_wep_default = key_index;
1013 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
d00d2ba3 1014 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
c5c77ba1
JK
1015
1016 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1017 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1018 if (INFO) {
1019 for (i = 0; i < params->key_len; i++)
1020 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1021 }
fbf5379b
GL
1022 wilc_add_wep_key_bss_sta(vif, params->key,
1023 params->key_len, key_index);
c5c77ba1
JK
1024 }
1025
1026 break;
1027
1028 case WLAN_CIPHER_SUITE_TKIP:
1029 case WLAN_CIPHER_SUITE_CCMP:
c5c77ba1 1030 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
369a1d3b 1031 if (!priv->wilc_gtk[key_index]) {
f3052587 1032 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
b1413b60
GKH
1033 priv->wilc_gtk[key_index]->key = NULL;
1034 priv->wilc_gtk[key_index]->seq = NULL;
c5c77ba1 1035 }
369a1d3b 1036 if (!priv->wilc_ptk[key_index]) {
f3052587 1037 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
b1413b60
GKH
1038 priv->wilc_ptk[key_index]->key = NULL;
1039 priv->wilc_ptk[key_index]->seq = NULL;
c5c77ba1
JK
1040 }
1041
1042
1043
1913221c 1044 if (!pairwise) {
c5c77ba1
JK
1045 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1046 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1047 else
1048 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1049
1050 priv->wilc_groupkey = u8gmode;
1051
1052 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
1053 pu8TxMic = params->key + 24;
1054 pu8RxMic = params->key + 16;
1055 KeyLen = params->key_len - 16;
1056 }
cccfc39e 1057 kfree(priv->wilc_gtk[key_index]->key);
c5c77ba1 1058
f3052587 1059 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
d00d2ba3 1060 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
cccfc39e 1061 kfree(priv->wilc_gtk[key_index]->seq);
c5c77ba1
JK
1062
1063 if ((params->seq_len) > 0) {
f3052587 1064 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
d00d2ba3 1065 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
c5c77ba1
JK
1066 }
1067
1068 priv->wilc_gtk[key_index]->cipher = params->cipher;
1069 priv->wilc_gtk[key_index]->key_len = params->key_len;
1070 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1071
1072 if (INFO) {
1073 for (i = 0; i < params->key_len; i++)
1074 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1075 for (i = 0; i < params->seq_len; i++)
1076 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1077 }
1078
1079
fbf5379b
GL
1080 wilc_add_rx_gtk(vif, params->key, KeyLen,
1081 key_index, params->seq_len,
1082 params->seq, pu8RxMic,
1083 pu8TxMic, AP_MODE, u8gmode);
c5c77ba1
JK
1084
1085 } else {
1086 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]);
1087
1088 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1089 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1090 else
1091 u8pmode = priv->wilc_groupkey | AES;
1092
1093
1094 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
1095 pu8TxMic = params->key + 24;
1096 pu8RxMic = params->key + 16;
1097 KeyLen = params->key_len - 16;
1098 }
1099
cccfc39e 1100 kfree(priv->wilc_ptk[key_index]->key);
c5c77ba1 1101
f3052587 1102 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
c5c77ba1 1103
cccfc39e 1104 kfree(priv->wilc_ptk[key_index]->seq);
c5c77ba1
JK
1105
1106 if ((params->seq_len) > 0)
f3052587 1107 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba1
JK
1108
1109 if (INFO) {
1110 for (i = 0; i < params->key_len; i++)
1111 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1112
1113 for (i = 0; i < params->seq_len; i++)
1114 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1115 }
1116
d00d2ba3 1117 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
c5c77ba1
JK
1118
1119 if ((params->seq_len) > 0)
d00d2ba3 1120 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
c5c77ba1
JK
1121
1122 priv->wilc_ptk[key_index]->cipher = params->cipher;
1123 priv->wilc_ptk[key_index]->key_len = params->key_len;
1124 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1125
fbf5379b
GL
1126 wilc_add_ptk(vif, params->key, KeyLen,
1127 mac_addr, pu8RxMic, pu8TxMic,
1128 AP_MODE, u8pmode, key_index);
c5c77ba1
JK
1129 }
1130 break;
1131 }
c5c77ba1
JK
1132
1133 {
1134 u8mode = 0;
1913221c 1135 if (!pairwise) {
c5c77ba1 1136 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
1137 pu8RxMic = params->key + 24;
1138 pu8TxMic = params->key + 16;
1139 KeyLen = params->key_len - 16;
1140 }
1141
1f435d2e 1142 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
c5c77ba1 1143 g_add_gtk_key_params.key_idx = key_index;
c5c77ba1 1144 g_add_gtk_key_params.pairwise = pairwise;
c5c77ba1
JK
1145 if (!mac_addr) {
1146 g_add_gtk_key_params.mac_addr = NULL;
1147 } else {
f3052587 1148 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
c5c77ba1
JK
1149 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1150 }
1151 g_key_gtk_params.key_len = params->key_len;
1152 g_key_gtk_params.seq_len = params->seq_len;
f3052587 1153 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
c5c77ba1
JK
1154 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1155 if (params->seq_len > 0) {
f3052587 1156 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba1
JK
1157 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1158 }
1159 g_key_gtk_params.cipher = params->cipher;
1160
1161 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1162 g_key_gtk_params.key[1],
1163 g_key_gtk_params.key[2]);
72ed4dc7 1164 g_gtk_keys_saved = true;
c5c77ba1
JK
1165 }
1166
fbf5379b
GL
1167 wilc_add_rx_gtk(vif, params->key, KeyLen,
1168 key_index, params->seq_len,
1169 params->seq, pu8RxMic,
1170 pu8TxMic, STATION_MODE,
1171 u8mode);
c5c77ba1
JK
1172 } else {
1173 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
1174 pu8RxMic = params->key + 24;
1175 pu8TxMic = params->key + 16;
1176 KeyLen = params->key_len - 16;
1177 }
1178
1f435d2e 1179 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
c5c77ba1 1180 g_add_ptk_key_params.key_idx = key_index;
c5c77ba1 1181 g_add_ptk_key_params.pairwise = pairwise;
c5c77ba1
JK
1182 if (!mac_addr) {
1183 g_add_ptk_key_params.mac_addr = NULL;
1184 } else {
f3052587 1185 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
c5c77ba1
JK
1186 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1187 }
1188 g_key_ptk_params.key_len = params->key_len;
1189 g_key_ptk_params.seq_len = params->seq_len;
f3052587 1190 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
c5c77ba1
JK
1191 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1192 if (params->seq_len > 0) {
f3052587 1193 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba1
JK
1194 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1195 }
1196 g_key_ptk_params.cipher = params->cipher;
1197
1198 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1199 g_key_ptk_params.key[1],
1200 g_key_ptk_params.key[2]);
72ed4dc7 1201 g_ptk_keys_saved = true;
c5c77ba1
JK
1202 }
1203
fbf5379b
GL
1204 wilc_add_ptk(vif, params->key, KeyLen,
1205 mac_addr, pu8RxMic, pu8TxMic,
1206 STATION_MODE, u8mode, key_index);
c5c77ba1
JK
1207 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1208 if (INFO) {
1209 for (i = 0; i < params->key_len; i++)
1210 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1211 }
1212 }
1213 }
1214 break;
1215
1216 default:
1217 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1218 s32Error = -ENOTSUPP;
c5c77ba1
JK
1219 }
1220
1221 return s32Error;
1222}
1223
3044ba7e
CL
1224static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1225 u8 key_index,
1226 bool pairwise,
1227 const u8 *mac_addr)
c5c77ba1 1228{
2726887c 1229 struct wilc_priv *priv;
692e2ace 1230 struct wilc *wl;
a4cac481 1231 struct wilc_vif *vif;
c5c77ba1
JK
1232
1233 priv = wiphy_priv(wiphy);
a4cac481
GL
1234 vif = netdev_priv(netdev);
1235 wl = vif->wilc;
c5c77ba1 1236
1f435d2e 1237 if (netdev == wl->vif[0]->ndev) {
72ed4dc7
DL
1238 g_ptk_keys_saved = false;
1239 g_gtk_keys_saved = false;
1240 g_wep_keys_saved = false;
c5c77ba1 1241
cccfc39e
SB
1242 kfree(g_key_wep_params.key);
1243 g_key_wep_params.key = NULL;
c5c77ba1 1244
c5c77ba1 1245 if ((priv->wilc_gtk[key_index]) != NULL) {
cccfc39e
SB
1246 kfree(priv->wilc_gtk[key_index]->key);
1247 priv->wilc_gtk[key_index]->key = NULL;
1248 kfree(priv->wilc_gtk[key_index]->seq);
1249 priv->wilc_gtk[key_index]->seq = NULL;
c5c77ba1 1250
49188af2 1251 kfree(priv->wilc_gtk[key_index]);
c5c77ba1 1252 priv->wilc_gtk[key_index] = NULL;
c5c77ba1
JK
1253 }
1254
1255 if ((priv->wilc_ptk[key_index]) != NULL) {
cccfc39e
SB
1256 kfree(priv->wilc_ptk[key_index]->key);
1257 priv->wilc_ptk[key_index]->key = NULL;
1258 kfree(priv->wilc_ptk[key_index]->seq);
1259 priv->wilc_ptk[key_index]->seq = NULL;
49188af2 1260 kfree(priv->wilc_ptk[key_index]);
c5c77ba1
JK
1261 priv->wilc_ptk[key_index] = NULL;
1262 }
c5c77ba1 1263
cccfc39e
SB
1264 kfree(g_key_ptk_params.key);
1265 g_key_ptk_params.key = NULL;
1266 kfree(g_key_ptk_params.seq);
1267 g_key_ptk_params.seq = NULL;
1268
1269 kfree(g_key_gtk_params.key);
1270 g_key_gtk_params.key = NULL;
1271 kfree(g_key_gtk_params.seq);
1272 g_key_gtk_params.seq = NULL;
c5c77ba1 1273
c5c77ba1
JK
1274 }
1275
1276 if (key_index >= 0 && key_index <= 3) {
2cc46837 1277 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
c5c77ba1
JK
1278 priv->WILC_WFI_wep_key_len[key_index] = 0;
1279
1280 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
fbf5379b 1281 wilc_remove_wep_key(vif, key_index);
c5c77ba1
JK
1282 } else {
1283 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
0e1af73d 1284 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
c5c77ba1
JK
1285 }
1286
aaed3290 1287 return 0;
c5c77ba1
JK
1288}
1289
f4893dfc
CL
1290static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1291 bool pairwise,
1292 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
c5c77ba1 1293{
2726887c 1294 struct wilc_priv *priv;
c5c77ba1 1295 struct key_params key_params;
4e4467fd 1296 u32 i;
8dfaafd6 1297
c5c77ba1
JK
1298 priv = wiphy_priv(wiphy);
1299
1300
3604af50 1301 if (!pairwise) {
c5c77ba1
JK
1302 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1303
1304 key_params.key = priv->wilc_gtk[key_index]->key;
1305 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1306 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1307 key_params.seq = priv->wilc_gtk[key_index]->seq;
1308 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1309 if (INFO) {
1310 for (i = 0; i < key_params.key_len; i++)
1311 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1312 }
1313 } else {
1314 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1315
1316 key_params.key = priv->wilc_ptk[key_index]->key;
1317 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1318 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1319 key_params.seq = priv->wilc_ptk[key_index]->seq;
1320 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1321 }
1322
1323 callback(cookie, &key_params);
1324
a89f7c55 1325 return 0;
c5c77ba1
JK
1326}
1327
0f5b8ca3
CL
1328static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1329 bool unicast, bool multicast)
c5c77ba1 1330{
2726887c 1331 struct wilc_priv *priv;
cf60106b 1332 struct wilc_vif *vif;
c5c77ba1
JK
1333
1334 priv = wiphy_priv(wiphy);
cf60106b 1335 vif = netdev_priv(priv->dev);
c5c77ba1 1336
17aacd43 1337 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
c5c77ba1
JK
1338
1339 if (key_index != priv->WILC_WFI_wep_default) {
fbf5379b 1340 wilc_set_wep_default_keyid(vif, key_index);
c5c77ba1
JK
1341 }
1342
aaed3290 1343 return 0;
c5c77ba1
JK
1344}
1345
f06f562d
CL
1346static int get_station(struct wiphy *wiphy, struct net_device *dev,
1347 const u8 *mac, struct station_info *sinfo)
c5c77ba1 1348{
2726887c 1349 struct wilc_priv *priv;
a4cac481 1350 struct wilc_vif *vif;
4e4467fd
CL
1351 u32 i = 0;
1352 u32 associatedsta = 0;
1353 u32 inactive_time = 0;
c5c77ba1 1354 priv = wiphy_priv(wiphy);
a4cac481 1355 vif = netdev_priv(dev);
c5c77ba1 1356
a4cac481 1357 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
c5c77ba1
JK
1358 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1359
1360 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1361
1362 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
c5c77ba1
JK
1363 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1364 associatedsta = i;
1365 break;
1366 }
c5c77ba1
JK
1367 }
1368
1369 if (associatedsta == -1) {
aaed3290
LK
1370 PRINT_ER("Station required is not associated\n");
1371 return -ENOENT;
c5c77ba1
JK
1372 }
1373
c5c77ba1 1374 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
c5c77ba1 1375
fbf5379b 1376 wilc_get_inactive_time(vif, mac, &inactive_time);
c5c77ba1
JK
1377 sinfo->inactive_time = 1000 * inactive_time;
1378 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
c5c77ba1 1379 }
c5c77ba1 1380
a4cac481 1381 if (vif->iftype == STATION_MODE) {
03e7b9c4 1382 struct rf_info strStatistics;
8dfaafd6 1383
fbf5379b 1384 wilc_get_statistics(vif, &strStatistics);
c5c77ba1 1385
c5c77ba1 1386 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
6212990a 1387 BIT(NL80211_STA_INFO_RX_PACKETS) |
c5c77ba1
JK
1388 BIT(NL80211_STA_INFO_TX_PACKETS) |
1389 BIT(NL80211_STA_INFO_TX_FAILED) |
1390 BIT(NL80211_STA_INFO_TX_BITRATE);
c5c77ba1 1391
00c8dfcf 1392 sinfo->signal = strStatistics.rssi;
9b99274a 1393 sinfo->rx_packets = strStatistics.rx_cnt;
54160376
LK
1394 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1395 sinfo->tx_failed = strStatistics.tx_fail_cnt;
5babeecb 1396 sinfo->txrate.legacy = strStatistics.link_speed * 10;
c5c77ba1 1397
5babeecb
LK
1398 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1399 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
0e1af73d 1400 wilc_enable_tcp_ack_filter(true);
5babeecb 1401 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
0e1af73d 1402 wilc_enable_tcp_ack_filter(false);
c5c77ba1 1403
c5c77ba1
JK
1404 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1405 sinfo->tx_failed, sinfo->txrate.legacy);
c5c77ba1 1406 }
aaed3290 1407 return 0;
c5c77ba1
JK
1408}
1409
a5f7db6a
CL
1410static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1411 struct bss_parameters *params)
c5c77ba1
JK
1412{
1413 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1414 return 0;
1415}
1416
a76b63ef 1417static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
c5c77ba1 1418{
e6e12661 1419 s32 s32Error = 0;
9529650a 1420 struct cfg_param_val pstrCfgParamVal;
2726887c 1421 struct wilc_priv *priv;
cf60106b 1422 struct wilc_vif *vif;
c5c77ba1
JK
1423
1424 priv = wiphy_priv(wiphy);
cf60106b 1425 vif = netdev_priv(priv->dev);
c5c77ba1 1426
87c05b28 1427 pstrCfgParamVal.flag = 0;
17aacd43 1428 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
c5c77ba1
JK
1429
1430 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1431 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1432 priv->dev->ieee80211_ptr->wiphy->retry_short);
87c05b28 1433 pstrCfgParamVal.flag |= RETRY_SHORT;
c5c77ba1
JK
1434 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1435 }
1436 if (changed & WIPHY_PARAM_RETRY_LONG) {
c5c77ba1 1437 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
87c05b28 1438 pstrCfgParamVal.flag |= RETRY_LONG;
c5c77ba1 1439 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
c5c77ba1
JK
1440 }
1441 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1442 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
87c05b28 1443 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
c5c77ba1 1444 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
c5c77ba1
JK
1445 }
1446
1447 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1448 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1449
87c05b28 1450 pstrCfgParamVal.flag |= RTS_THRESHOLD;
c5c77ba1 1451 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
c5c77ba1
JK
1452 }
1453
1454 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
fbf5379b 1455 s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
c5c77ba1
JK
1456 if (s32Error)
1457 PRINT_ER("Error in setting WIPHY PARAMS\n");
1458
1459
1460 return s32Error;
1461}
e5af0561 1462
4d46657a
CL
1463static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1464 struct cfg80211_pmksa *pmksa)
c5c77ba1 1465{
4e4467fd 1466 u32 i;
e6e12661 1467 s32 s32Error = 0;
63d03e47 1468 u8 flag = 0;
cf60106b 1469 struct wilc_vif *vif;
2726887c 1470 struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba1 1471
cf60106b 1472 vif = netdev_priv(priv->dev);
c5c77ba1
JK
1473 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1474
1475
1476 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1a646e7e 1477 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba1 1478 ETH_ALEN)) {
c5c77ba1
JK
1479 flag = PMKID_FOUND;
1480 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1481 break;
1482 }
1483 }
1484 if (i < WILC_MAX_NUM_PMKIDS) {
1485 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
d00d2ba3 1486 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
c5c77ba1 1487 ETH_ALEN);
d00d2ba3 1488 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
c5c77ba1
JK
1489 PMKID_LEN);
1490 if (!(flag == PMKID_FOUND))
1491 priv->pmkid_list.numpmkid++;
1492 } else {
1493 PRINT_ER("Invalid PMKID index\n");
1494 s32Error = -EINVAL;
1495 }
1496
1497 if (!s32Error) {
1498 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
fbf5379b 1499 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
c5c77ba1
JK
1500 }
1501 return s32Error;
1502}
1503
1ff86d96
CL
1504static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1505 struct cfg80211_pmksa *pmksa)
c5c77ba1 1506{
4e4467fd 1507 u32 i;
e6e12661 1508 s32 s32Error = 0;
c5c77ba1 1509
2726887c 1510 struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba1
JK
1511
1512 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1513
1514 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1a646e7e 1515 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba1 1516 ETH_ALEN)) {
c5c77ba1 1517 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
cd1e6cb4 1518 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
c5c77ba1
JK
1519 break;
1520 }
1521 }
1522
1523 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1524 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
d00d2ba3 1525 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba1
JK
1526 priv->pmkid_list.pmkidlist[i + 1].bssid,
1527 ETH_ALEN);
d00d2ba3 1528 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
c5c77ba1
JK
1529 priv->pmkid_list.pmkidlist[i].pmkid,
1530 PMKID_LEN);
1531 }
1532 priv->pmkid_list.numpmkid--;
1533 } else {
1534 s32Error = -EINVAL;
1535 }
1536
1537 return s32Error;
1538}
1539
b33c39b1 1540static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
c5c77ba1 1541{
2726887c 1542 struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba1
JK
1543
1544 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1545
a949f909 1546 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
c5c77ba1
JK
1547
1548 return 0;
1549}
c5c77ba1 1550
1608c403 1551static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
c5c77ba1 1552{
4e4467fd
CL
1553 u32 index = 0;
1554 u32 i = 0, j = 0;
c5c77ba1 1555
63d03e47
GKH
1556 u8 op_channel_attr_index = 0;
1557 u8 channel_list_attr_index = 0;
c5c77ba1
JK
1558
1559 while (index < len) {
1560 if (buf[index] == GO_INTENT_ATTR_ID) {
c5c77ba1 1561 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
c5c77ba1
JK
1562 }
1563
78174ada 1564 if (buf[index] == CHANLIST_ATTR_ID)
c5c77ba1 1565 channel_list_attr_index = index;
78174ada 1566 else if (buf[index] == OPERCHAN_ATTR_ID)
c5c77ba1 1567 op_channel_attr_index = index;
a89f7c55 1568 index += buf[index + 1] + 3;
c5c77ba1 1569 }
0bd8274f 1570 if (wlan_channel != INVALID_CHANNEL) {
c5c77ba1
JK
1571 if (channel_list_attr_index) {
1572 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1573 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1574 if (buf[i] == 0x51) {
1575 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
0bd8274f 1576 buf[j] = wlan_channel;
c5c77ba1
JK
1577 }
1578 break;
1579 }
1580 }
1581 }
a89f7c55 1582
c5c77ba1
JK
1583 if (op_channel_attr_index) {
1584 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1585 buf[op_channel_attr_index + 6] = 0x51;
0bd8274f 1586 buf[op_channel_attr_index + 7] = wlan_channel;
c5c77ba1
JK
1587 }
1588 }
1589}
1590
1608c403 1591static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
c5c77ba1 1592{
4e4467fd
CL
1593 u32 index = 0;
1594 u32 i = 0, j = 0;
c5c77ba1 1595
63d03e47
GKH
1596 u8 op_channel_attr_index = 0;
1597 u8 channel_list_attr_index = 0;
c5c77ba1
JK
1598
1599 while (index < len) {
c5c77ba1 1600 if (buf[index] == GO_INTENT_ATTR_ID) {
c5c77ba1 1601 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
c5c77ba1
JK
1602
1603 break;
1604 }
c5c77ba1 1605
78174ada 1606 if (buf[index] == CHANLIST_ATTR_ID)
c5c77ba1 1607 channel_list_attr_index = index;
78174ada 1608 else if (buf[index] == OPERCHAN_ATTR_ID)
c5c77ba1 1609 op_channel_attr_index = index;
a89f7c55 1610 index += buf[index + 1] + 3;
c5c77ba1 1611 }
0bd8274f 1612 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
c5c77ba1
JK
1613 if (channel_list_attr_index) {
1614 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1615 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1616 if (buf[i] == 0x51) {
1617 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
0bd8274f 1618 buf[j] = wlan_channel;
c5c77ba1
JK
1619 }
1620 break;
1621 }
1622 }
1623 }
a89f7c55 1624
c5c77ba1
JK
1625 if (op_channel_attr_index) {
1626 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1627 buf[op_channel_attr_index + 6] = 0x51;
0bd8274f 1628 buf[op_channel_attr_index + 7] = wlan_channel;
c5c77ba1
JK
1629 }
1630 }
1631}
1632
fbc2fe16 1633void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
c5c77ba1 1634{
2726887c 1635 struct wilc_priv *priv;
4e4467fd 1636 u32 header, pkt_offset;
441dc609 1637 struct host_if_drv *pstrWFIDrv;
4e4467fd 1638 u32 i = 0;
fb4ec9ca 1639 s32 s32Freq;
8dfaafd6 1640
c5c77ba1 1641 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
441dc609 1642 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1 1643
d00d2ba3 1644 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
c5c77ba1 1645
c5c77ba1
JK
1646 pkt_offset = GET_PKT_OFFSET(header);
1647
1648 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1649 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1650 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
c5c77ba1 1651 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
c5c77ba1
JK
1652 return;
1653 } else {
1654 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1655 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],
1656 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
c5c77ba1 1657 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
c5c77ba1
JK
1658 } else {
1659 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],
1660 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
c5c77ba1 1661 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
c5c77ba1
JK
1662 }
1663 return;
1664 }
1665 } else {
c5c77ba1
JK
1666 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1667
866a2c24 1668 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
c5c77ba1
JK
1669
1670 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1671 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1672
1229b1ab 1673 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
c5c77ba1
JK
1674 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1675 return;
1676 }
1677 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
c5c77ba1
JK
1678 switch (buff[ACTION_SUBTYPE_ID]) {
1679 case GAS_INTIAL_REQ:
1680 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1681 break;
1682
1683 case GAS_INTIAL_RSP:
1684 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1685 break;
1686
1687 case PUBLIC_ACT_VENDORSPEC:
881eb5d8 1688 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
c5c77ba1 1689 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
a25d5186 1690 if (!wilc_ie) {
c5c77ba1 1691 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
8668594a 1692 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
b84a3ac4 1693 p2p_recv_random = buff[i + 6];
a25d5186 1694 wilc_ie = true;
b84a3ac4 1695 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
c5c77ba1
JK
1696 break;
1697 }
1698 }
1699 }
1700 }
b84a3ac4 1701 if (p2p_local_random > p2p_recv_random) {
c5c77ba1
JK
1702 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1703 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1704 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
881eb5d8 1705 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
c5c77ba1
JK
1706 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1707 break;
1708 }
1709 }
1710 }
583d972c 1711 } else {
b84a3ac4 1712 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
583d972c 1713 }
c5c77ba1
JK
1714 }
1715
1716
a25d5186 1717 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
c5c77ba1 1718 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
c5c77ba1 1719 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
c5c77ba1
JK
1720 return;
1721 }
1722 break;
1723
1724 default:
1725 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1726 break;
1727 }
1728 }
1729 }
1730
783d07c1 1731 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
c5c77ba1
JK
1732 }
1733}
1734
c5c77ba1
JK
1735static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1736{
1737 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1738
1739
1740 kfree(pv_data->buff);
1741 kfree(pv_data);
1742}
1743
c5c77ba1
JK
1744static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1745{
2726887c 1746 struct wilc_priv *priv;
8dfaafd6 1747
2726887c 1748 priv = (struct wilc_priv *)pUserVoid;
c5c77ba1 1749
17aacd43 1750 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
c5c77ba1 1751
72ed4dc7 1752 priv->bInP2PlistenState = true;
c5c77ba1 1753
c5c77ba1
JK
1754 cfg80211_ready_on_channel(priv->wdev,
1755 priv->strRemainOnChanParams.u64ListenCookie,
1756 priv->strRemainOnChanParams.pstrListenChan,
1757 priv->strRemainOnChanParams.u32ListenDuration,
1758 GFP_KERNEL);
c5c77ba1
JK
1759}
1760
4e4467fd 1761static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
c5c77ba1 1762{
2726887c 1763 struct wilc_priv *priv;
8dfaafd6 1764
2726887c 1765 priv = (struct wilc_priv *)pUserVoid;
c5c77ba1 1766
c5c77ba1 1767 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
17aacd43 1768 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
c5c77ba1 1769
72ed4dc7 1770 priv->bInP2PlistenState = false;
c5c77ba1 1771
c5c77ba1
JK
1772 cfg80211_remain_on_channel_expired(priv->wdev,
1773 priv->strRemainOnChanParams.u64ListenCookie,
1774 priv->strRemainOnChanParams.pstrListenChan,
1775 GFP_KERNEL);
c5c77ba1
JK
1776 } else {
1777 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
1778 , priv->strRemainOnChanParams.u32ListenSessionID);
1779 }
1780}
1781
6d19d695
CL
1782static int remain_on_channel(struct wiphy *wiphy,
1783 struct wireless_dev *wdev,
1784 struct ieee80211_channel *chan,
1785 unsigned int duration, u64 *cookie)
c5c77ba1 1786{
e6e12661 1787 s32 s32Error = 0;
2726887c 1788 struct wilc_priv *priv;
cf60106b 1789 struct wilc_vif *vif;
8dfaafd6 1790
c5c77ba1 1791 priv = wiphy_priv(wiphy);
cf60106b 1792 vif = netdev_priv(priv->dev);
c5c77ba1
JK
1793
1794 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
1795
c5c77ba1 1796
c5c77ba1
JK
1797 if (wdev->iftype == NL80211_IFTYPE_AP) {
1798 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
1799 return s32Error;
1800 }
c5c77ba1 1801
866a2c24 1802 curr_channel = chan->hw_value;
c5c77ba1 1803
c5c77ba1
JK
1804 priv->strRemainOnChanParams.pstrListenChan = chan;
1805 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
c5c77ba1
JK
1806 priv->strRemainOnChanParams.u32ListenDuration = duration;
1807 priv->strRemainOnChanParams.u32ListenSessionID++;
1808
fbf5379b
GL
1809 s32Error = wilc_remain_on_channel(vif,
1810 priv->strRemainOnChanParams.u32ListenSessionID,
1811 duration, chan->hw_value,
1812 WILC_WFI_RemainOnChannelExpired,
1813 WILC_WFI_RemainOnChannelReady, (void *)priv);
c5c77ba1
JK
1814
1815 return s32Error;
1816}
1817
1dd5440b
CL
1818static int cancel_remain_on_channel(struct wiphy *wiphy,
1819 struct wireless_dev *wdev,
1820 u64 cookie)
c5c77ba1 1821{
e6e12661 1822 s32 s32Error = 0;
2726887c 1823 struct wilc_priv *priv;
cf60106b 1824 struct wilc_vif *vif;
8dfaafd6 1825
c5c77ba1 1826 priv = wiphy_priv(wiphy);
cf60106b 1827 vif = netdev_priv(priv->dev);
c5c77ba1
JK
1828
1829 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1830
fbf5379b 1831 s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
c5c77ba1
JK
1832 return s32Error;
1833}
a89f7c55 1834
c156032d
CL
1835static int mgmt_tx(struct wiphy *wiphy,
1836 struct wireless_dev *wdev,
1837 struct cfg80211_mgmt_tx_params *params,
1838 u64 *cookie)
c5c77ba1 1839{
c5c77ba1
JK
1840 struct ieee80211_channel *chan = params->chan;
1841 unsigned int wait = params->wait;
1842 const u8 *buf = params->buf;
1843 size_t len = params->len;
c5c77ba1
JK
1844 const struct ieee80211_mgmt *mgmt;
1845 struct p2p_mgmt_data *mgmt_tx;
2726887c 1846 struct wilc_priv *priv;
441dc609 1847 struct host_if_drv *pstrWFIDrv;
4e4467fd 1848 u32 i;
a4cac481 1849 struct wilc_vif *vif;
8668594a 1850 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
c5c77ba1 1851
a4cac481 1852 vif = netdev_priv(wdev->netdev);
c5c77ba1 1853 priv = wiphy_priv(wiphy);
441dc609 1854 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1
JK
1855
1856 *cookie = (unsigned long)buf;
1857 priv->u64tx_cookie = *cookie;
1858 mgmt = (const struct ieee80211_mgmt *) buf;
1859
1860 if (ieee80211_is_mgmt(mgmt->frame_control)) {
f3052587 1861 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
369a1d3b 1862 if (!mgmt_tx) {
c5c77ba1 1863 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
e6e12661 1864 return -EFAULT;
c5c77ba1 1865 }
f3052587 1866 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
369a1d3b 1867 if (!mgmt_tx->buff) {
c5c77ba1 1868 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
f638dd39 1869 kfree(mgmt_tx);
e6e12661 1870 return -EFAULT;
c5c77ba1 1871 }
d00d2ba3 1872 memcpy(mgmt_tx->buff, buf, len);
c5c77ba1
JK
1873 mgmt_tx->size = len;
1874
1875
1876 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1877 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
1878 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
fbf5379b 1879 wilc_set_mac_chnl_num(vif, chan->hw_value);
866a2c24 1880 curr_channel = chan->hw_value;
c5c77ba1 1881 } else if (ieee80211_is_action(mgmt->frame_control)) {
d85f5326 1882 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
c5c77ba1
JK
1883
1884
c5c77ba1 1885 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
c5c77ba1
JK
1886 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1887 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1888 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
fbf5379b
GL
1889 wilc_set_mac_chnl_num(vif,
1890 chan->hw_value);
866a2c24 1891 curr_channel = chan->hw_value;
c5c77ba1
JK
1892 }
1893 switch (buf[ACTION_SUBTYPE_ID]) {
1894 case GAS_INTIAL_REQ:
1895 {
1896 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
1897 break;
1898 }
1899
1900 case GAS_INTIAL_RSP:
1901 {
1902 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
1903 break;
1904 }
1905
1906 case PUBLIC_ACT_VENDORSPEC:
1907 {
881eb5d8 1908 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
c5c77ba1 1909 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
b84a3ac4 1910 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
583d972c
LK
1911 get_random_bytes(&p2p_local_random, 1);
1912 p2p_local_random++;
c5c77ba1
JK
1913 }
1914 }
1915
1916 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1917 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
b84a3ac4
LK
1918 if (p2p_local_random > p2p_recv_random) {
1919 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
c5c77ba1 1920
c5c77ba1 1921 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
881eb5d8 1922 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
c5c77ba1 1923 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
a4cac481 1924 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
c5c77ba1 1925 else
a4cac481 1926 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
c5c77ba1
JK
1927 break;
1928 }
1929 }
1930
1931 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
8668594a
LK
1932 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1933 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
c5c77ba1
JK
1934 mgmt_tx->size = buf_len;
1935 }
583d972c 1936 } else {
b84a3ac4 1937 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
583d972c 1938 }
c5c77ba1
JK
1939 }
1940
1941 } else {
1942 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
1943 }
1944
1945 break;
1946 }
1947
1948 default:
1949 {
1950 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1951 break;
1952 }
1953 }
c5c77ba1
JK
1954 }
1955
1956 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
1229b1ab 1957 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
c5c77ba1 1958
1229b1ab
LK
1959 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
1960 jiffies, pstrWFIDrv->p2p_timeout);
c5c77ba1
JK
1961 }
1962
829c477f
GL
1963 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1964 mgmt_tx->buff, mgmt_tx->size,
c9d4834d 1965 WILC_WFI_mgmt_tx_complete);
c5c77ba1
JK
1966 } else {
1967 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
1968 }
aaed3290 1969 return 0;
c5c77ba1
JK
1970}
1971
85c587a5
CL
1972static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1973 struct wireless_dev *wdev,
1974 u64 cookie)
c5c77ba1 1975{
2726887c 1976 struct wilc_priv *priv;
441dc609 1977 struct host_if_drv *pstrWFIDrv;
8dfaafd6 1978
c5c77ba1 1979 priv = wiphy_priv(wiphy);
441dc609 1980 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1
JK
1981
1982
1983 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
1229b1ab 1984 pstrWFIDrv->p2p_timeout = jiffies;
c5c77ba1 1985
7e4e87d3 1986 if (!priv->bInP2PlistenState) {
c5c77ba1
JK
1987 cfg80211_remain_on_channel_expired(priv->wdev,
1988 priv->strRemainOnChanParams.u64ListenCookie,
1989 priv->strRemainOnChanParams.pstrListenChan,
1990 GFP_KERNEL);
c5c77ba1
JK
1991 }
1992
1993 return 0;
1994}
1995
8e0735c5
CL
1996void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1997 u16 frame_type, bool reg)
c5c77ba1 1998{
2726887c 1999 struct wilc_priv *priv;
a4cac481 2000 struct wilc_vif *vif;
1b86935e 2001 struct wilc *wl;
c5c77ba1
JK
2002
2003 priv = wiphy_priv(wiphy);
a4cac481
GL
2004 vif = netdev_priv(priv->wdev->netdev);
2005 wl = vif->wilc;
c5c77ba1 2006
c5c77ba1
JK
2007 if (!frame_type)
2008 return;
2009
2010 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2011 switch (frame_type) {
2012 case PROBE_REQ:
2013 {
a4cac481
GL
2014 vif->g_struct_frame_reg[0].frame_type = frame_type;
2015 vif->g_struct_frame_reg[0].reg = reg;
c5c77ba1
JK
2016 }
2017 break;
2018
2019 case ACTION:
2020 {
a4cac481
GL
2021 vif->g_struct_frame_reg[1].frame_type = frame_type;
2022 vif->g_struct_frame_reg[1].reg = reg;
c5c77ba1
JK
2023 }
2024 break;
2025
2026 default:
2027 {
2028 break;
2029 }
c5c77ba1 2030 }
a89f7c55 2031
1b86935e 2032 if (!wl->initialized) {
c5c77ba1
JK
2033 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2034 return;
2035 }
fbf5379b 2036 wilc_frame_register(vif, frame_type, reg);
c5c77ba1 2037}
c5c77ba1 2038
a8047e26
CL
2039static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2040 s32 rssi_thold, u32 rssi_hyst)
c5c77ba1
JK
2041{
2042 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2043 return 0;
c5c77ba1 2044}
a89f7c55 2045
bdb6338f
CL
2046static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2047 int idx, u8 *mac, struct station_info *sinfo)
c5c77ba1 2048{
2726887c 2049 struct wilc_priv *priv;
cf60106b 2050 struct wilc_vif *vif;
8dfaafd6 2051
c5c77ba1
JK
2052 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2053
2054 if (idx != 0)
2055 return -ENOENT;
2056
2057 priv = wiphy_priv(wiphy);
cf60106b 2058 vif = netdev_priv(priv->dev);
c5c77ba1 2059
c5c77ba1 2060 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
c5c77ba1 2061
fbf5379b 2062 wilc_get_rssi(vif, &sinfo->signal);
c5c77ba1 2063
c5c77ba1 2064 return 0;
c5c77ba1
JK
2065}
2066
46530679
CL
2067static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2068 bool enabled, int timeout)
c5c77ba1 2069{
2726887c 2070 struct wilc_priv *priv;
cf60106b 2071 struct wilc_vif *vif;
8dfaafd6 2072
c5c77ba1
JK
2073 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2074
369a1d3b 2075 if (!wiphy)
c5c77ba1
JK
2076 return -ENOENT;
2077
2078 priv = wiphy_priv(wiphy);
cf60106b 2079 vif = netdev_priv(priv->dev);
369a1d3b 2080 if (!priv->hWILCWFIDrv) {
c5c77ba1
JK
2081 PRINT_ER("Driver is NULL\n");
2082 return -EIO;
2083 }
2084
0e1af73d 2085 if (wilc_enable_ps)
fbf5379b 2086 wilc_set_power_mgmt(vif, enabled, timeout);
c5c77ba1
JK
2087
2088
e6e12661 2089 return 0;
c5c77ba1 2090}
108b3439 2091
3615e9a3
CL
2092static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2093 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
c5c77ba1 2094{
2726887c 2095 struct wilc_priv *priv;
a4cac481 2096 struct wilc_vif *vif;
299382cf 2097 struct wilc *wl;
c5c77ba1 2098
a4cac481 2099 vif = netdev_priv(dev);
c5c77ba1 2100 priv = wiphy_priv(wiphy);
a4cac481 2101 wl = vif->wilc;
c5c77ba1
JK
2102
2103 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2104 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
583d972c 2105 p2p_local_random = 0x01;
b84a3ac4 2106 p2p_recv_random = 0x00;
a25d5186 2107 wilc_ie = false;
0e1af73d
AB
2108 wilc_optaining_ip = false;
2109 del_timer(&wilc_during_ip_timer);
c5c77ba1 2110 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
a89f7c55 2111
c5c77ba1
JK
2112 switch (type) {
2113 case NL80211_IFTYPE_STATION:
0e1af73d 2114 wilc_connecting = 0;
c5c77ba1 2115 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
c5c77ba1 2116
c5c77ba1
JK
2117 dev->ieee80211_ptr->iftype = type;
2118 priv->wdev->iftype = type;
a4cac481
GL
2119 vif->monitor_flag = 0;
2120 vif->iftype = STATION_MODE;
86bff01b 2121 wilc_set_operation_mode(vif, STATION_MODE);
c5c77ba1 2122
c5c77ba1 2123 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
c5c77ba1 2124
86bff01b
GL
2125 wilc_enable_ps = true;
2126 wilc_set_power_mgmt(vif, 1, 0);
c5c77ba1
JK
2127 break;
2128
2129 case NL80211_IFTYPE_P2P_CLIENT:
0e1af73d 2130 wilc_connecting = 0;
c5c77ba1 2131 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
c5c77ba1 2132
c5c77ba1
JK
2133 dev->ieee80211_ptr->iftype = type;
2134 priv->wdev->iftype = type;
a4cac481 2135 vif->monitor_flag = 0;
a4cac481 2136 vif->iftype = CLIENT_MODE;
86bff01b 2137 wilc_set_operation_mode(vif, STATION_MODE);
ee632309
GL
2138
2139 wilc_enable_ps = false;
2140 wilc_set_power_mgmt(vif, 0, 0);
c5c77ba1
JK
2141 break;
2142
2143 case NL80211_IFTYPE_AP:
0e1af73d 2144 wilc_enable_ps = false;
c5c77ba1 2145 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
c5c77ba1
JK
2146 dev->ieee80211_ptr->iftype = type;
2147 priv->wdev->iftype = type;
a4cac481 2148 vif->iftype = AP_MODE;
86bff01b
GL
2149
2150 if (wl->initialized) {
b3306865
GL
2151 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
2152 0);
86bff01b
GL
2153 wilc_set_operation_mode(vif, AP_MODE);
2154 wilc_set_power_mgmt(vif, 0, 0);
c5c77ba1 2155 }
c5c77ba1
JK
2156 break;
2157
2158 case NL80211_IFTYPE_P2P_GO:
2159 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2160
0e1af73d 2161 wilc_optaining_ip = true;
7e872df9
LK
2162 mod_timer(&wilc_during_ip_timer,
2163 jiffies + msecs_to_jiffies(during_ip_time));
c5c77ba1 2164 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
86bff01b
GL
2165
2166 wilc_set_operation_mode(vif, AP_MODE);
c5c77ba1
JK
2167 dev->ieee80211_ptr->iftype = type;
2168 priv->wdev->iftype = type;
a4cac481 2169 vif->iftype = GO_MODE;
ee632309
GL
2170
2171 wilc_enable_ps = false;
2172 wilc_set_power_mgmt(vif, 0, 0);
c5c77ba1
JK
2173 break;
2174
2175 default:
2176 PRINT_ER("Unknown interface type= %d\n", type);
aaed3290 2177 return -EINVAL;
c5c77ba1
JK
2178 }
2179
aaed3290 2180 return 0;
c5c77ba1
JK
2181}
2182
a13168d7
CL
2183static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2184 struct cfg80211_ap_settings *settings)
c5c77ba1
JK
2185{
2186 struct cfg80211_beacon_data *beacon = &(settings->beacon);
2726887c 2187 struct wilc_priv *priv;
e6e12661 2188 s32 s32Error = 0;
684dc186 2189 struct wilc *wl;
a4cac481 2190 struct wilc_vif *vif;
c5c77ba1
JK
2191
2192 priv = wiphy_priv(wiphy);
a4cac481
GL
2193 vif = netdev_priv(dev);
2194 wl = vif ->wilc;
c5c77ba1
JK
2195 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2196
17aacd43 2197 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
c5c77ba1
JK
2198 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2199
80785a9a 2200 s32Error = set_channel(wiphy, &settings->chandef);
c5c77ba1 2201
e6e12661 2202 if (s32Error != 0)
c5c77ba1 2203 PRINT_ER("Error in setting channel\n");
c5c77ba1 2204
ff355679 2205 wilc_wlan_set_bssid(dev, wl->vif[vif->u8IfIdx]->src_addr, AP_MODE);
cba352a4 2206 wilc_set_power_mgmt(vif, 0, 0);
c5c77ba1 2207
fbf5379b
GL
2208 s32Error = wilc_add_beacon(vif, settings->beacon_interval,
2209 settings->dtim_period, beacon->head_len,
2210 (u8 *)beacon->head, beacon->tail_len,
2211 (u8 *)beacon->tail);
c5c77ba1
JK
2212
2213 return s32Error;
2214}
2215
2a4c84d7
CL
2216static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2217 struct cfg80211_beacon_data *beacon)
c5c77ba1 2218{
2726887c 2219 struct wilc_priv *priv;
cf60106b 2220 struct wilc_vif *vif;
e6e12661 2221 s32 s32Error = 0;
c5c77ba1
JK
2222
2223 priv = wiphy_priv(wiphy);
cf60106b 2224 vif = netdev_priv(priv->dev);
c5c77ba1
JK
2225 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2226
2227
fbf5379b
GL
2228 s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
2229 (u8 *)beacon->head, beacon->tail_len,
2230 (u8 *)beacon->tail);
c5c77ba1
JK
2231
2232 return s32Error;
2233}
2234
c8cddd79 2235static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
c5c77ba1 2236{
e6e12661 2237 s32 s32Error = 0;
2726887c 2238 struct wilc_priv *priv;
cf60106b 2239 struct wilc_vif *vif;
63d03e47 2240 u8 NullBssid[ETH_ALEN] = {0};
c5c77ba1 2241
7ae43363
LK
2242 if (!wiphy)
2243 return -EFAULT;
c5c77ba1
JK
2244
2245 priv = wiphy_priv(wiphy);
cf60106b 2246 vif = netdev_priv(priv->dev);
c5c77ba1
JK
2247
2248 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2249
ba615f1e 2250 wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
c5c77ba1 2251
fbf5379b 2252 s32Error = wilc_del_beacon(vif);
c5c77ba1 2253
7dc1d0cc
LK
2254 if (s32Error)
2255 PRINT_ER("Host delete beacon fail\n");
c5c77ba1 2256
c5c77ba1
JK
2257 return s32Error;
2258}
2259
ed26955c
CL
2260static int add_station(struct wiphy *wiphy, struct net_device *dev,
2261 const u8 *mac, struct station_parameters *params)
c5c77ba1 2262{
e6e12661 2263 s32 s32Error = 0;
2726887c 2264 struct wilc_priv *priv;
6a89ba9c 2265 struct add_sta_param strStaParams = { {0} };
a4cac481 2266 struct wilc_vif *vif;
c5c77ba1 2267
7ae43363
LK
2268 if (!wiphy)
2269 return -EFAULT;
c5c77ba1
JK
2270
2271 priv = wiphy_priv(wiphy);
a4cac481 2272 vif = netdev_priv(dev);
c5c77ba1 2273
a4cac481 2274 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2353c388 2275 memcpy(strStaParams.bssid, mac, ETH_ALEN);
d00d2ba3 2276 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
4101eb8a 2277 strStaParams.aid = params->aid;
e734223c 2278 strStaParams.rates_len = params->supported_rates_len;
a622e016 2279 strStaParams.rates = params->supported_rates;
c5c77ba1
JK
2280
2281 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2282
2283 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],
2284 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
4101eb8a 2285 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
e734223c
LK
2286 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2287 strStaParams.rates_len);
c5c77ba1 2288
369a1d3b 2289 if (!params->ht_capa) {
22520120 2290 strStaParams.ht_supported = false;
c5c77ba1 2291 } else {
22520120 2292 strStaParams.ht_supported = true;
0d073f69 2293 strStaParams.ht_capa_info = params->ht_capa->cap_info;
fba1f2d2 2294 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
5ebbf4f7
LK
2295 memcpy(strStaParams.ht_supp_mcs_set,
2296 &params->ht_capa->mcs,
2297 WILC_SUPP_MCS_SET_SIZE);
223741d7 2298 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
74fe73cf 2299 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
a486baff 2300 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
c5c77ba1
JK
2301 }
2302
f676e17a 2303 strStaParams.flags_mask = params->sta_flags_mask;
67ab64e4 2304 strStaParams.flags_set = params->sta_flags_set;
c5c77ba1 2305
22520120
LK
2306 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2307 strStaParams.ht_supported);
0d073f69
LK
2308 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2309 strStaParams.ht_capa_info);
fba1f2d2
LK
2310 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2311 strStaParams.ht_ampdu_params);
223741d7
LK
2312 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2313 strStaParams.ht_ext_params);
74fe73cf
LK
2314 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2315 strStaParams.ht_tx_bf_cap);
a486baff
LK
2316 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2317 strStaParams.ht_ante_sel);
f676e17a
LK
2318 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2319 strStaParams.flags_mask);
67ab64e4
LK
2320 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2321 strStaParams.flags_set);
c5c77ba1 2322
fbf5379b 2323 s32Error = wilc_add_station(vif, &strStaParams);
7dc1d0cc
LK
2324 if (s32Error)
2325 PRINT_ER("Host add station fail\n");
c5c77ba1
JK
2326 }
2327
c5c77ba1
JK
2328 return s32Error;
2329}
2330
a0a8be95
CL
2331static int del_station(struct wiphy *wiphy, struct net_device *dev,
2332 struct station_del_parameters *params)
c5c77ba1 2333{
057d1e97 2334 const u8 *mac = params->mac;
e6e12661 2335 s32 s32Error = 0;
2726887c 2336 struct wilc_priv *priv;
a4cac481 2337 struct wilc_vif *vif;
8dfaafd6 2338
7ae43363
LK
2339 if (!wiphy)
2340 return -EFAULT;
c5c77ba1
JK
2341
2342 priv = wiphy_priv(wiphy);
a4cac481 2343 vif = netdev_priv(dev);
c5c77ba1 2344
a4cac481 2345 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
c5c77ba1
JK
2346 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2347
2348
369a1d3b 2349 if (!mac) {
17aacd43 2350 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
fbf5379b
GL
2351 s32Error = wilc_del_allstation(vif,
2352 priv->assoc_stainfo.au8Sta_AssociatedBss);
c5c77ba1
JK
2353 } else {
2354 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]);
2355 }
2356
fbf5379b 2357 s32Error = wilc_del_station(vif, mac);
c5c77ba1 2358
7dc1d0cc
LK
2359 if (s32Error)
2360 PRINT_ER("Host delete station fail\n");
c5c77ba1
JK
2361 }
2362 return s32Error;
2363}
2364
14b42084
CL
2365static int change_station(struct wiphy *wiphy, struct net_device *dev,
2366 const u8 *mac, struct station_parameters *params)
c5c77ba1 2367{
e6e12661 2368 s32 s32Error = 0;
2726887c 2369 struct wilc_priv *priv;
6a89ba9c 2370 struct add_sta_param strStaParams = { {0} };
a4cac481 2371 struct wilc_vif *vif;
c5c77ba1
JK
2372
2373
2374 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2375
7ae43363
LK
2376 if (!wiphy)
2377 return -EFAULT;
c5c77ba1
JK
2378
2379 priv = wiphy_priv(wiphy);
a4cac481 2380 vif = netdev_priv(dev);
c5c77ba1 2381
a4cac481 2382 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2353c388 2383 memcpy(strStaParams.bssid, mac, ETH_ALEN);
4101eb8a 2384 strStaParams.aid = params->aid;
e734223c 2385 strStaParams.rates_len = params->supported_rates_len;
a622e016 2386 strStaParams.rates = params->supported_rates;
c5c77ba1 2387
2353c388
LK
2388 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2389 strStaParams.bssid[0], strStaParams.bssid[1],
2390 strStaParams.bssid[2], strStaParams.bssid[3],
2391 strStaParams.bssid[4], strStaParams.bssid[5]);
4101eb8a 2392 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
e734223c
LK
2393 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2394 strStaParams.rates_len);
c5c77ba1 2395
369a1d3b 2396 if (!params->ht_capa) {
22520120 2397 strStaParams.ht_supported = false;
c5c77ba1 2398 } else {
22520120 2399 strStaParams.ht_supported = true;
0d073f69 2400 strStaParams.ht_capa_info = params->ht_capa->cap_info;
fba1f2d2 2401 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
5ebbf4f7
LK
2402 memcpy(strStaParams.ht_supp_mcs_set,
2403 &params->ht_capa->mcs,
2404 WILC_SUPP_MCS_SET_SIZE);
223741d7 2405 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
74fe73cf 2406 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
a486baff 2407 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
c5c77ba1
JK
2408 }
2409
f676e17a 2410 strStaParams.flags_mask = params->sta_flags_mask;
67ab64e4 2411 strStaParams.flags_set = params->sta_flags_set;
c5c77ba1 2412
22520120
LK
2413 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2414 strStaParams.ht_supported);
0d073f69
LK
2415 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2416 strStaParams.ht_capa_info);
fba1f2d2
LK
2417 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2418 strStaParams.ht_ampdu_params);
223741d7
LK
2419 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2420 strStaParams.ht_ext_params);
74fe73cf
LK
2421 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2422 strStaParams.ht_tx_bf_cap);
a486baff
LK
2423 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2424 strStaParams.ht_ante_sel);
f676e17a
LK
2425 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2426 strStaParams.flags_mask);
67ab64e4
LK
2427 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2428 strStaParams.flags_set);
c5c77ba1 2429
fbf5379b 2430 s32Error = wilc_edit_station(vif, &strStaParams);
7dc1d0cc
LK
2431 if (s32Error)
2432 PRINT_ER("Host edit station fail\n");
c5c77ba1
JK
2433 }
2434 return s32Error;
2435}
2436
37316e81
CL
2437static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2438 const char *name,
2439 unsigned char name_assign_type,
2440 enum nl80211_iftype type,
2441 u32 *flags,
2442 struct vif_params *params)
c5c77ba1 2443{
a4cac481 2444 struct wilc_vif *vif;
2726887c 2445 struct wilc_priv *priv;
c5c77ba1 2446 struct net_device *new_ifc = NULL;
8dfaafd6 2447
c5c77ba1
JK
2448 priv = wiphy_priv(wiphy);
2449
2450
2451
2452 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2453
a4cac481 2454 vif = netdev_priv(priv->wdev->netdev);
c5c77ba1
JK
2455
2456
2457 if (type == NL80211_IFTYPE_MONITOR) {
2458 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
1006b5c7
GL
2459 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->ndev);
2460 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
369a1d3b 2461 if (new_ifc) {
c5c77ba1 2462 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
a4cac481
GL
2463 vif = netdev_priv(priv->wdev->netdev);
2464 vif->monitor_flag = 1;
c5c77ba1
JK
2465 } else
2466 PRINT_ER("Error in initializing monitor interface\n ");
2467 }
c5c77ba1 2468 return priv->wdev;
c5c77ba1
JK
2469}
2470
956d7211 2471static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
c5c77ba1
JK
2472{
2473 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
e6e12661 2474 return 0;
c5c77ba1
JK
2475}
2476
73584a40
GL
2477static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2478{
2479 struct wilc_priv *priv = wiphy_priv(wiphy);
2480 struct wilc_vif *vif = netdev_priv(priv->dev);
2481
2482 if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2483 vif->wilc->suspend_event = true;
2484 else
2485 vif->wilc->suspend_event = false;
2486
2487 return 0;
2488}
2489
2490static int wilc_resume(struct wiphy *wiphy)
2491{
2492 struct wilc_priv *priv = wiphy_priv(wiphy);
2493 struct wilc_vif *vif = netdev_priv(priv->dev);
2494
2495 netdev_info(vif->ndev, "cfg resume\n");
2496 return 0;
2497}
2498
2499static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2500{
2501 struct wilc_priv *priv = wiphy_priv(wiphy);
2502 struct wilc_vif *vif = netdev_priv(priv->dev);
2503
2504 netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2505}
2506
70418790
GL
2507static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2508 enum nl80211_tx_power_setting type, int mbm)
2509{
2510 int ret;
2511 s32 tx_power = MBM_TO_DBM(mbm);
2512 struct wilc_priv *priv = wiphy_priv(wiphy);
2513 struct wilc_vif *vif = netdev_priv(priv->dev);
2514
2515 if (tx_power < 0)
2516 tx_power = 0;
2517 else if (tx_power > 18)
2518 tx_power = 18;
2519 ret = wilc_set_tx_power(vif, tx_power);
2520 if (ret)
2521 netdev_err(vif->ndev, "Failed to set tx power\n");
2522
2523 return ret;
2524}
2525
2526static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2527 int *dbm)
2528{
2529 int ret;
2530 struct wilc_priv *priv = wiphy_priv(wiphy);
2531 struct wilc_vif *vif = netdev_priv(priv->dev);
2532
2533 ret = wilc_get_tx_power(vif, (u8 *)dbm);
2534 if (ret)
2535 netdev_err(vif->ndev, "Failed to get tx power\n");
2536
2537 return ret;
2538}
2539
08241924 2540static struct cfg80211_ops wilc_cfg80211_ops = {
80785a9a 2541 .set_monitor_channel = set_channel,
0e30d06d 2542 .scan = scan,
4ffbcdb6 2543 .connect = connect,
b027cde9 2544 .disconnect = disconnect,
953d417a 2545 .add_key = add_key,
3044ba7e 2546 .del_key = del_key,
f4893dfc 2547 .get_key = get_key,
0f5b8ca3 2548 .set_default_key = set_default_key,
69deb4c2 2549 .add_virtual_intf = add_virtual_intf,
b4a73355 2550 .del_virtual_intf = del_virtual_intf,
3615e9a3 2551 .change_virtual_intf = change_virtual_intf,
c5c77ba1 2552
a13168d7 2553 .start_ap = start_ap,
2a4c84d7 2554 .change_beacon = change_beacon,
c8cddd79 2555 .stop_ap = stop_ap,
ed26955c 2556 .add_station = add_station,
a0a8be95 2557 .del_station = del_station,
14b42084 2558 .change_station = change_station,
f06f562d 2559 .get_station = get_station,
bdb6338f 2560 .dump_station = dump_station,
a5f7db6a 2561 .change_bss = change_bss,
a76b63ef 2562 .set_wiphy_params = set_wiphy_params,
c5c77ba1 2563
4d46657a 2564 .set_pmksa = set_pmksa,
1ff86d96 2565 .del_pmksa = del_pmksa,
b33c39b1 2566 .flush_pmksa = flush_pmksa,
6d19d695 2567 .remain_on_channel = remain_on_channel,
1dd5440b 2568 .cancel_remain_on_channel = cancel_remain_on_channel,
4a2f9b38 2569 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
12a26a33 2570 .mgmt_tx = mgmt_tx,
8e0735c5 2571 .mgmt_frame_register = wilc_mgmt_frame_register,
46530679 2572 .set_power_mgmt = set_power_mgmt,
a8047e26 2573 .set_cqm_rssi_config = set_cqm_rssi_config,
c5c77ba1 2574
73584a40
GL
2575 .suspend = wilc_suspend,
2576 .resume = wilc_resume,
2577 .set_wakeup = wilc_set_wakeup,
70418790
GL
2578 .set_tx_power = set_tx_power,
2579 .get_tx_power = get_tx_power,
73584a40 2580
c5c77ba1
JK
2581};
2582
c5c77ba1
JK
2583int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2584{
2726887c 2585 struct wilc_priv *priv;
c5c77ba1
JK
2586
2587 priv = wiphy_priv(wiphy);
c5c77ba1 2588 switch (changed) {
c5c77ba1
JK
2589 case WILC_WFI_RX_PKT:
2590 {
c5c77ba1
JK
2591 priv->netstats.rx_packets++;
2592 priv->netstats.rx_bytes += pktlen;
2593 priv->netstats.rx_time = get_jiffies_64();
2594 }
2595 break;
2596
2597 case WILC_WFI_TX_PKT:
2598 {
2599 priv->netstats.tx_packets++;
2600 priv->netstats.tx_bytes += pktlen;
2601 priv->netstats.tx_time = get_jiffies_64();
2602
2603 }
2604 break;
2605
2606 default:
2607 break;
2608 }
c5c77ba1
JK
2609 return 0;
2610}
c5c77ba1 2611
1608c403 2612static struct wireless_dev *WILC_WFI_CfgAlloc(void)
c5c77ba1 2613{
c5c77ba1
JK
2614 struct wireless_dev *wdev;
2615
2616
2617 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
a89f7c55 2618
c5c77ba1
JK
2619 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2620 if (!wdev) {
2621 PRINT_ER("Cannot allocate wireless device\n");
2622 goto _fail_;
2623 }
2624
2726887c 2625 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
c5c77ba1
JK
2626 if (!wdev->wiphy) {
2627 PRINT_ER("Cannot allocate wiphy\n");
2628 goto _fail_mem_;
c5c77ba1
JK
2629 }
2630
c5c77ba1
JK
2631 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2632 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2633 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2634 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2635 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
c5c77ba1 2636
c5c77ba1
JK
2637 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2638
2639 return wdev;
2640
2641_fail_mem_:
2642 kfree(wdev);
2643_fail_:
2644 return NULL;
c5c77ba1 2645}
a89f7c55 2646
2e7d5377 2647struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
c5c77ba1 2648{
2726887c 2649 struct wilc_priv *priv;
c5c77ba1 2650 struct wireless_dev *wdev;
e6e12661 2651 s32 s32Error = 0;
c5c77ba1
JK
2652
2653 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2654
2655 wdev = WILC_WFI_CfgAlloc();
369a1d3b 2656 if (!wdev) {
c5c77ba1
JK
2657 PRINT_ER("CfgAlloc Failed\n");
2658 return NULL;
2659 }
2660
c5c77ba1 2661 priv = wdev_priv(wdev);
83383ea3 2662 sema_init(&(priv->SemHandleUpdateStats), 1);
c5c77ba1 2663 priv->wdev = wdev;
c5c77ba1 2664 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
abb4f8ad 2665#ifdef CONFIG_PM
73584a40 2666 wdev->wiphy->wowlan = &wowlan_support;
abb4f8ad 2667#endif
c5c77ba1
JK
2668 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2669 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
c5c77ba1
JK
2670
2671 wdev->wiphy->max_scan_ie_len = 1000;
c5c77ba1 2672 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
c5c77ba1
JK
2673 wdev->wiphy->cipher_suites = cipher_suites;
2674 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
c5c77ba1 2675 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
c5c77ba1 2676
c5c77ba1 2677 wdev->wiphy->max_remain_on_channel_duration = 500;
c5c77ba1
JK
2678 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2679 BIT(NL80211_IFTYPE_P2P_CLIENT);
c5c77ba1 2680 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
c5c77ba1
JK
2681 wdev->iftype = NL80211_IFTYPE_STATION;
2682
2683
2684
2685 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2686 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2687 wdev->wiphy->interface_modes, wdev->iftype);
2688
2e7d5377 2689 set_wiphy_dev(wdev->wiphy, dev);
c5c77ba1 2690
c5c77ba1
JK
2691 s32Error = wiphy_register(wdev->wiphy);
2692 if (s32Error) {
2693 PRINT_ER("Cannot register wiphy device\n");
c5c77ba1
JK
2694 } else {
2695 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2696 }
2697
c5c77ba1 2698 priv->dev = net;
c5c77ba1 2699 return wdev;
c5c77ba1 2700}
a89f7c55 2701
dd4b6a83 2702int wilc_init_host_int(struct net_device *net)
c5c77ba1 2703{
1a8ccd85 2704 int s32Error = 0;
c5c77ba1 2705
2726887c 2706 struct wilc_priv *priv;
c5c77ba1 2707
c5c77ba1
JK
2708 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2709 priv = wdev_priv(net->ieee80211_ptr);
2710 if (op_ifcs == 0) {
93dee8ee 2711 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
0e1af73d 2712 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
c5c77ba1
JK
2713 }
2714 op_ifcs++;
2715 if (s32Error < 0) {
2716 PRINT_ER("Failed to creat refresh Timer\n");
2717 return s32Error;
2718 }
2719
72ed4dc7 2720 priv->gbAutoRateAdjusted = false;
c5c77ba1 2721
72ed4dc7 2722 priv->bInP2PlistenState = false;
c5c77ba1 2723
83383ea3 2724 sema_init(&(priv->hSemScanReq), 1);
0e1af73d 2725 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
f1fe9c43 2726 if (s32Error)
c5c77ba1 2727 PRINT_ER("Error while initializing hostinterface\n");
f1fe9c43 2728
c5c77ba1
JK
2729 return s32Error;
2730}
2731
a9a16823 2732int wilc_deinit_host_int(struct net_device *net)
c5c77ba1 2733{
1a8ccd85 2734 int s32Error = 0;
cf60106b 2735 struct wilc_vif *vif;
2726887c 2736 struct wilc_priv *priv;
8dfaafd6 2737
c5c77ba1 2738 priv = wdev_priv(net->ieee80211_ptr);
cf60106b 2739 vif = netdev_priv(priv->dev);
c5c77ba1 2740
72ed4dc7 2741 priv->gbAutoRateAdjusted = false;
c5c77ba1 2742
72ed4dc7 2743 priv->bInP2PlistenState = false;
c5c77ba1
JK
2744
2745 op_ifcs--;
2746
fbf5379b 2747 s32Error = wilc_deinit(vif);
c5c77ba1 2748
d14991af 2749 clear_shadow_scan();
c5c77ba1
JK
2750 if (op_ifcs == 0) {
2751 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
0e1af73d 2752 del_timer_sync(&wilc_during_ip_timer);
c5c77ba1 2753 }
c5c77ba1 2754
f1fe9c43 2755 if (s32Error)
c5c77ba1 2756 PRINT_ER("Error while deintializing host interface\n");
f1fe9c43 2757
c5c77ba1
JK
2758 return s32Error;
2759}
2760
96da20a9 2761void wilc_free_wiphy(struct net_device *net)
c5c77ba1 2762{
c5c77ba1
JK
2763 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2764
619837ae 2765 if (!net) {
c5c77ba1
JK
2766 PRINT_D(INIT_DBG, "net_device is NULL\n");
2767 return;
2768 }
2769
619837ae 2770 if (!net->ieee80211_ptr) {
c5c77ba1
JK
2771 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2772 return;
2773 }
2774
619837ae 2775 if (!net->ieee80211_ptr->wiphy) {
c5c77ba1
JK
2776 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2777 return;
2778 }
2779
2780 wiphy_unregister(net->ieee80211_ptr->wiphy);
2781
2782 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2783 wiphy_free(net->ieee80211_ptr->wiphy);
2784 kfree(net->ieee80211_ptr);
c5c77ba1 2785}