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