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