staging: wilc1000: change vif to pointer to refence real private data
[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
f1ab117d
LK
199 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
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
f1ab117d 285 wilc_free_join_params(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)
f1ab117d
LK
379 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
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;
8dfaafd6 598
c5c77ba1
JK
599 priv = wiphy_priv(wiphy);
600
c5c77ba1
JK
601 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
602 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
c5c77ba1 603
866a2c24 604 curr_channel = channelnum;
0e1af73d 605 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
c5c77ba1 606
dd739ea5 607 if (result != 0)
c5c77ba1
JK
608 PRINT_ER("Error in setting channel %d\n", channelnum);
609
dd739ea5 610 return result;
c5c77ba1
JK
611}
612
0e30d06d 613static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
c5c77ba1 614{
2726887c 615 struct wilc_priv *priv;
4e4467fd 616 u32 i;
e6e12661 617 s32 s32Error = 0;
63d03e47 618 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
607db447 619 struct hidden_network strHiddenNetwork;
c5c77ba1
JK
620
621 priv = wiphy_priv(wiphy);
622
c5c77ba1
JK
623 priv->pstrScanReq = request;
624
625 priv->u32RcvdChCount = 0;
626
0e1af73d 627 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
12b0138b 628 reset_shadow_found();
c5c77ba1 629
72ed4dc7 630 priv->bCfgScanning = true;
a89f7c55 631 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
c5c77ba1 632 for (i = 0; i < request->n_channels; i++) {
63d03e47 633 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
c5c77ba1
JK
634 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
635 }
636
637 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
52db7520 638 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
c5c77ba1
JK
639
640 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
641
642 if (request->n_ssids >= 1) {
607db447 643 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
c5c77ba1
JK
644 strHiddenNetwork.u8ssidnum = request->n_ssids;
645
646
c5c77ba1 647 for (i = 0; i < request->n_ssids; i++) {
369a1d3b
LK
648 if (request->ssids[i].ssid &&
649 request->ssids[i].ssid_len != 0) {
f3052587 650 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
d00d2ba3 651 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
c5c77ba1
JK
652 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
653 } else {
17aacd43 654 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
c5c77ba1
JK
655 strHiddenNetwork.u8ssidnum -= 1;
656 }
657 }
17aacd43 658 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
0e1af73d 659 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
c5c77ba1 660 au8ScanChanList, request->n_channels,
63d03e47 661 (const u8 *)request->ie, request->ie_len,
c5c77ba1
JK
662 CfgScanResult, (void *)priv, &strHiddenNetwork);
663 } else {
17aacd43 664 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
0e1af73d 665 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
c5c77ba1 666 au8ScanChanList, request->n_channels,
63d03e47 667 (const u8 *)request->ie, request->ie_len,
c5c77ba1
JK
668 CfgScanResult, (void *)priv, NULL);
669 }
c5c77ba1
JK
670 } else {
671 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
17aacd43 672 " channels\n");
c5c77ba1
JK
673 }
674
e6e12661 675 if (s32Error != 0) {
c5c77ba1
JK
676 s32Error = -EBUSY;
677 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
678 }
679
680 return s32Error;
681}
682
4ffbcdb6
CL
683static int connect(struct wiphy *wiphy, struct net_device *dev,
684 struct cfg80211_connect_params *sme)
c5c77ba1 685{
e6e12661 686 s32 s32Error = 0;
4e4467fd 687 u32 i;
63d03e47 688 u8 u8security = NO_ENCRYPT;
841dfc42 689 enum AUTHTYPE tenuAuth_type = ANY;
576917ad
DL
690 char *pcgroup_encrypt_val = NULL;
691 char *pccipher_group = NULL;
692 char *pcwpa_version = NULL;
c5c77ba1 693
2726887c 694 struct wilc_priv *priv;
441dc609 695 struct host_if_drv *pstrWFIDrv;
c5c77ba1
JK
696 tstrNetworkInfo *pstrNetworkInfo = NULL;
697
698
0e1af73d 699 wilc_connecting = 1;
c5c77ba1 700 priv = wiphy_priv(wiphy);
441dc609 701 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
c5c77ba1 702
0e1af73d 703 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
c5c77ba1 704
8a14330f 705 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
3f882895 706 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
c5c77ba1 707 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
ab16ec0b
LK
708 pstrWFIDrv->p2p_connect = 1;
709 } else {
710 pstrWFIDrv->p2p_connect = 0;
711 }
17aacd43 712 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
c5c77ba1 713
771fbae4 714 for (i = 0; i < last_scanned_cnt; i++) {
f1ab117d
LK
715 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
716 memcmp(last_scanned_shadow[i].au8ssid,
717 sme->ssid,
718 sme->ssid_len) == 0) {
c5c77ba1 719 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
369a1d3b 720 if (!sme->bssid) {
c5c77ba1
JK
721 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
722 break;
723 } else {
f1ab117d
LK
724 if (memcmp(last_scanned_shadow[i].au8bssid,
725 sme->bssid,
726 ETH_ALEN) == 0) {
c5c77ba1
JK
727 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
728 break;
729 }
730 }
731 }
732 }
733
771fbae4 734 if (i < last_scanned_cnt) {
c5c77ba1
JK
735 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
736
f1ab117d 737 pstrNetworkInfo = &last_scanned_shadow[i];
c5c77ba1
JK
738
739 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
740 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
741 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
742 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
743 } else {
744 s32Error = -ENOENT;
771fbae4 745 if (last_scanned_cnt == 0)
c5c77ba1
JK
746 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
747 else
748 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
749
750 goto done;
751 }
752
753 priv->WILC_WFI_wep_default = 0;
2cc46837
CL
754 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
755 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
c5c77ba1
JK
756
757 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
758 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
759
760 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
761
762 if (INFO) {
763 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
764 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
765 }
766
767 if (sme->crypto.cipher_group != NO_ENCRYPT) {
c5c77ba1
JK
768 pcwpa_version = "Default";
769 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
c5c77ba1 770 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
c5c77ba1
JK
771 u8security = ENCRYPT_ENABLED | WEP;
772 pcgroup_encrypt_val = "WEP40";
773 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
774 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
775
776 if (INFO) {
777 for (i = 0; i < sme->key_len; i++)
778 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
779 }
780 priv->WILC_WFI_wep_default = sme->key_idx;
781 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
d00d2ba3 782 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
c5c77ba1 783
c5c77ba1 784 g_key_wep_params.key_len = sme->key_len;
f3052587 785 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
c5c77ba1
JK
786 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
787 g_key_wep_params.key_idx = sme->key_idx;
72ed4dc7 788 g_wep_keys_saved = true;
c5c77ba1 789
0e1af73d
AB
790 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
791 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
c5c77ba1 792 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
c5c77ba1
JK
793 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
794 pcgroup_encrypt_val = "WEP104";
795 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
796
797 priv->WILC_WFI_wep_default = sme->key_idx;
798 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
d00d2ba3 799 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
c5c77ba1 800
c5c77ba1 801 g_key_wep_params.key_len = sme->key_len;
f3052587 802 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
c5c77ba1
JK
803 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
804 g_key_wep_params.key_idx = sme->key_idx;
72ed4dc7 805 g_wep_keys_saved = true;
c5c77ba1 806
0e1af73d
AB
807 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
808 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
c5c77ba1 809 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
c5c77ba1 810 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
811 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
812 pcgroup_encrypt_val = "WPA2_TKIP";
813 pccipher_group = "TKIP";
a89f7c55 814 } else {
c5c77ba1
JK
815 u8security = ENCRYPT_ENABLED | WPA2 | AES;
816 pcgroup_encrypt_val = "WPA2_AES";
817 pccipher_group = "AES";
818 }
819 pcwpa_version = "WPA_VERSION_2";
820 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
821 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
822 u8security = ENCRYPT_ENABLED | WPA | TKIP;
823 pcgroup_encrypt_val = "WPA_TKIP";
824 pccipher_group = "TKIP";
a89f7c55 825 } else {
c5c77ba1
JK
826 u8security = ENCRYPT_ENABLED | WPA | AES;
827 pcgroup_encrypt_val = "WPA_AES";
828 pccipher_group = "AES";
c5c77ba1
JK
829 }
830 pcwpa_version = "WPA_VERSION_1";
831
c5c77ba1
JK
832 } else {
833 s32Error = -ENOTSUPP;
834 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
835
836 goto done;
837 }
c5c77ba1
JK
838 }
839
c5c77ba1
JK
840 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
841 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
842 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
843 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
844 u8security = u8security | TKIP;
a89f7c55 845 } else {
c5c77ba1
JK
846 u8security = u8security | AES;
847 }
848 }
849 }
850
851 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
852
853 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
854 switch (sme->auth_type) {
855 case NL80211_AUTHTYPE_OPEN_SYSTEM:
856 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
857 tenuAuth_type = OPEN_SYSTEM;
858 break;
859
860 case NL80211_AUTHTYPE_SHARED_KEY:
861 tenuAuth_type = SHARED_KEY;
862 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
863 break;
864
865 default:
866 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
867 }
868
c5c77ba1
JK
869 if (sme->crypto.n_akm_suites) {
870 switch (sme->crypto.akm_suites[0]) {
871 case WLAN_AKM_SUITE_8021X:
872 tenuAuth_type = IEEE8021;
873 break;
874
875 default:
876 break;
877 }
878 }
879
880
881 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
882
883 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
884 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
885
866a2c24 886 curr_channel = pstrNetworkInfo->u8channel;
c5c77ba1 887
ab16ec0b 888 if (!pstrWFIDrv->p2p_connect)
0bd8274f 889 wlan_channel = pstrNetworkInfo->u8channel;
c5c77ba1 890
0e1af73d 891 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
c5c77ba1 892
0e1af73d 893 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
c5c77ba1
JK
894 sme->ssid_len, sme->ie, sme->ie_len,
895 CfgConnectResult, (void *)priv, u8security,
896 tenuAuth_type, pstrNetworkInfo->u8channel,
897 pstrNetworkInfo->pJoinParams);
e6e12661 898 if (s32Error != 0) {
0e1af73d 899 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
c5c77ba1
JK
900 s32Error = -ENOENT;
901 goto done;
902 }
903
904done:
905
906 return s32Error;
907}
908
b027cde9 909static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
c5c77ba1 910{
e6e12661 911 s32 s32Error = 0;
2726887c 912 struct wilc_priv *priv;
441dc609 913 struct host_if_drv *pstrWFIDrv;
51e825f7 914 u8 NullBssid[ETH_ALEN] = {0};
8dfaafd6 915
0e1af73d 916 wilc_connecting = 0;
c5c77ba1
JK
917 priv = wiphy_priv(wiphy);
918
441dc609 919 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
ab16ec0b 920 if (!pstrWFIDrv->p2p_connect)
0bd8274f 921 wlan_channel = INVALID_CHANNEL;
0e1af73d 922 wilc_wlan_set_bssid(priv->dev, NullBssid);
c5c77ba1
JK
923
924 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
925
583d972c 926 p2p_local_random = 0x01;
b84a3ac4 927 p2p_recv_random = 0x00;
a25d5186 928 wilc_ie = false;
1229b1ab 929 pstrWFIDrv->p2p_timeout = 0;
c5c77ba1 930
0e1af73d 931 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
e6e12661 932 if (s32Error != 0) {
c5c77ba1
JK
933 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
934 s32Error = -EINVAL;
935 }
936
937 return s32Error;
938}
939
953d417a
CL
940static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
941 bool pairwise,
942 const u8 *mac_addr, struct key_params *params)
c5c77ba1
JK
943
944{
e6e12661 945 s32 s32Error = 0, KeyLen = params->key_len;
4e4467fd 946 u32 i;
2726887c 947 struct wilc_priv *priv;
057d1e97
AB
948 const u8 *pu8RxMic = NULL;
949 const u8 *pu8TxMic = NULL;
63d03e47 950 u8 u8mode = NO_ENCRYPT;
63d03e47
GKH
951 u8 u8gmode = NO_ENCRYPT;
952 u8 u8pmode = NO_ENCRYPT;
841dfc42 953 enum AUTHTYPE tenuAuth_type = ANY;
76469200 954 struct wilc *wl;
a4cac481 955 struct wilc_vif *vif;
c5c77ba1
JK
956
957 priv = wiphy_priv(wiphy);
a4cac481
GL
958 vif = netdev_priv(netdev);
959 wl = vif->wilc;
c5c77ba1
JK
960
961 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
962
8a14330f 963 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
c5c77ba1
JK
964
965 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
966 params->key[1],
967 params->key[2]);
968
969
970 switch (params->cipher) {
971 case WLAN_CIPHER_SUITE_WEP40:
972 case WLAN_CIPHER_SUITE_WEP104:
c5c77ba1 973 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
c5c77ba1
JK
974 priv->WILC_WFI_wep_default = key_index;
975 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
d00d2ba3 976 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
c5c77ba1
JK
977
978 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
979 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
980
981 for (i = 0; i < params->key_len; i++)
982 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
983
984 tenuAuth_type = OPEN_SYSTEM;
985
986 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
987 u8mode = ENCRYPT_ENABLED | WEP;
988 else
989 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
990
0e1af73d 991 wilc_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
c5c77ba1
JK
992 break;
993 }
1a646e7e 994 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
c5c77ba1
JK
995 priv->WILC_WFI_wep_default = key_index;
996 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
d00d2ba3 997 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
c5c77ba1
JK
998
999 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1000 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1001 if (INFO) {
1002 for (i = 0; i < params->key_len; i++)
1003 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1004 }
0e1af73d 1005 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
c5c77ba1
JK
1006 }
1007
1008 break;
1009
1010 case WLAN_CIPHER_SUITE_TKIP:
1011 case WLAN_CIPHER_SUITE_CCMP:
c5c77ba1 1012 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
369a1d3b 1013 if (!priv->wilc_gtk[key_index]) {
f3052587 1014 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
b1413b60
GKH
1015 priv->wilc_gtk[key_index]->key = NULL;
1016 priv->wilc_gtk[key_index]->seq = NULL;
c5c77ba1 1017 }
369a1d3b 1018 if (!priv->wilc_ptk[key_index]) {
f3052587 1019 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
b1413b60
GKH
1020 priv->wilc_ptk[key_index]->key = NULL;
1021 priv->wilc_ptk[key_index]->seq = NULL;
c5c77ba1
JK
1022 }
1023
1024
1025
1913221c 1026 if (!pairwise) {
c5c77ba1
JK
1027 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1028 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1029 else
1030 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1031
1032 priv->wilc_groupkey = u8gmode;
1033
1034 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
1035 pu8TxMic = params->key + 24;
1036 pu8RxMic = params->key + 16;
1037 KeyLen = params->key_len - 16;
1038 }
cccfc39e 1039 kfree(priv->wilc_gtk[key_index]->key);
c5c77ba1 1040
f3052587 1041 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
d00d2ba3 1042 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
cccfc39e 1043 kfree(priv->wilc_gtk[key_index]->seq);
c5c77ba1
JK
1044
1045 if ((params->seq_len) > 0) {
f3052587 1046 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
d00d2ba3 1047 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
c5c77ba1
JK
1048 }
1049
1050 priv->wilc_gtk[key_index]->cipher = params->cipher;
1051 priv->wilc_gtk[key_index]->key_len = params->key_len;
1052 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1053
1054 if (INFO) {
1055 for (i = 0; i < params->key_len; i++)
1056 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1057 for (i = 0; i < params->seq_len; i++)
1058 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1059 }
1060
1061
0e1af73d 1062 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
c5c77ba1
JK
1063 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1064
1065 } else {
1066 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]);
1067
1068 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1069 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1070 else
1071 u8pmode = priv->wilc_groupkey | AES;
1072
1073
1074 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
1075 pu8TxMic = params->key + 24;
1076 pu8RxMic = params->key + 16;
1077 KeyLen = params->key_len - 16;
1078 }
1079
cccfc39e 1080 kfree(priv->wilc_ptk[key_index]->key);
c5c77ba1 1081
f3052587 1082 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
c5c77ba1 1083
cccfc39e 1084 kfree(priv->wilc_ptk[key_index]->seq);
c5c77ba1
JK
1085
1086 if ((params->seq_len) > 0)
f3052587 1087 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba1
JK
1088
1089 if (INFO) {
1090 for (i = 0; i < params->key_len; i++)
1091 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1092
1093 for (i = 0; i < params->seq_len; i++)
1094 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1095 }
1096
d00d2ba3 1097 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
c5c77ba1
JK
1098
1099 if ((params->seq_len) > 0)
d00d2ba3 1100 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
c5c77ba1
JK
1101
1102 priv->wilc_ptk[key_index]->cipher = params->cipher;
1103 priv->wilc_ptk[key_index]->key_len = params->key_len;
1104 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1105
0e1af73d 1106 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
c5c77ba1
JK
1107 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1108 }
1109 break;
1110 }
c5c77ba1
JK
1111
1112 {
1113 u8mode = 0;
1913221c 1114 if (!pairwise) {
c5c77ba1 1115 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
1116 pu8RxMic = params->key + 24;
1117 pu8TxMic = params->key + 16;
1118 KeyLen = params->key_len - 16;
1119 }
1120
1f435d2e 1121 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
c5c77ba1 1122 g_add_gtk_key_params.key_idx = key_index;
c5c77ba1 1123 g_add_gtk_key_params.pairwise = pairwise;
c5c77ba1
JK
1124 if (!mac_addr) {
1125 g_add_gtk_key_params.mac_addr = NULL;
1126 } else {
f3052587 1127 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
c5c77ba1
JK
1128 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1129 }
1130 g_key_gtk_params.key_len = params->key_len;
1131 g_key_gtk_params.seq_len = params->seq_len;
f3052587 1132 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
c5c77ba1
JK
1133 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1134 if (params->seq_len > 0) {
f3052587 1135 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba1
JK
1136 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1137 }
1138 g_key_gtk_params.cipher = params->cipher;
1139
1140 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1141 g_key_gtk_params.key[1],
1142 g_key_gtk_params.key[2]);
72ed4dc7 1143 g_gtk_keys_saved = true;
c5c77ba1
JK
1144 }
1145
0e1af73d 1146 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
c5c77ba1 1147 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
c5c77ba1
JK
1148 } else {
1149 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba1
JK
1150 pu8RxMic = params->key + 24;
1151 pu8TxMic = params->key + 16;
1152 KeyLen = params->key_len - 16;
1153 }
1154
1f435d2e 1155 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
c5c77ba1 1156 g_add_ptk_key_params.key_idx = key_index;
c5c77ba1 1157 g_add_ptk_key_params.pairwise = pairwise;
c5c77ba1
JK
1158 if (!mac_addr) {
1159 g_add_ptk_key_params.mac_addr = NULL;
1160 } else {
f3052587 1161 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
c5c77ba1
JK
1162 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1163 }
1164 g_key_ptk_params.key_len = params->key_len;
1165 g_key_ptk_params.seq_len = params->seq_len;
f3052587 1166 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
c5c77ba1
JK
1167 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1168 if (params->seq_len > 0) {
f3052587 1169 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba1
JK
1170 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1171 }
1172 g_key_ptk_params.cipher = params->cipher;
1173
1174 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1175 g_key_ptk_params.key[1],
1176 g_key_ptk_params.key[2]);
72ed4dc7 1177 g_ptk_keys_saved = true;
c5c77ba1
JK
1178 }
1179
0e1af73d 1180 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
c5c77ba1
JK
1181 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1182 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1183 if (INFO) {
1184 for (i = 0; i < params->key_len; i++)
1185 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1186 }
1187 }
1188 }
1189 break;
1190
1191 default:
1192 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1193 s32Error = -ENOTSUPP;
c5c77ba1
JK
1194 }
1195
1196 return s32Error;
1197}
1198
3044ba7e
CL
1199static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1200 u8 key_index,
1201 bool pairwise,
1202 const u8 *mac_addr)
c5c77ba1 1203{
2726887c 1204 struct wilc_priv *priv;
692e2ace 1205 struct wilc *wl;
a4cac481 1206 struct wilc_vif *vif;
c5c77ba1
JK
1207
1208 priv = wiphy_priv(wiphy);
a4cac481
GL
1209 vif = netdev_priv(netdev);
1210 wl = vif->wilc;
c5c77ba1 1211
1f435d2e 1212 if (netdev == wl->vif[0]->ndev) {
72ed4dc7
DL
1213 g_ptk_keys_saved = false;
1214 g_gtk_keys_saved = false;
1215 g_wep_keys_saved = false;
c5c77ba1 1216
cccfc39e
SB
1217 kfree(g_key_wep_params.key);
1218 g_key_wep_params.key = NULL;
c5c77ba1 1219
c5c77ba1 1220 if ((priv->wilc_gtk[key_index]) != NULL) {
cccfc39e
SB
1221 kfree(priv->wilc_gtk[key_index]->key);
1222 priv->wilc_gtk[key_index]->key = NULL;
1223 kfree(priv->wilc_gtk[key_index]->seq);
1224 priv->wilc_gtk[key_index]->seq = NULL;
c5c77ba1 1225
49188af2 1226 kfree(priv->wilc_gtk[key_index]);
c5c77ba1 1227 priv->wilc_gtk[key_index] = NULL;
c5c77ba1
JK
1228 }
1229
1230 if ((priv->wilc_ptk[key_index]) != NULL) {
cccfc39e
SB
1231 kfree(priv->wilc_ptk[key_index]->key);
1232 priv->wilc_ptk[key_index]->key = NULL;
1233 kfree(priv->wilc_ptk[key_index]->seq);
1234 priv->wilc_ptk[key_index]->seq = NULL;
49188af2 1235 kfree(priv->wilc_ptk[key_index]);
c5c77ba1
JK
1236 priv->wilc_ptk[key_index] = NULL;
1237 }
c5c77ba1 1238
cccfc39e
SB
1239 kfree(g_key_ptk_params.key);
1240 g_key_ptk_params.key = NULL;
1241 kfree(g_key_ptk_params.seq);
1242 g_key_ptk_params.seq = NULL;
1243
1244 kfree(g_key_gtk_params.key);
1245 g_key_gtk_params.key = NULL;
1246 kfree(g_key_gtk_params.seq);
1247 g_key_gtk_params.seq = NULL;
c5c77ba1 1248
0e1af73d 1249 wilc_set_machw_change_vir_if(netdev, false);
c5c77ba1
JK
1250 }
1251
1252 if (key_index >= 0 && key_index <= 3) {
2cc46837 1253 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
c5c77ba1
JK
1254 priv->WILC_WFI_wep_key_len[key_index] = 0;
1255
1256 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
0e1af73d 1257 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
c5c77ba1
JK
1258 } else {
1259 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
0e1af73d 1260 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
c5c77ba1
JK
1261 }
1262
aaed3290 1263 return 0;
c5c77ba1
JK
1264}
1265
f4893dfc
CL
1266static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1267 bool pairwise,
1268 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
c5c77ba1 1269{
2726887c 1270 struct wilc_priv *priv;
c5c77ba1 1271 struct key_params key_params;
4e4467fd 1272 u32 i;
8dfaafd6 1273
c5c77ba1
JK
1274 priv = wiphy_priv(wiphy);
1275
1276
3604af50 1277 if (!pairwise) {
c5c77ba1
JK
1278 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1279
1280 key_params.key = priv->wilc_gtk[key_index]->key;
1281 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1282 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1283 key_params.seq = priv->wilc_gtk[key_index]->seq;
1284 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1285 if (INFO) {
1286 for (i = 0; i < key_params.key_len; i++)
1287 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1288 }
1289 } else {
1290 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1291
1292 key_params.key = priv->wilc_ptk[key_index]->key;
1293 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1294 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1295 key_params.seq = priv->wilc_ptk[key_index]->seq;
1296 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1297 }
1298
1299 callback(cookie, &key_params);
1300
a89f7c55 1301 return 0;
c5c77ba1
JK
1302}
1303
0f5b8ca3
CL
1304static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1305 bool unicast, bool multicast)
c5c77ba1 1306{
2726887c 1307 struct wilc_priv *priv;
c5c77ba1
JK
1308
1309
1310 priv = wiphy_priv(wiphy);
1311
17aacd43 1312 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
c5c77ba1
JK
1313
1314 if (key_index != priv->WILC_WFI_wep_default) {
0e1af73d 1315 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
c5c77ba1
JK
1316 }
1317
aaed3290 1318 return 0;
c5c77ba1
JK
1319}
1320
f06f562d
CL
1321static int get_station(struct wiphy *wiphy, struct net_device *dev,
1322 const u8 *mac, struct station_info *sinfo)
c5c77ba1 1323{
2726887c 1324 struct wilc_priv *priv;
a4cac481 1325 struct wilc_vif *vif;
4e4467fd
CL
1326 u32 i = 0;
1327 u32 associatedsta = 0;
1328 u32 inactive_time = 0;
c5c77ba1 1329 priv = wiphy_priv(wiphy);
a4cac481 1330 vif = netdev_priv(dev);
c5c77ba1 1331
a4cac481 1332 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
c5c77ba1
JK
1333 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1334
1335 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1336
1337 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
c5c77ba1
JK
1338 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1339 associatedsta = i;
1340 break;
1341 }
c5c77ba1
JK
1342 }
1343
1344 if (associatedsta == -1) {
aaed3290
LK
1345 PRINT_ER("Station required is not associated\n");
1346 return -ENOENT;
c5c77ba1
JK
1347 }
1348
c5c77ba1 1349 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
c5c77ba1 1350
0e1af73d 1351 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
c5c77ba1
JK
1352 sinfo->inactive_time = 1000 * inactive_time;
1353 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
c5c77ba1 1354 }
c5c77ba1 1355
a4cac481 1356 if (vif->iftype == STATION_MODE) {
03e7b9c4 1357 struct rf_info strStatistics;
8dfaafd6 1358
0e1af73d 1359 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
c5c77ba1 1360
c5c77ba1 1361 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
6212990a 1362 BIT(NL80211_STA_INFO_RX_PACKETS) |
c5c77ba1
JK
1363 BIT(NL80211_STA_INFO_TX_PACKETS) |
1364 BIT(NL80211_STA_INFO_TX_FAILED) |
1365 BIT(NL80211_STA_INFO_TX_BITRATE);
c5c77ba1 1366
00c8dfcf 1367 sinfo->signal = strStatistics.rssi;
9b99274a 1368 sinfo->rx_packets = strStatistics.rx_cnt;
54160376
LK
1369 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1370 sinfo->tx_failed = strStatistics.tx_fail_cnt;
5babeecb 1371 sinfo->txrate.legacy = strStatistics.link_speed * 10;
c5c77ba1 1372
5babeecb
LK
1373 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1374 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
0e1af73d 1375 wilc_enable_tcp_ack_filter(true);
5babeecb 1376 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
0e1af73d 1377 wilc_enable_tcp_ack_filter(false);
c5c77ba1 1378
c5c77ba1
JK
1379 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1380 sinfo->tx_failed, sinfo->txrate.legacy);
c5c77ba1 1381 }
aaed3290 1382 return 0;
c5c77ba1
JK
1383}
1384
a5f7db6a
CL
1385static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1386 struct bss_parameters *params)
c5c77ba1
JK
1387{
1388 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1389 return 0;
1390}
1391
a76b63ef 1392static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
c5c77ba1 1393{
e6e12661 1394 s32 s32Error = 0;
9529650a 1395 struct cfg_param_val pstrCfgParamVal;
2726887c 1396 struct wilc_priv *priv;
c5c77ba1
JK
1397
1398 priv = wiphy_priv(wiphy);
c5c77ba1 1399
87c05b28 1400 pstrCfgParamVal.flag = 0;
17aacd43 1401 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
c5c77ba1
JK
1402
1403 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1404 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1405 priv->dev->ieee80211_ptr->wiphy->retry_short);
87c05b28 1406 pstrCfgParamVal.flag |= RETRY_SHORT;
c5c77ba1
JK
1407 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1408 }
1409 if (changed & WIPHY_PARAM_RETRY_LONG) {
c5c77ba1 1410 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
87c05b28 1411 pstrCfgParamVal.flag |= RETRY_LONG;
c5c77ba1 1412 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
c5c77ba1
JK
1413 }
1414 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1415 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
87c05b28 1416 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
c5c77ba1 1417 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
c5c77ba1
JK
1418 }
1419
1420 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1421 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1422
87c05b28 1423 pstrCfgParamVal.flag |= RTS_THRESHOLD;
c5c77ba1 1424 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
c5c77ba1
JK
1425 }
1426
1427 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
0e1af73d 1428 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
c5c77ba1
JK
1429 if (s32Error)
1430 PRINT_ER("Error in setting WIPHY PARAMS\n");
1431
1432
1433 return s32Error;
1434}
e5af0561 1435
4d46657a
CL
1436static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1437 struct cfg80211_pmksa *pmksa)
c5c77ba1 1438{
4e4467fd 1439 u32 i;
e6e12661 1440 s32 s32Error = 0;
63d03e47 1441 u8 flag = 0;
c5c77ba1 1442
2726887c 1443 struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba1
JK
1444
1445 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1446
1447
1448 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1a646e7e 1449 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba1 1450 ETH_ALEN)) {
c5c77ba1
JK
1451 flag = PMKID_FOUND;
1452 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1453 break;
1454 }
1455 }
1456 if (i < WILC_MAX_NUM_PMKIDS) {
1457 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
d00d2ba3 1458 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
c5c77ba1 1459 ETH_ALEN);
d00d2ba3 1460 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
c5c77ba1
JK
1461 PMKID_LEN);
1462 if (!(flag == PMKID_FOUND))
1463 priv->pmkid_list.numpmkid++;
1464 } else {
1465 PRINT_ER("Invalid PMKID index\n");
1466 s32Error = -EINVAL;
1467 }
1468
1469 if (!s32Error) {
1470 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
0e1af73d 1471 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
c5c77ba1
JK
1472 }
1473 return s32Error;
1474}
1475
1ff86d96
CL
1476static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1477 struct cfg80211_pmksa *pmksa)
c5c77ba1 1478{
4e4467fd 1479 u32 i;
e6e12661 1480 s32 s32Error = 0;
c5c77ba1 1481
2726887c 1482 struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba1
JK
1483
1484 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1485
1486 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1a646e7e 1487 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba1 1488 ETH_ALEN)) {
c5c77ba1 1489 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
cd1e6cb4 1490 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
c5c77ba1
JK
1491 break;
1492 }
1493 }
1494
1495 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1496 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
d00d2ba3 1497 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba1
JK
1498 priv->pmkid_list.pmkidlist[i + 1].bssid,
1499 ETH_ALEN);
d00d2ba3 1500 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
c5c77ba1
JK
1501 priv->pmkid_list.pmkidlist[i].pmkid,
1502 PMKID_LEN);
1503 }
1504 priv->pmkid_list.numpmkid--;
1505 } else {
1506 s32Error = -EINVAL;
1507 }
1508
1509 return s32Error;
1510}
1511
b33c39b1 1512static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
c5c77ba1 1513{
2726887c 1514 struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba1
JK
1515
1516 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1517
a949f909 1518 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
c5c77ba1
JK
1519
1520 return 0;
1521}
c5c77ba1 1522
1608c403 1523static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
c5c77ba1 1524{
4e4467fd
CL
1525 u32 index = 0;
1526 u32 i = 0, j = 0;
c5c77ba1 1527
63d03e47
GKH
1528 u8 op_channel_attr_index = 0;
1529 u8 channel_list_attr_index = 0;
c5c77ba1
JK
1530
1531 while (index < len) {
1532 if (buf[index] == GO_INTENT_ATTR_ID) {
c5c77ba1 1533 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
c5c77ba1
JK
1534 }
1535
78174ada 1536 if (buf[index] == CHANLIST_ATTR_ID)
c5c77ba1 1537 channel_list_attr_index = index;
78174ada 1538 else if (buf[index] == OPERCHAN_ATTR_ID)
c5c77ba1 1539 op_channel_attr_index = index;
a89f7c55 1540 index += buf[index + 1] + 3;
c5c77ba1 1541 }
0bd8274f 1542 if (wlan_channel != INVALID_CHANNEL) {
c5c77ba1
JK
1543 if (channel_list_attr_index) {
1544 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1545 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1546 if (buf[i] == 0x51) {
1547 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
0bd8274f 1548 buf[j] = wlan_channel;
c5c77ba1
JK
1549 }
1550 break;
1551 }
1552 }
1553 }
a89f7c55 1554
c5c77ba1
JK
1555 if (op_channel_attr_index) {
1556 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1557 buf[op_channel_attr_index + 6] = 0x51;
0bd8274f 1558 buf[op_channel_attr_index + 7] = wlan_channel;
c5c77ba1
JK
1559 }
1560 }
1561}
1562
1608c403 1563static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
c5c77ba1 1564{
4e4467fd
CL
1565 u32 index = 0;
1566 u32 i = 0, j = 0;
c5c77ba1 1567
63d03e47
GKH
1568 u8 op_channel_attr_index = 0;
1569 u8 channel_list_attr_index = 0;
c5c77ba1
JK
1570
1571 while (index < len) {
c5c77ba1 1572 if (buf[index] == GO_INTENT_ATTR_ID) {
c5c77ba1 1573 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
c5c77ba1
JK
1574
1575 break;
1576 }
c5c77ba1 1577
78174ada 1578 if (buf[index] == CHANLIST_ATTR_ID)
c5c77ba1 1579 channel_list_attr_index = index;
78174ada 1580 else if (buf[index] == OPERCHAN_ATTR_ID)
c5c77ba1 1581 op_channel_attr_index = index;
a89f7c55 1582 index += buf[index + 1] + 3;
c5c77ba1 1583 }
0bd8274f 1584 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
c5c77ba1
JK
1585 if (channel_list_attr_index) {
1586 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1587 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1588 if (buf[i] == 0x51) {
1589 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
0bd8274f 1590 buf[j] = wlan_channel;
c5c77ba1
JK
1591 }
1592 break;
1593 }
1594 }
1595 }
a89f7c55 1596
c5c77ba1
JK
1597 if (op_channel_attr_index) {
1598 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1599 buf[op_channel_attr_index + 6] = 0x51;
0bd8274f 1600 buf[op_channel_attr_index + 7] = wlan_channel;
c5c77ba1
JK
1601 }
1602 }
1603}
1604
fbc2fe16 1605void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
c5c77ba1 1606{
2726887c 1607 struct wilc_priv *priv;
4e4467fd 1608 u32 header, pkt_offset;
441dc609 1609 struct host_if_drv *pstrWFIDrv;
4e4467fd 1610 u32 i = 0;
fb4ec9ca 1611 s32 s32Freq;
8dfaafd6 1612
c5c77ba1 1613 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
441dc609 1614 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1 1615
d00d2ba3 1616 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
c5c77ba1 1617
c5c77ba1
JK
1618 pkt_offset = GET_PKT_OFFSET(header);
1619
1620 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1621 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1622 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
c5c77ba1 1623 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
c5c77ba1
JK
1624 return;
1625 } else {
1626 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1627 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],
1628 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
c5c77ba1 1629 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
c5c77ba1
JK
1630 } else {
1631 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],
1632 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
c5c77ba1 1633 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
c5c77ba1
JK
1634 }
1635 return;
1636 }
1637 } else {
c5c77ba1
JK
1638 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1639
866a2c24 1640 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
c5c77ba1
JK
1641
1642 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1643 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1644
1229b1ab 1645 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
c5c77ba1
JK
1646 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1647 return;
1648 }
1649 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
c5c77ba1
JK
1650 switch (buff[ACTION_SUBTYPE_ID]) {
1651 case GAS_INTIAL_REQ:
1652 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1653 break;
1654
1655 case GAS_INTIAL_RSP:
1656 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1657 break;
1658
1659 case PUBLIC_ACT_VENDORSPEC:
881eb5d8 1660 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
c5c77ba1 1661 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
a25d5186 1662 if (!wilc_ie) {
c5c77ba1 1663 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
8668594a 1664 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
b84a3ac4 1665 p2p_recv_random = buff[i + 6];
a25d5186 1666 wilc_ie = true;
b84a3ac4 1667 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
c5c77ba1
JK
1668 break;
1669 }
1670 }
1671 }
1672 }
b84a3ac4 1673 if (p2p_local_random > p2p_recv_random) {
c5c77ba1
JK
1674 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1675 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1676 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
881eb5d8 1677 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
c5c77ba1
JK
1678 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1679 break;
1680 }
1681 }
1682 }
583d972c 1683 } else {
b84a3ac4 1684 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
583d972c 1685 }
c5c77ba1
JK
1686 }
1687
1688
a25d5186 1689 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
c5c77ba1 1690 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
c5c77ba1 1691 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
c5c77ba1
JK
1692 return;
1693 }
1694 break;
1695
1696 default:
1697 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1698 break;
1699 }
1700 }
1701 }
1702
c5c77ba1 1703 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
c5c77ba1
JK
1704 }
1705}
1706
c5c77ba1
JK
1707static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1708{
1709 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1710
1711
1712 kfree(pv_data->buff);
1713 kfree(pv_data);
1714}
1715
c5c77ba1
JK
1716static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1717{
2726887c 1718 struct wilc_priv *priv;
8dfaafd6 1719
2726887c 1720 priv = (struct wilc_priv *)pUserVoid;
c5c77ba1 1721
17aacd43 1722 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
c5c77ba1 1723
72ed4dc7 1724 priv->bInP2PlistenState = true;
c5c77ba1 1725
c5c77ba1
JK
1726 cfg80211_ready_on_channel(priv->wdev,
1727 priv->strRemainOnChanParams.u64ListenCookie,
1728 priv->strRemainOnChanParams.pstrListenChan,
1729 priv->strRemainOnChanParams.u32ListenDuration,
1730 GFP_KERNEL);
c5c77ba1
JK
1731}
1732
4e4467fd 1733static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
c5c77ba1 1734{
2726887c 1735 struct wilc_priv *priv;
8dfaafd6 1736
2726887c 1737 priv = (struct wilc_priv *)pUserVoid;
c5c77ba1 1738
c5c77ba1 1739 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
17aacd43 1740 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
c5c77ba1 1741
72ed4dc7 1742 priv->bInP2PlistenState = false;
c5c77ba1 1743
c5c77ba1
JK
1744 cfg80211_remain_on_channel_expired(priv->wdev,
1745 priv->strRemainOnChanParams.u64ListenCookie,
1746 priv->strRemainOnChanParams.pstrListenChan,
1747 GFP_KERNEL);
c5c77ba1
JK
1748 } else {
1749 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
1750 , priv->strRemainOnChanParams.u32ListenSessionID);
1751 }
1752}
1753
6d19d695
CL
1754static int remain_on_channel(struct wiphy *wiphy,
1755 struct wireless_dev *wdev,
1756 struct ieee80211_channel *chan,
1757 unsigned int duration, u64 *cookie)
c5c77ba1 1758{
e6e12661 1759 s32 s32Error = 0;
2726887c 1760 struct wilc_priv *priv;
8dfaafd6 1761
c5c77ba1
JK
1762 priv = wiphy_priv(wiphy);
1763
1764 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
1765
c5c77ba1 1766
c5c77ba1
JK
1767 if (wdev->iftype == NL80211_IFTYPE_AP) {
1768 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
1769 return s32Error;
1770 }
c5c77ba1 1771
866a2c24 1772 curr_channel = chan->hw_value;
c5c77ba1 1773
c5c77ba1
JK
1774 priv->strRemainOnChanParams.pstrListenChan = chan;
1775 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
c5c77ba1
JK
1776 priv->strRemainOnChanParams.u32ListenDuration = duration;
1777 priv->strRemainOnChanParams.u32ListenSessionID++;
1778
0e1af73d 1779 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
c5c77ba1
JK
1780 , priv->strRemainOnChanParams.u32ListenSessionID
1781 , duration
1782 , chan->hw_value
1783 , WILC_WFI_RemainOnChannelExpired
1784 , WILC_WFI_RemainOnChannelReady
1785 , (void *)priv);
1786
1787 return s32Error;
1788}
1789
1dd5440b
CL
1790static int cancel_remain_on_channel(struct wiphy *wiphy,
1791 struct wireless_dev *wdev,
1792 u64 cookie)
c5c77ba1 1793{
e6e12661 1794 s32 s32Error = 0;
2726887c 1795 struct wilc_priv *priv;
8dfaafd6 1796
c5c77ba1
JK
1797 priv = wiphy_priv(wiphy);
1798
1799 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1800
0e1af73d 1801 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
c5c77ba1
JK
1802 return s32Error;
1803}
a89f7c55 1804
c156032d
CL
1805static int mgmt_tx(struct wiphy *wiphy,
1806 struct wireless_dev *wdev,
1807 struct cfg80211_mgmt_tx_params *params,
1808 u64 *cookie)
c5c77ba1 1809{
c5c77ba1
JK
1810 struct ieee80211_channel *chan = params->chan;
1811 unsigned int wait = params->wait;
1812 const u8 *buf = params->buf;
1813 size_t len = params->len;
c5c77ba1
JK
1814 const struct ieee80211_mgmt *mgmt;
1815 struct p2p_mgmt_data *mgmt_tx;
2726887c 1816 struct wilc_priv *priv;
441dc609 1817 struct host_if_drv *pstrWFIDrv;
4e4467fd 1818 u32 i;
a4cac481 1819 struct wilc_vif *vif;
8668594a 1820 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
c5c77ba1 1821
a4cac481 1822 vif = netdev_priv(wdev->netdev);
c5c77ba1 1823 priv = wiphy_priv(wiphy);
441dc609 1824 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1
JK
1825
1826 *cookie = (unsigned long)buf;
1827 priv->u64tx_cookie = *cookie;
1828 mgmt = (const struct ieee80211_mgmt *) buf;
1829
1830 if (ieee80211_is_mgmt(mgmt->frame_control)) {
f3052587 1831 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
369a1d3b 1832 if (!mgmt_tx) {
c5c77ba1 1833 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
e6e12661 1834 return -EFAULT;
c5c77ba1 1835 }
f3052587 1836 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
369a1d3b 1837 if (!mgmt_tx->buff) {
c5c77ba1 1838 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
f638dd39 1839 kfree(mgmt_tx);
e6e12661 1840 return -EFAULT;
c5c77ba1 1841 }
d00d2ba3 1842 memcpy(mgmt_tx->buff, buf, len);
c5c77ba1
JK
1843 mgmt_tx->size = len;
1844
1845
1846 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1847 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
1848 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
0e1af73d 1849 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
866a2c24 1850 curr_channel = chan->hw_value;
c5c77ba1 1851 } else if (ieee80211_is_action(mgmt->frame_control)) {
d85f5326 1852 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
c5c77ba1
JK
1853
1854
c5c77ba1 1855 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
c5c77ba1
JK
1856 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1857 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1858 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
0e1af73d 1859 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
866a2c24 1860 curr_channel = chan->hw_value;
c5c77ba1
JK
1861 }
1862 switch (buf[ACTION_SUBTYPE_ID]) {
1863 case GAS_INTIAL_REQ:
1864 {
1865 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
1866 break;
1867 }
1868
1869 case GAS_INTIAL_RSP:
1870 {
1871 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
1872 break;
1873 }
1874
1875 case PUBLIC_ACT_VENDORSPEC:
1876 {
881eb5d8 1877 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
c5c77ba1 1878 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
b84a3ac4 1879 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
583d972c
LK
1880 get_random_bytes(&p2p_local_random, 1);
1881 p2p_local_random++;
c5c77ba1
JK
1882 }
1883 }
1884
1885 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1886 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
b84a3ac4
LK
1887 if (p2p_local_random > p2p_recv_random) {
1888 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
c5c77ba1 1889
c5c77ba1 1890 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
881eb5d8 1891 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
c5c77ba1 1892 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
a4cac481 1893 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
c5c77ba1 1894 else
a4cac481 1895 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
c5c77ba1
JK
1896 break;
1897 }
1898 }
1899
1900 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
8668594a
LK
1901 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1902 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
c5c77ba1
JK
1903 mgmt_tx->size = buf_len;
1904 }
583d972c 1905 } else {
b84a3ac4 1906 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
583d972c 1907 }
c5c77ba1
JK
1908 }
1909
1910 } else {
1911 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
1912 }
1913
1914 break;
1915 }
1916
1917 default:
1918 {
1919 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1920 break;
1921 }
1922 }
c5c77ba1
JK
1923 }
1924
1925 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
1229b1ab 1926 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
c5c77ba1 1927
1229b1ab
LK
1928 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
1929 jiffies, pstrWFIDrv->p2p_timeout);
c5c77ba1
JK
1930 }
1931
829c477f
GL
1932 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1933 mgmt_tx->buff, mgmt_tx->size,
c9d4834d 1934 WILC_WFI_mgmt_tx_complete);
c5c77ba1
JK
1935 } else {
1936 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
1937 }
aaed3290 1938 return 0;
c5c77ba1
JK
1939}
1940
85c587a5
CL
1941static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1942 struct wireless_dev *wdev,
1943 u64 cookie)
c5c77ba1 1944{
2726887c 1945 struct wilc_priv *priv;
441dc609 1946 struct host_if_drv *pstrWFIDrv;
8dfaafd6 1947
c5c77ba1 1948 priv = wiphy_priv(wiphy);
441dc609 1949 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1
JK
1950
1951
1952 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
1229b1ab 1953 pstrWFIDrv->p2p_timeout = jiffies;
c5c77ba1 1954
7e4e87d3 1955 if (!priv->bInP2PlistenState) {
c5c77ba1
JK
1956 cfg80211_remain_on_channel_expired(priv->wdev,
1957 priv->strRemainOnChanParams.u64ListenCookie,
1958 priv->strRemainOnChanParams.pstrListenChan,
1959 GFP_KERNEL);
c5c77ba1
JK
1960 }
1961
1962 return 0;
1963}
1964
8e0735c5
CL
1965void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1966 u16 frame_type, bool reg)
c5c77ba1 1967{
2726887c 1968 struct wilc_priv *priv;
a4cac481 1969 struct wilc_vif *vif;
1b86935e 1970 struct wilc *wl;
c5c77ba1
JK
1971
1972 priv = wiphy_priv(wiphy);
a4cac481
GL
1973 vif = netdev_priv(priv->wdev->netdev);
1974 wl = vif->wilc;
c5c77ba1 1975
c5c77ba1
JK
1976 if (!frame_type)
1977 return;
1978
1979 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
1980 switch (frame_type) {
1981 case PROBE_REQ:
1982 {
a4cac481
GL
1983 vif->g_struct_frame_reg[0].frame_type = frame_type;
1984 vif->g_struct_frame_reg[0].reg = reg;
c5c77ba1
JK
1985 }
1986 break;
1987
1988 case ACTION:
1989 {
a4cac481
GL
1990 vif->g_struct_frame_reg[1].frame_type = frame_type;
1991 vif->g_struct_frame_reg[1].reg = reg;
c5c77ba1
JK
1992 }
1993 break;
1994
1995 default:
1996 {
1997 break;
1998 }
c5c77ba1 1999 }
a89f7c55 2000
1b86935e 2001 if (!wl->initialized) {
c5c77ba1
JK
2002 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2003 return;
2004 }
0e1af73d 2005 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
c5c77ba1 2006}
c5c77ba1 2007
a8047e26
CL
2008static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2009 s32 rssi_thold, u32 rssi_hyst)
c5c77ba1
JK
2010{
2011 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2012 return 0;
c5c77ba1 2013}
a89f7c55 2014
bdb6338f
CL
2015static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2016 int idx, u8 *mac, struct station_info *sinfo)
c5c77ba1 2017{
2726887c 2018 struct wilc_priv *priv;
8dfaafd6 2019
c5c77ba1
JK
2020 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2021
2022 if (idx != 0)
2023 return -ENOENT;
2024
2025 priv = wiphy_priv(wiphy);
c5c77ba1 2026
c5c77ba1 2027 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
c5c77ba1 2028
0e1af73d 2029 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
c5c77ba1 2030
c5c77ba1 2031 return 0;
c5c77ba1
JK
2032}
2033
46530679
CL
2034static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2035 bool enabled, int timeout)
c5c77ba1 2036{
2726887c 2037 struct wilc_priv *priv;
8dfaafd6 2038
c5c77ba1
JK
2039 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2040
369a1d3b 2041 if (!wiphy)
c5c77ba1
JK
2042 return -ENOENT;
2043
2044 priv = wiphy_priv(wiphy);
369a1d3b 2045 if (!priv->hWILCWFIDrv) {
c5c77ba1
JK
2046 PRINT_ER("Driver is NULL\n");
2047 return -EIO;
2048 }
2049
0e1af73d
AB
2050 if (wilc_enable_ps)
2051 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
c5c77ba1
JK
2052
2053
e6e12661 2054 return 0;
c5c77ba1 2055}
108b3439 2056
3615e9a3
CL
2057static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2058 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
c5c77ba1 2059{
2726887c 2060 struct wilc_priv *priv;
a4cac481 2061 struct wilc_vif *vif;
63d03e47 2062 u8 interface_type;
d85f5326 2063 u16 TID = 0;
63d03e47 2064 u8 i;
299382cf 2065 struct wilc *wl;
c5c77ba1 2066
a4cac481 2067 vif = netdev_priv(dev);
c5c77ba1 2068 priv = wiphy_priv(wiphy);
a4cac481 2069 wl = vif->wilc;
c5c77ba1
JK
2070
2071 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2072 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
583d972c 2073 p2p_local_random = 0x01;
b84a3ac4 2074 p2p_recv_random = 0x00;
a25d5186 2075 wilc_ie = false;
0e1af73d
AB
2076 wilc_optaining_ip = false;
2077 del_timer(&wilc_during_ip_timer);
c5c77ba1 2078 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
a89f7c55 2079
c5c77ba1 2080 if (g_ptk_keys_saved && g_gtk_keys_saved) {
0e1af73d 2081 wilc_set_machw_change_vir_if(dev, true);
c5c77ba1
JK
2082 }
2083
2084 switch (type) {
2085 case NL80211_IFTYPE_STATION:
0e1af73d 2086 wilc_connecting = 0;
c5c77ba1 2087 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
c5c77ba1 2088
c5c77ba1
JK
2089 dev->ieee80211_ptr->iftype = type;
2090 priv->wdev->iftype = type;
a4cac481
GL
2091 vif->monitor_flag = 0;
2092 vif->iftype = STATION_MODE;
c5c77ba1 2093
c5c77ba1 2094 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
a4cac481
GL
2095 interface_type = vif->iftype;
2096 vif->iftype = STATION_MODE;
c5c77ba1 2097
299382cf 2098 if (wl->initialized) {
0e1af73d 2099 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
1f435d2e 2100 wl->vif[0]->bssid, TID);
0e1af73d 2101 wilc_wait_msg_queue_idle();
c5c77ba1 2102
299382cf 2103 up(&wl->cfg_event);
c5c77ba1 2104
53dc0cfe 2105 wilc1000_wlan_deinit(dev);
a4cac481 2106 wilc1000_wlan_init(dev, vif);
0e1af73d 2107 wilc_initialized = 1;
a4cac481 2108 vif->iftype = interface_type;
c5c77ba1 2109
1f435d2e
GL
2110 wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv);
2111 wilc_set_mac_address(wl->vif[0]->hif_drv,
2112 wl->vif[0]->src_addr);
0e1af73d 2113 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
c5c77ba1 2114
c5c77ba1 2115 if (g_wep_keys_saved) {
1f435d2e 2116 wilc_set_wep_default_keyid(wl->vif[0]->hif_drv,
c5c77ba1 2117 g_key_wep_params.key_idx);
1f435d2e 2118 wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv,
c5c77ba1
JK
2119 g_key_wep_params.key,
2120 g_key_wep_params.key_len,
2121 g_key_wep_params.key_idx);
2122 }
2123
0e1af73d 2124 wilc_flush_join_req(priv->hWILCWFIDrv);
c5c77ba1 2125
c5c77ba1
JK
2126 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2127 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2128 g_key_ptk_params.key[1],
2129 g_key_ptk_params.key[2]);
2130 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2131 g_key_gtk_params.key[1],
2132 g_key_gtk_params.key[2]);
1f435d2e
GL
2133 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2134 wl->vif[0]->ndev,
953d417a
CL
2135 g_add_ptk_key_params.key_idx,
2136 g_add_ptk_key_params.pairwise,
2137 g_add_ptk_key_params.mac_addr,
2138 (struct key_params *)(&g_key_ptk_params));
2139
1f435d2e
GL
2140 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2141 wl->vif[0]->ndev,
953d417a
CL
2142 g_add_gtk_key_params.key_idx,
2143 g_add_gtk_key_params.pairwise,
2144 g_add_gtk_key_params.mac_addr,
2145 (struct key_params *)(&g_key_gtk_params));
c5c77ba1
JK
2146 }
2147
299382cf 2148 if (wl->initialized) {
c5c77ba1 2149 for (i = 0; i < num_reg_frame; i++) {
a4cac481
GL
2150 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2151 vif->g_struct_frame_reg[i].reg);
0e1af73d 2152 wilc_frame_register(priv->hWILCWFIDrv,
a4cac481
GL
2153 vif->g_struct_frame_reg[i].frame_type,
2154 vif->g_struct_frame_reg[i].reg);
c5c77ba1
JK
2155 }
2156 }
2157
0e1af73d
AB
2158 wilc_enable_ps = true;
2159 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
c5c77ba1 2160 }
c5c77ba1
JK
2161 break;
2162
2163 case NL80211_IFTYPE_P2P_CLIENT:
0e1af73d
AB
2164 wilc_enable_ps = false;
2165 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2166 wilc_connecting = 0;
c5c77ba1 2167 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
c5c77ba1 2168
0e1af73d 2169 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
1f435d2e 2170 wl->vif[0]->bssid, TID);
c5c77ba1
JK
2171
2172 dev->ieee80211_ptr->iftype = type;
2173 priv->wdev->iftype = type;
a4cac481 2174 vif->monitor_flag = 0;
c5c77ba1 2175
c5c77ba1 2176 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
a4cac481 2177 vif->iftype = CLIENT_MODE;
c5c77ba1
JK
2178
2179
299382cf 2180 if (wl->initialized) {
0e1af73d 2181 wilc_wait_msg_queue_idle();
c5c77ba1 2182
53dc0cfe 2183 wilc1000_wlan_deinit(dev);
a4cac481 2184 wilc1000_wlan_init(dev, vif);
0e1af73d 2185 wilc_initialized = 1;
c5c77ba1 2186
1f435d2e
GL
2187 wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv);
2188 wilc_set_mac_address(wl->vif[0]->hif_drv,
2189 wl->vif[0]->src_addr);
0e1af73d 2190 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
c5c77ba1 2191
c5c77ba1 2192 if (g_wep_keys_saved) {
1f435d2e 2193 wilc_set_wep_default_keyid(wl->vif[0]->hif_drv,
0e1af73d 2194 g_key_wep_params.key_idx);
1f435d2e 2195 wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv,
0e1af73d
AB
2196 g_key_wep_params.key,
2197 g_key_wep_params.key_len,
2198 g_key_wep_params.key_idx);
c5c77ba1
JK
2199 }
2200
0e1af73d 2201 wilc_flush_join_req(priv->hWILCWFIDrv);
c5c77ba1 2202
c5c77ba1
JK
2203 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2204 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2205 g_key_ptk_params.key[1],
2206 g_key_ptk_params.key[2]);
2207 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2208 g_key_gtk_params.key[1],
2209 g_key_gtk_params.key[2]);
1f435d2e
GL
2210 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2211 wl->vif[0]->ndev,
953d417a
CL
2212 g_add_ptk_key_params.key_idx,
2213 g_add_ptk_key_params.pairwise,
2214 g_add_ptk_key_params.mac_addr,
2215 (struct key_params *)(&g_key_ptk_params));
2216
1f435d2e
GL
2217 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2218 wl->vif[0]->ndev,
953d417a
CL
2219 g_add_gtk_key_params.key_idx,
2220 g_add_gtk_key_params.pairwise,
2221 g_add_gtk_key_params.mac_addr,
2222 (struct key_params *)(&g_key_gtk_params));
c5c77ba1
JK
2223 }
2224
72ed4dc7 2225 refresh_scan(priv, 1, true);
0e1af73d 2226 wilc_set_machw_change_vir_if(dev, false);
c5c77ba1 2227
299382cf 2228 if (wl->initialized) {
c5c77ba1 2229 for (i = 0; i < num_reg_frame; i++) {
a4cac481
GL
2230 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2231 vif->g_struct_frame_reg[i].reg);
0e1af73d 2232 wilc_frame_register(priv->hWILCWFIDrv,
a4cac481
GL
2233 vif->g_struct_frame_reg[i].frame_type,
2234 vif->g_struct_frame_reg[i].reg);
c5c77ba1
JK
2235 }
2236 }
2237 }
c5c77ba1
JK
2238 break;
2239
2240 case NL80211_IFTYPE_AP:
0e1af73d 2241 wilc_enable_ps = false;
c5c77ba1 2242 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
c5c77ba1
JK
2243 dev->ieee80211_ptr->iftype = type;
2244 priv->wdev->iftype = type;
a4cac481 2245 vif->iftype = AP_MODE;
8a14330f 2246 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
c5c77ba1 2247
c5c77ba1 2248 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
0e1af73d 2249 wilc_wlan_get_firmware(dev);
a89f7c55 2250
299382cf 2251 if (wl->initialized) {
a4cac481 2252 vif->iftype = AP_MODE;
0e1af73d
AB
2253 wilc_mac_close(dev);
2254 wilc_mac_open(dev);
c5c77ba1 2255
c5c77ba1 2256 for (i = 0; i < num_reg_frame; i++) {
a4cac481
GL
2257 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2258 vif->g_struct_frame_reg[i].reg);
0e1af73d 2259 wilc_frame_register(priv->hWILCWFIDrv,
a4cac481
GL
2260 vif->g_struct_frame_reg[i].frame_type,
2261 vif->g_struct_frame_reg[i].reg);
c5c77ba1
JK
2262 }
2263 }
c5c77ba1
JK
2264 break;
2265
2266 case NL80211_IFTYPE_P2P_GO:
2267 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2268
0e1af73d 2269 wilc_optaining_ip = true;
7e872df9
LK
2270 mod_timer(&wilc_during_ip_timer,
2271 jiffies + msecs_to_jiffies(during_ip_time));
0e1af73d 2272 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
0e1af73d 2273 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
1f435d2e 2274 wl->vif[0]->bssid, TID);
0e1af73d 2275 wilc_enable_ps = false;
c5c77ba1 2276 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
c5c77ba1
JK
2277 dev->ieee80211_ptr->iftype = type;
2278 priv->wdev->iftype = type;
2279
8a14330f 2280 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
c5c77ba1 2281
c5c77ba1
JK
2282 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2283
2284
a4cac481 2285 vif->iftype = GO_MODE;
c5c77ba1 2286
0e1af73d 2287 wilc_wait_msg_queue_idle();
53dc0cfe 2288 wilc1000_wlan_deinit(dev);
a4cac481 2289 wilc1000_wlan_init(dev, vif);
0e1af73d 2290 wilc_initialized = 1;
c5c77ba1 2291
1f435d2e
GL
2292 wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv);
2293 wilc_set_mac_address(wl->vif[0]->hif_drv,
2294 wl->vif[0]->src_addr);
0e1af73d 2295 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
c5c77ba1 2296
c5c77ba1 2297 if (g_wep_keys_saved) {
1f435d2e 2298 wilc_set_wep_default_keyid(wl->vif[0]->hif_drv,
0e1af73d 2299 g_key_wep_params.key_idx);
1f435d2e 2300 wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv,
c5c77ba1
JK
2301 g_key_wep_params.key,
2302 g_key_wep_params.key_len,
2303 g_key_wep_params.key_idx);
2304 }
2305
0e1af73d 2306 wilc_flush_join_req(priv->hWILCWFIDrv);
c5c77ba1 2307
c5c77ba1
JK
2308 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2309 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2310 g_key_ptk_params.key[1],
2311 g_key_ptk_params.key[2],
2312 g_key_ptk_params.cipher);
2313 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2314 g_key_gtk_params.key[1],
2315 g_key_gtk_params.key[2],
2316 g_key_gtk_params.cipher);
1f435d2e
GL
2317 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2318 wl->vif[0]->ndev,
953d417a
CL
2319 g_add_ptk_key_params.key_idx,
2320 g_add_ptk_key_params.pairwise,
2321 g_add_ptk_key_params.mac_addr,
2322 (struct key_params *)(&g_key_ptk_params));
2323
1f435d2e
GL
2324 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2325 wl->vif[0]->ndev,
953d417a
CL
2326 g_add_gtk_key_params.key_idx,
2327 g_add_gtk_key_params.pairwise,
2328 g_add_gtk_key_params.mac_addr,
2329 (struct key_params *)(&g_key_gtk_params));
c5c77ba1 2330 }
c5c77ba1 2331
299382cf 2332 if (wl->initialized) {
c5c77ba1 2333 for (i = 0; i < num_reg_frame; i++) {
a4cac481
GL
2334 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2335 vif->g_struct_frame_reg[i].reg);
0e1af73d 2336 wilc_frame_register(priv->hWILCWFIDrv,
a4cac481
GL
2337 vif->g_struct_frame_reg[i].frame_type,
2338 vif->g_struct_frame_reg[i].reg);
c5c77ba1
JK
2339 }
2340 }
c5c77ba1
JK
2341 break;
2342
2343 default:
2344 PRINT_ER("Unknown interface type= %d\n", type);
aaed3290 2345 return -EINVAL;
c5c77ba1
JK
2346 }
2347
aaed3290 2348 return 0;
c5c77ba1
JK
2349}
2350
a13168d7
CL
2351static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2352 struct cfg80211_ap_settings *settings)
c5c77ba1
JK
2353{
2354 struct cfg80211_beacon_data *beacon = &(settings->beacon);
2726887c 2355 struct wilc_priv *priv;
e6e12661 2356 s32 s32Error = 0;
684dc186 2357 struct wilc *wl;
a4cac481 2358 struct wilc_vif *vif;
c5c77ba1
JK
2359
2360 priv = wiphy_priv(wiphy);
a4cac481
GL
2361 vif = netdev_priv(dev);
2362 wl = vif ->wilc;
c5c77ba1
JK
2363 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2364
17aacd43 2365 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
c5c77ba1
JK
2366 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2367
80785a9a 2368 s32Error = set_channel(wiphy, &settings->chandef);
c5c77ba1 2369
e6e12661 2370 if (s32Error != 0)
c5c77ba1 2371 PRINT_ER("Error in setting channel\n");
c5c77ba1 2372
1f435d2e 2373 wilc_wlan_set_bssid(dev, wl->vif[0]->src_addr);
c5c77ba1 2374
0e1af73d 2375 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
c5c77ba1
JK
2376 settings->beacon_interval,
2377 settings->dtim_period,
63d03e47
GKH
2378 beacon->head_len, (u8 *)beacon->head,
2379 beacon->tail_len, (u8 *)beacon->tail);
c5c77ba1
JK
2380
2381 return s32Error;
2382}
2383
2a4c84d7
CL
2384static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2385 struct cfg80211_beacon_data *beacon)
c5c77ba1 2386{
2726887c 2387 struct wilc_priv *priv;
e6e12661 2388 s32 s32Error = 0;
c5c77ba1
JK
2389
2390 priv = wiphy_priv(wiphy);
2391 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2392
2393
0e1af73d 2394 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
c5c77ba1
JK
2395 0,
2396 0,
63d03e47
GKH
2397 beacon->head_len, (u8 *)beacon->head,
2398 beacon->tail_len, (u8 *)beacon->tail);
c5c77ba1
JK
2399
2400 return s32Error;
2401}
2402
c8cddd79 2403static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
c5c77ba1 2404{
e6e12661 2405 s32 s32Error = 0;
2726887c 2406 struct wilc_priv *priv;
63d03e47 2407 u8 NullBssid[ETH_ALEN] = {0};
c5c77ba1 2408
7ae43363
LK
2409 if (!wiphy)
2410 return -EFAULT;
c5c77ba1
JK
2411
2412 priv = wiphy_priv(wiphy);
2413
2414 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2415
0e1af73d 2416 wilc_wlan_set_bssid(dev, NullBssid);
c5c77ba1 2417
0e1af73d 2418 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
c5c77ba1 2419
7dc1d0cc
LK
2420 if (s32Error)
2421 PRINT_ER("Host delete beacon fail\n");
c5c77ba1 2422
c5c77ba1
JK
2423 return s32Error;
2424}
2425
ed26955c
CL
2426static int add_station(struct wiphy *wiphy, struct net_device *dev,
2427 const u8 *mac, struct station_parameters *params)
c5c77ba1 2428{
e6e12661 2429 s32 s32Error = 0;
2726887c 2430 struct wilc_priv *priv;
6a89ba9c 2431 struct add_sta_param strStaParams = { {0} };
a4cac481 2432 struct wilc_vif *vif;
c5c77ba1 2433
7ae43363
LK
2434 if (!wiphy)
2435 return -EFAULT;
c5c77ba1
JK
2436
2437 priv = wiphy_priv(wiphy);
a4cac481 2438 vif = netdev_priv(dev);
c5c77ba1 2439
a4cac481 2440 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2353c388 2441 memcpy(strStaParams.bssid, mac, ETH_ALEN);
d00d2ba3 2442 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
4101eb8a 2443 strStaParams.aid = params->aid;
e734223c 2444 strStaParams.rates_len = params->supported_rates_len;
a622e016 2445 strStaParams.rates = params->supported_rates;
c5c77ba1
JK
2446
2447 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2448
2449 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],
2450 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
4101eb8a 2451 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
e734223c
LK
2452 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2453 strStaParams.rates_len);
c5c77ba1 2454
369a1d3b 2455 if (!params->ht_capa) {
22520120 2456 strStaParams.ht_supported = false;
c5c77ba1 2457 } else {
22520120 2458 strStaParams.ht_supported = true;
0d073f69 2459 strStaParams.ht_capa_info = params->ht_capa->cap_info;
fba1f2d2 2460 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
5ebbf4f7
LK
2461 memcpy(strStaParams.ht_supp_mcs_set,
2462 &params->ht_capa->mcs,
2463 WILC_SUPP_MCS_SET_SIZE);
223741d7 2464 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
74fe73cf 2465 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
a486baff 2466 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
c5c77ba1
JK
2467 }
2468
f676e17a 2469 strStaParams.flags_mask = params->sta_flags_mask;
67ab64e4 2470 strStaParams.flags_set = params->sta_flags_set;
c5c77ba1 2471
22520120
LK
2472 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2473 strStaParams.ht_supported);
0d073f69
LK
2474 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2475 strStaParams.ht_capa_info);
fba1f2d2
LK
2476 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2477 strStaParams.ht_ampdu_params);
223741d7
LK
2478 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2479 strStaParams.ht_ext_params);
74fe73cf
LK
2480 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2481 strStaParams.ht_tx_bf_cap);
a486baff
LK
2482 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2483 strStaParams.ht_ante_sel);
f676e17a
LK
2484 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2485 strStaParams.flags_mask);
67ab64e4
LK
2486 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2487 strStaParams.flags_set);
c5c77ba1 2488
0e1af73d 2489 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
7dc1d0cc
LK
2490 if (s32Error)
2491 PRINT_ER("Host add station fail\n");
c5c77ba1
JK
2492 }
2493
c5c77ba1
JK
2494 return s32Error;
2495}
2496
a0a8be95
CL
2497static int del_station(struct wiphy *wiphy, struct net_device *dev,
2498 struct station_del_parameters *params)
c5c77ba1 2499{
057d1e97 2500 const u8 *mac = params->mac;
e6e12661 2501 s32 s32Error = 0;
2726887c 2502 struct wilc_priv *priv;
a4cac481 2503 struct wilc_vif *vif;
8dfaafd6 2504
7ae43363
LK
2505 if (!wiphy)
2506 return -EFAULT;
c5c77ba1
JK
2507
2508 priv = wiphy_priv(wiphy);
a4cac481 2509 vif = netdev_priv(dev);
c5c77ba1 2510
a4cac481 2511 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
c5c77ba1
JK
2512 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2513
2514
369a1d3b 2515 if (!mac) {
17aacd43 2516 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
0e1af73d 2517 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
c5c77ba1
JK
2518 } else {
2519 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]);
2520 }
2521
0e1af73d 2522 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
c5c77ba1 2523
7dc1d0cc
LK
2524 if (s32Error)
2525 PRINT_ER("Host delete station fail\n");
c5c77ba1
JK
2526 }
2527 return s32Error;
2528}
2529
14b42084
CL
2530static int change_station(struct wiphy *wiphy, struct net_device *dev,
2531 const u8 *mac, struct station_parameters *params)
c5c77ba1 2532{
e6e12661 2533 s32 s32Error = 0;
2726887c 2534 struct wilc_priv *priv;
6a89ba9c 2535 struct add_sta_param strStaParams = { {0} };
a4cac481 2536 struct wilc_vif *vif;
c5c77ba1
JK
2537
2538
2539 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2540
7ae43363
LK
2541 if (!wiphy)
2542 return -EFAULT;
c5c77ba1
JK
2543
2544 priv = wiphy_priv(wiphy);
a4cac481 2545 vif = netdev_priv(dev);
c5c77ba1 2546
a4cac481 2547 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2353c388 2548 memcpy(strStaParams.bssid, mac, ETH_ALEN);
4101eb8a 2549 strStaParams.aid = params->aid;
e734223c 2550 strStaParams.rates_len = params->supported_rates_len;
a622e016 2551 strStaParams.rates = params->supported_rates;
c5c77ba1 2552
2353c388
LK
2553 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2554 strStaParams.bssid[0], strStaParams.bssid[1],
2555 strStaParams.bssid[2], strStaParams.bssid[3],
2556 strStaParams.bssid[4], strStaParams.bssid[5]);
4101eb8a 2557 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
e734223c
LK
2558 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2559 strStaParams.rates_len);
c5c77ba1 2560
369a1d3b 2561 if (!params->ht_capa) {
22520120 2562 strStaParams.ht_supported = false;
c5c77ba1 2563 } else {
22520120 2564 strStaParams.ht_supported = true;
0d073f69 2565 strStaParams.ht_capa_info = params->ht_capa->cap_info;
fba1f2d2 2566 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
5ebbf4f7
LK
2567 memcpy(strStaParams.ht_supp_mcs_set,
2568 &params->ht_capa->mcs,
2569 WILC_SUPP_MCS_SET_SIZE);
223741d7 2570 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
74fe73cf 2571 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
a486baff 2572 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
c5c77ba1
JK
2573 }
2574
f676e17a 2575 strStaParams.flags_mask = params->sta_flags_mask;
67ab64e4 2576 strStaParams.flags_set = params->sta_flags_set;
c5c77ba1 2577
22520120
LK
2578 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2579 strStaParams.ht_supported);
0d073f69
LK
2580 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2581 strStaParams.ht_capa_info);
fba1f2d2
LK
2582 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2583 strStaParams.ht_ampdu_params);
223741d7
LK
2584 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2585 strStaParams.ht_ext_params);
74fe73cf
LK
2586 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2587 strStaParams.ht_tx_bf_cap);
a486baff
LK
2588 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2589 strStaParams.ht_ante_sel);
f676e17a
LK
2590 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2591 strStaParams.flags_mask);
67ab64e4
LK
2592 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2593 strStaParams.flags_set);
c5c77ba1 2594
0e1af73d 2595 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
7dc1d0cc
LK
2596 if (s32Error)
2597 PRINT_ER("Host edit station fail\n");
c5c77ba1
JK
2598 }
2599 return s32Error;
2600}
2601
37316e81
CL
2602static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2603 const char *name,
2604 unsigned char name_assign_type,
2605 enum nl80211_iftype type,
2606 u32 *flags,
2607 struct vif_params *params)
c5c77ba1 2608{
a4cac481 2609 struct wilc_vif *vif;
2726887c 2610 struct wilc_priv *priv;
c5c77ba1 2611 struct net_device *new_ifc = NULL;
8dfaafd6 2612
c5c77ba1
JK
2613 priv = wiphy_priv(wiphy);
2614
2615
2616
2617 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2618
a4cac481 2619 vif = netdev_priv(priv->wdev->netdev);
c5c77ba1
JK
2620
2621
2622 if (type == NL80211_IFTYPE_MONITOR) {
2623 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
a4cac481
GL
2624 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->wilc_netdev);
2625 new_ifc = WILC_WFI_init_mon_interface(name, vif->wilc_netdev);
369a1d3b 2626 if (new_ifc) {
c5c77ba1 2627 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
a4cac481
GL
2628 vif = netdev_priv(priv->wdev->netdev);
2629 vif->monitor_flag = 1;
c5c77ba1
JK
2630 } else
2631 PRINT_ER("Error in initializing monitor interface\n ");
2632 }
c5c77ba1 2633 return priv->wdev;
c5c77ba1
JK
2634}
2635
956d7211 2636static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
c5c77ba1
JK
2637{
2638 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
e6e12661 2639 return 0;
c5c77ba1
JK
2640}
2641
08241924 2642static struct cfg80211_ops wilc_cfg80211_ops = {
80785a9a 2643 .set_monitor_channel = set_channel,
0e30d06d 2644 .scan = scan,
4ffbcdb6 2645 .connect = connect,
b027cde9 2646 .disconnect = disconnect,
953d417a 2647 .add_key = add_key,
3044ba7e 2648 .del_key = del_key,
f4893dfc 2649 .get_key = get_key,
0f5b8ca3 2650 .set_default_key = set_default_key,
69deb4c2 2651 .add_virtual_intf = add_virtual_intf,
b4a73355 2652 .del_virtual_intf = del_virtual_intf,
3615e9a3 2653 .change_virtual_intf = change_virtual_intf,
c5c77ba1 2654
a13168d7 2655 .start_ap = start_ap,
2a4c84d7 2656 .change_beacon = change_beacon,
c8cddd79 2657 .stop_ap = stop_ap,
ed26955c 2658 .add_station = add_station,
a0a8be95 2659 .del_station = del_station,
14b42084 2660 .change_station = change_station,
f06f562d 2661 .get_station = get_station,
bdb6338f 2662 .dump_station = dump_station,
a5f7db6a 2663 .change_bss = change_bss,
a76b63ef 2664 .set_wiphy_params = set_wiphy_params,
c5c77ba1 2665
4d46657a 2666 .set_pmksa = set_pmksa,
1ff86d96 2667 .del_pmksa = del_pmksa,
b33c39b1 2668 .flush_pmksa = flush_pmksa,
6d19d695 2669 .remain_on_channel = remain_on_channel,
1dd5440b 2670 .cancel_remain_on_channel = cancel_remain_on_channel,
4a2f9b38 2671 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
12a26a33 2672 .mgmt_tx = mgmt_tx,
8e0735c5 2673 .mgmt_frame_register = wilc_mgmt_frame_register,
46530679 2674 .set_power_mgmt = set_power_mgmt,
a8047e26 2675 .set_cqm_rssi_config = set_cqm_rssi_config,
c5c77ba1
JK
2676
2677};
2678
c5c77ba1
JK
2679int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2680{
2726887c 2681 struct wilc_priv *priv;
c5c77ba1
JK
2682
2683 priv = wiphy_priv(wiphy);
c5c77ba1 2684 switch (changed) {
c5c77ba1
JK
2685 case WILC_WFI_RX_PKT:
2686 {
c5c77ba1
JK
2687 priv->netstats.rx_packets++;
2688 priv->netstats.rx_bytes += pktlen;
2689 priv->netstats.rx_time = get_jiffies_64();
2690 }
2691 break;
2692
2693 case WILC_WFI_TX_PKT:
2694 {
2695 priv->netstats.tx_packets++;
2696 priv->netstats.tx_bytes += pktlen;
2697 priv->netstats.tx_time = get_jiffies_64();
2698
2699 }
2700 break;
2701
2702 default:
2703 break;
2704 }
c5c77ba1
JK
2705 return 0;
2706}
c5c77ba1 2707
1608c403 2708static struct wireless_dev *WILC_WFI_CfgAlloc(void)
c5c77ba1 2709{
c5c77ba1
JK
2710 struct wireless_dev *wdev;
2711
2712
2713 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
a89f7c55 2714
c5c77ba1
JK
2715 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2716 if (!wdev) {
2717 PRINT_ER("Cannot allocate wireless device\n");
2718 goto _fail_;
2719 }
2720
2726887c 2721 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
c5c77ba1
JK
2722 if (!wdev->wiphy) {
2723 PRINT_ER("Cannot allocate wiphy\n");
2724 goto _fail_mem_;
c5c77ba1
JK
2725 }
2726
c5c77ba1
JK
2727 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2728 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2729 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2730 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2731 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
c5c77ba1 2732
c5c77ba1
JK
2733 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2734
2735 return wdev;
2736
2737_fail_mem_:
2738 kfree(wdev);
2739_fail_:
2740 return NULL;
c5c77ba1 2741}
a89f7c55 2742
2e7d5377 2743struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
c5c77ba1 2744{
2726887c 2745 struct wilc_priv *priv;
c5c77ba1 2746 struct wireless_dev *wdev;
e6e12661 2747 s32 s32Error = 0;
c5c77ba1
JK
2748
2749 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2750
2751 wdev = WILC_WFI_CfgAlloc();
369a1d3b 2752 if (!wdev) {
c5c77ba1
JK
2753 PRINT_ER("CfgAlloc Failed\n");
2754 return NULL;
2755 }
2756
c5c77ba1 2757 priv = wdev_priv(wdev);
83383ea3 2758 sema_init(&(priv->SemHandleUpdateStats), 1);
c5c77ba1 2759 priv->wdev = wdev;
c5c77ba1 2760 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
c5c77ba1
JK
2761 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2762 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
c5c77ba1
JK
2763
2764 wdev->wiphy->max_scan_ie_len = 1000;
c5c77ba1 2765 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
c5c77ba1
JK
2766 wdev->wiphy->cipher_suites = cipher_suites;
2767 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
c5c77ba1 2768 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
c5c77ba1 2769
c5c77ba1 2770 wdev->wiphy->max_remain_on_channel_duration = 500;
c5c77ba1
JK
2771 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2772 BIT(NL80211_IFTYPE_P2P_CLIENT);
c5c77ba1 2773 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
c5c77ba1
JK
2774 wdev->iftype = NL80211_IFTYPE_STATION;
2775
2776
2777
2778 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2779 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2780 wdev->wiphy->interface_modes, wdev->iftype);
2781
2e7d5377 2782 set_wiphy_dev(wdev->wiphy, dev);
c5c77ba1 2783
c5c77ba1
JK
2784 s32Error = wiphy_register(wdev->wiphy);
2785 if (s32Error) {
2786 PRINT_ER("Cannot register wiphy device\n");
c5c77ba1
JK
2787 } else {
2788 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2789 }
2790
c5c77ba1 2791 priv->dev = net;
c5c77ba1 2792 return wdev;
c5c77ba1 2793}
a89f7c55 2794
dd4b6a83 2795int wilc_init_host_int(struct net_device *net)
c5c77ba1 2796{
1a8ccd85 2797 int s32Error = 0;
c5c77ba1 2798
2726887c 2799 struct wilc_priv *priv;
c5c77ba1 2800
c5c77ba1
JK
2801 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2802 priv = wdev_priv(net->ieee80211_ptr);
2803 if (op_ifcs == 0) {
93dee8ee 2804 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
0e1af73d 2805 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
c5c77ba1
JK
2806 }
2807 op_ifcs++;
2808 if (s32Error < 0) {
2809 PRINT_ER("Failed to creat refresh Timer\n");
2810 return s32Error;
2811 }
2812
72ed4dc7 2813 priv->gbAutoRateAdjusted = false;
c5c77ba1 2814
72ed4dc7 2815 priv->bInP2PlistenState = false;
c5c77ba1 2816
83383ea3 2817 sema_init(&(priv->hSemScanReq), 1);
0e1af73d 2818 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
f1fe9c43 2819 if (s32Error)
c5c77ba1 2820 PRINT_ER("Error while initializing hostinterface\n");
f1fe9c43 2821
c5c77ba1
JK
2822 return s32Error;
2823}
2824
a9a16823 2825int wilc_deinit_host_int(struct net_device *net)
c5c77ba1 2826{
1a8ccd85 2827 int s32Error = 0;
c5c77ba1 2828
2726887c 2829 struct wilc_priv *priv;
8dfaafd6 2830
c5c77ba1
JK
2831 priv = wdev_priv(net->ieee80211_ptr);
2832
72ed4dc7 2833 priv->gbAutoRateAdjusted = false;
c5c77ba1 2834
72ed4dc7 2835 priv->bInP2PlistenState = false;
c5c77ba1
JK
2836
2837 op_ifcs--;
2838
0e1af73d 2839 s32Error = wilc_deinit(priv->hWILCWFIDrv);
c5c77ba1 2840
d14991af 2841 clear_shadow_scan();
c5c77ba1
JK
2842 if (op_ifcs == 0) {
2843 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
0e1af73d 2844 del_timer_sync(&wilc_during_ip_timer);
c5c77ba1 2845 }
c5c77ba1 2846
f1fe9c43 2847 if (s32Error)
c5c77ba1 2848 PRINT_ER("Error while deintializing host interface\n");
f1fe9c43 2849
c5c77ba1
JK
2850 return s32Error;
2851}
2852
96da20a9 2853void wilc_free_wiphy(struct net_device *net)
c5c77ba1 2854{
c5c77ba1
JK
2855 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2856
619837ae 2857 if (!net) {
c5c77ba1
JK
2858 PRINT_D(INIT_DBG, "net_device is NULL\n");
2859 return;
2860 }
2861
619837ae 2862 if (!net->ieee80211_ptr) {
c5c77ba1
JK
2863 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2864 return;
2865 }
2866
619837ae 2867 if (!net->ieee80211_ptr->wiphy) {
c5c77ba1
JK
2868 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2869 return;
2870 }
2871
2872 wiphy_unregister(net->ieee80211_ptr->wiphy);
2873
2874 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2875 wiphy_free(net->ieee80211_ptr->wiphy);
2876 kfree(net->ieee80211_ptr);
c5c77ba1 2877}