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