]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
378c3505e2b090b414f1840ea8fd1833e8a80a50
[karo-tx-linux.git] / drivers / staging / wilc1000 / wilc_wfi_cfgoperations.c
1 #include "wilc_wfi_cfgoperations.h"
2 #include "host_interface.h"
3 #include <linux/errno.h>
4
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
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
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
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
40 static 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
48 static 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
77 static const struct wiphy_wowlan_support wowlan_support = {
78         .flags = WIPHY_WOWLAN_ANY
79 };
80
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
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
93 extern int wilc_mac_open(struct net_device *ndev);
94 extern int wilc_mac_close(struct net_device *ndev);
95
96 static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
97 static u32 last_scanned_cnt;
98 struct timer_list wilc_during_ip_timer;
99 static struct timer_list hAgingTimer;
100 static u8 op_ifcs;
101
102 u8 wilc_initialized = 1;
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
113 static struct ieee80211_channel ieee80211_2ghz_channels[] = {
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
136 static struct ieee80211_rate ieee80211_bitrates[] = {
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
151 struct p2p_mgmt_data {
152         int size;
153         u8 *buff;
154 };
155
156 static u8 wlan_channel = INVALID_CHANNEL;
157 static u8 curr_channel;
158 static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
159 static u8 p2p_local_random = 0x01;
160 static u8 p2p_recv_random;
161 static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
162 static bool wilc_ie;
163
164 static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
165         .channels = ieee80211_2ghz_channels,
166         .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
167         .bitrates = ieee80211_bitrates,
168         .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
169 };
170
171
172 struct add_key_params {
173         u8 key_idx;
174         bool pairwise;
175         u8 *mac_addr;
176 };
177 static struct add_key_params g_add_gtk_key_params;
178 static struct wilc_wfi_key g_key_gtk_params;
179 static struct add_key_params g_add_ptk_key_params;
180 static struct wilc_wfi_key g_key_ptk_params;
181 static struct wilc_wfi_wep_key g_key_wep_params;
182 static bool g_ptk_keys_saved;
183 static bool g_gtk_keys_saved;
184 static bool g_wep_keys_saved;
185
186 #define AGING_TIME      (9 * 1000)
187 #define during_ip_time  15000
188
189 static void clear_shadow_scan(void)
190 {
191         int i;
192
193         if (op_ifcs == 0) {
194                 del_timer_sync(&hAgingTimer);
195
196                 for (i = 0; i < last_scanned_cnt; i++) {
197                         if (last_scanned_shadow[last_scanned_cnt].ies) {
198                                 kfree(last_scanned_shadow[i].ies);
199                                 last_scanned_shadow[last_scanned_cnt].ies = NULL;
200                         }
201
202                         kfree(last_scanned_shadow[i].join_params);
203                         last_scanned_shadow[i].join_params = NULL;
204                 }
205                 last_scanned_cnt = 0;
206         }
207 }
208
209 static u32 get_rssi_avg(struct network_info *network_info)
210 {
211         u8 i;
212         int rssi_v = 0;
213         u8 num_rssi = (network_info->str_rssi.u8Full) ?
214                        NUM_RSSI : (network_info->str_rssi.u8Index);
215
216         for (i = 0; i < num_rssi; i++)
217                 rssi_v += network_info->str_rssi.as8RSSI[i];
218
219         rssi_v /= num_rssi;
220         return rssi_v;
221 }
222
223 static void refresh_scan(void *user_void, u8 all, bool direct_scan)
224 {
225         struct wilc_priv *priv;
226         struct wiphy *wiphy;
227         struct cfg80211_bss *bss = NULL;
228         int i;
229         int rssi = 0;
230
231         priv = user_void;
232         wiphy = priv->dev->ieee80211_ptr->wiphy;
233
234         for (i = 0; i < last_scanned_cnt; i++) {
235                 struct network_info *network_info;
236
237                 network_info = &last_scanned_shadow[i];
238
239                 if (!network_info->found || all) {
240                         s32 freq;
241                         struct ieee80211_channel *channel;
242
243                         if (network_info) {
244                                 freq = ieee80211_channel_to_frequency((s32)network_info->ch, IEEE80211_BAND_2GHZ);
245                                 channel = ieee80211_get_channel(wiphy, freq);
246
247                                 rssi = get_rssi_avg(network_info);
248                                 if (memcmp("DIRECT-", network_info->ssid, 7) ||
249                                     direct_scan) {
250                                         bss = cfg80211_inform_bss(wiphy,
251                                                                   channel,
252                                                                   CFG80211_BSS_FTYPE_UNKNOWN,
253                                                                   network_info->bssid,
254                                                                   network_info->tsf_hi,
255                                                                   network_info->cap_info,
256                                                                   network_info->beacon_period,
257                                                                   (const u8 *)network_info->ies,
258                                                                   (size_t)network_info->ies_len,
259                                                                   (s32)rssi * 100,
260                                                                   GFP_KERNEL);
261                                         cfg80211_put_bss(wiphy, bss);
262                                 }
263                         }
264                 }
265         }
266 }
267
268 static void reset_shadow_found(void)
269 {
270         int i;
271
272         for (i = 0; i < last_scanned_cnt; i++)
273                 last_scanned_shadow[i].found = 0;
274 }
275
276 static void update_scan_time(void)
277 {
278         int i;
279
280         for (i = 0; i < last_scanned_cnt; i++)
281                 last_scanned_shadow[i].time_scan = jiffies;
282 }
283
284 static void remove_network_from_shadow(unsigned long arg)
285 {
286         unsigned long now = jiffies;
287         int i, j;
288
289
290         for (i = 0; i < last_scanned_cnt; i++) {
291                 if (time_after(now, last_scanned_shadow[i].time_scan +
292                                (unsigned long)(SCAN_RESULT_EXPIRE))) {
293                         kfree(last_scanned_shadow[i].ies);
294                         last_scanned_shadow[i].ies = NULL;
295
296                         kfree(last_scanned_shadow[i].join_params);
297
298                         for (j = i; (j < last_scanned_cnt - 1); j++)
299                                 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
300
301                         last_scanned_cnt--;
302                 }
303         }
304
305         if (last_scanned_cnt != 0) {
306                 hAgingTimer.data = arg;
307                 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
308         }
309 }
310
311 static void clear_duringIP(unsigned long arg)
312 {
313         wilc_optaining_ip = false;
314 }
315
316 static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
317                                 void *user_void)
318 {
319         int state = -1;
320         int i;
321
322         if (last_scanned_cnt == 0) {
323                 hAgingTimer.data = (unsigned long)user_void;
324                 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
325                 state = -1;
326         } else {
327                 for (i = 0; i < last_scanned_cnt; i++) {
328                         if (memcmp(last_scanned_shadow[i].bssid,
329                                    pstrNetworkInfo->bssid, 6) == 0) {
330                                 state = i;
331                                 break;
332                         }
333                 }
334         }
335         return state;
336 }
337
338 static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
339                                   void *user_void, void *pJoinParams)
340 {
341         int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
342         u32 ap_index = 0;
343         u8 rssi_index = 0;
344
345         if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
346                 return;
347
348         if (ap_found == -1) {
349                 ap_index = last_scanned_cnt;
350                 last_scanned_cnt++;
351         } else {
352                 ap_index = ap_found;
353         }
354         rssi_index = last_scanned_shadow[ap_index].str_rssi.u8Index;
355         last_scanned_shadow[ap_index].str_rssi.as8RSSI[rssi_index++] = pstrNetworkInfo->rssi;
356         if (rssi_index == NUM_RSSI) {
357                 rssi_index = 0;
358                 last_scanned_shadow[ap_index].str_rssi.u8Full = 1;
359         }
360         last_scanned_shadow[ap_index].str_rssi.u8Index = rssi_index;
361         last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
362         last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
363         last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
364         memcpy(last_scanned_shadow[ap_index].ssid,
365                pstrNetworkInfo->ssid, pstrNetworkInfo->ssid_len);
366         memcpy(last_scanned_shadow[ap_index].bssid,
367                pstrNetworkInfo->bssid, ETH_ALEN);
368         last_scanned_shadow[ap_index].beacon_period = pstrNetworkInfo->beacon_period;
369         last_scanned_shadow[ap_index].dtim_period = pstrNetworkInfo->dtim_period;
370         last_scanned_shadow[ap_index].ch = pstrNetworkInfo->ch;
371         last_scanned_shadow[ap_index].ies_len = pstrNetworkInfo->ies_len;
372         last_scanned_shadow[ap_index].tsf_hi = pstrNetworkInfo->tsf_hi;
373         if (ap_found != -1)
374                 kfree(last_scanned_shadow[ap_index].ies);
375         last_scanned_shadow[ap_index].ies = kmalloc(pstrNetworkInfo->ies_len,
376                                                     GFP_KERNEL);
377         memcpy(last_scanned_shadow[ap_index].ies,
378                pstrNetworkInfo->ies, pstrNetworkInfo->ies_len);
379         last_scanned_shadow[ap_index].time_scan = jiffies;
380         last_scanned_shadow[ap_index].time_scan_cached = jiffies;
381         last_scanned_shadow[ap_index].found = 1;
382         if (ap_found != -1)
383                 kfree(last_scanned_shadow[ap_index].join_params);
384         last_scanned_shadow[ap_index].join_params = pJoinParams;
385 }
386
387 static void CfgScanResult(enum scan_event scan_event,
388                           struct network_info *network_info,
389                           void *user_void,
390                           void *join_params)
391 {
392         struct wilc_priv *priv;
393         struct wiphy *wiphy;
394         s32 s32Freq;
395         struct ieee80211_channel *channel;
396         struct cfg80211_bss *bss = NULL;
397
398         priv = user_void;
399         if (priv->bCfgScanning) {
400                 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
401                         wiphy = priv->dev->ieee80211_ptr->wiphy;
402
403                         if (!wiphy)
404                                 return;
405
406                         if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
407                             (((s32)network_info->rssi * 100) < 0 ||
408                             ((s32)network_info->rssi * 100) > 100))
409                                 return;
410
411                         if (network_info) {
412                                 s32Freq = ieee80211_channel_to_frequency((s32)network_info->ch, IEEE80211_BAND_2GHZ);
413                                 channel = ieee80211_get_channel(wiphy, s32Freq);
414
415                                 if (!channel)
416                                         return;
417
418                                 if (network_info->new_network) {
419                                         if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
420                                                 priv->u32RcvdChCount++;
421
422                                                 add_network_to_shadow(network_info, priv, join_params);
423
424                                                 if (!(memcmp("DIRECT-", network_info->ssid, 7))) {
425                                                         bss = cfg80211_inform_bss(wiphy,
426                                                                                   channel,
427                                                                                   CFG80211_BSS_FTYPE_UNKNOWN,
428                                                                                   network_info->bssid,
429                                                                                   network_info->tsf_hi,
430                                                                                   network_info->cap_info,
431                                                                                   network_info->beacon_period,
432                                                                                   (const u8 *)network_info->ies,
433                                                                                   (size_t)network_info->ies_len,
434                                                                                   (s32)network_info->rssi * 100,
435                                                                                   GFP_KERNEL);
436                                                         cfg80211_put_bss(wiphy, bss);
437                                                 }
438                                         }
439                                 } else {
440                                         u32 i;
441
442                                         for (i = 0; i < priv->u32RcvdChCount; i++) {
443                                                 if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) {
444                                                         last_scanned_shadow[i].rssi = network_info->rssi;
445                                                         last_scanned_shadow[i].time_scan = jiffies;
446                                                         break;
447                                                 }
448                                         }
449                                 }
450                         }
451                 } else if (scan_event == SCAN_EVENT_DONE) {
452                         refresh_scan(priv, 1, false);
453
454                         down(&(priv->hSemScanReq));
455
456                         if (priv->pstrScanReq) {
457                                 cfg80211_scan_done(priv->pstrScanReq, false);
458                                 priv->u32RcvdChCount = 0;
459                                 priv->bCfgScanning = false;
460                                 priv->pstrScanReq = NULL;
461                         }
462                         up(&(priv->hSemScanReq));
463                 } else if (scan_event == SCAN_EVENT_ABORTED) {
464                         down(&(priv->hSemScanReq));
465
466                         if (priv->pstrScanReq) {
467                                 update_scan_time();
468                                 refresh_scan(priv, 1, false);
469
470                                 cfg80211_scan_done(priv->pstrScanReq, false);
471                                 priv->bCfgScanning = false;
472                                 priv->pstrScanReq = NULL;
473                         }
474                         up(&(priv->hSemScanReq));
475                 }
476         }
477 }
478
479 int wilc_connecting;
480
481 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
482                              struct connect_info *pstrConnectInfo,
483                              u8 u8MacStatus,
484                              struct disconnect_info *pstrDisconnectNotifInfo,
485                              void *pUserVoid)
486 {
487         struct wilc_priv *priv;
488         struct net_device *dev;
489         struct host_if_drv *pstrWFIDrv;
490         u8 NullBssid[ETH_ALEN] = {0};
491         struct wilc *wl;
492         struct wilc_vif *vif;
493
494         wilc_connecting = 0;
495
496         priv = pUserVoid;
497         dev = priv->dev;
498         vif = netdev_priv(dev);
499         wl = vif->wilc;
500         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
501
502         if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
503                 u16 u16ConnectStatus;
504
505                 u16ConnectStatus = pstrConnectInfo->status;
506
507                 if ((u8MacStatus == MAC_DISCONNECTED) &&
508                     (pstrConnectInfo->status == SUCCESSFUL_STATUSCODE)) {
509                         u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
510                         wilc_wlan_set_bssid(priv->dev, NullBssid,
511                                             STATION_MODE);
512                         eth_zero_addr(wilc_connected_ssid);
513
514                         if (!pstrWFIDrv->p2p_connect)
515                                 wlan_channel = INVALID_CHANNEL;
516
517                         netdev_err(dev, "Unspecified failure\n");
518                 }
519
520                 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
521                         bool bNeedScanRefresh = false;
522                         u32 i;
523
524                         memcpy(priv->au8AssociatedBss, pstrConnectInfo->bssid, ETH_ALEN);
525
526
527                         for (i = 0; i < last_scanned_cnt; i++) {
528                                 if (memcmp(last_scanned_shadow[i].bssid,
529                                            pstrConnectInfo->bssid,
530                                            ETH_ALEN) == 0) {
531                                         unsigned long now = jiffies;
532
533                                         if (time_after(now,
534                                                        last_scanned_shadow[i].time_scan_cached +
535                                                        (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
536                                                 bNeedScanRefresh = true;
537
538                                         break;
539                                 }
540                         }
541
542                         if (bNeedScanRefresh)
543                                 refresh_scan(priv, 1, true);
544                 }
545
546                 cfg80211_connect_result(dev, pstrConnectInfo->bssid,
547                                         pstrConnectInfo->req_ies, pstrConnectInfo->req_ies_len,
548                                         pstrConnectInfo->resp_ies, pstrConnectInfo->resp_ies_len,
549                                         u16ConnectStatus, GFP_KERNEL);
550         } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF)    {
551                 wilc_optaining_ip = false;
552                 p2p_local_random = 0x01;
553                 p2p_recv_random = 0x00;
554                 wilc_ie = false;
555                 eth_zero_addr(priv->au8AssociatedBss);
556                 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
557                 eth_zero_addr(wilc_connected_ssid);
558
559                 if (!pstrWFIDrv->p2p_connect)
560                         wlan_channel = INVALID_CHANNEL;
561                 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
562                         pstrDisconnectNotifInfo->reason = 3;
563                 } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
564                         pstrDisconnectNotifInfo->reason = 1;
565                 }
566                 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->reason, pstrDisconnectNotifInfo->ie,
567                                       pstrDisconnectNotifInfo->ie_len, false,
568                                       GFP_KERNEL);
569         }
570 }
571
572 static int set_channel(struct wiphy *wiphy,
573                        struct cfg80211_chan_def *chandef)
574 {
575         u32 channelnum = 0;
576         struct wilc_priv *priv;
577         int result = 0;
578         struct wilc_vif *vif;
579
580         priv = wiphy_priv(wiphy);
581         vif = netdev_priv(priv->dev);
582
583         channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
584
585         curr_channel = channelnum;
586         result = wilc_set_mac_chnl_num(vif, channelnum);
587
588         if (result != 0)
589                 netdev_err(priv->dev, "Error in setting channel\n");
590
591         return result;
592 }
593
594 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
595 {
596         struct wilc_priv *priv;
597         u32 i;
598         s32 s32Error = 0;
599         u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
600         struct hidden_network strHiddenNetwork;
601         struct wilc_vif *vif;
602
603         priv = wiphy_priv(wiphy);
604         vif = netdev_priv(priv->dev);
605
606         priv->pstrScanReq = request;
607
608         priv->u32RcvdChCount = 0;
609
610         reset_shadow_found();
611
612         priv->bCfgScanning = true;
613         if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
614                 for (i = 0; i < request->n_channels; i++)
615                         au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
616
617                 if (request->n_ssids >= 1) {
618                         strHiddenNetwork.net_info =
619                                 kmalloc_array(request->n_ssids,
620                                               sizeof(struct hidden_network),
621                                               GFP_KERNEL);
622                         if (!strHiddenNetwork.net_info)
623                                 return -ENOMEM;
624                         strHiddenNetwork.n_ssids = request->n_ssids;
625
626
627                         for (i = 0; i < request->n_ssids; i++) {
628                                 if (request->ssids[i].ssid &&
629                                     request->ssids[i].ssid_len != 0) {
630                                         strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
631                                         memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
632                                         strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
633                                 } else {
634                                         strHiddenNetwork.n_ssids -= 1;
635                                 }
636                         }
637                         s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
638                                              au8ScanChanList,
639                                              request->n_channels,
640                                              (const u8 *)request->ie,
641                                              request->ie_len, CfgScanResult,
642                                              (void *)priv, &strHiddenNetwork);
643                 } else {
644                         s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
645                                              au8ScanChanList,
646                                              request->n_channels,
647                                              (const u8 *)request->ie,
648                                              request->ie_len, CfgScanResult,
649                                              (void *)priv, NULL);
650                 }
651         } else {
652                 netdev_err(priv->dev, "Requested scanned channels over\n");
653         }
654
655         if (s32Error != 0)
656                 s32Error = -EBUSY;
657
658         return s32Error;
659 }
660
661 static int connect(struct wiphy *wiphy, struct net_device *dev,
662                    struct cfg80211_connect_params *sme)
663 {
664         s32 s32Error = 0;
665         u32 i;
666         u8 u8security = NO_ENCRYPT;
667         enum AUTHTYPE tenuAuth_type = ANY;
668         char *pcgroup_encrypt_val = NULL;
669         char *pccipher_group = NULL;
670         char *pcwpa_version = NULL;
671
672         struct wilc_priv *priv;
673         struct host_if_drv *pstrWFIDrv;
674         struct network_info *pstrNetworkInfo = NULL;
675         struct wilc_vif *vif;
676
677         wilc_connecting = 1;
678         priv = wiphy_priv(wiphy);
679         vif = netdev_priv(priv->dev);
680         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
681
682         if (!(strncmp(sme->ssid, "DIRECT-", 7)))
683                 pstrWFIDrv->p2p_connect = 1;
684         else
685                 pstrWFIDrv->p2p_connect = 0;
686
687         for (i = 0; i < last_scanned_cnt; i++) {
688                 if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
689                     memcmp(last_scanned_shadow[i].ssid,
690                            sme->ssid,
691                            sme->ssid_len) == 0) {
692                         if (!sme->bssid)
693                                 break;
694                         else
695                                 if (memcmp(last_scanned_shadow[i].bssid,
696                                            sme->bssid,
697                                            ETH_ALEN) == 0)
698                                         break;
699                 }
700         }
701
702         if (i < last_scanned_cnt) {
703                 pstrNetworkInfo = &last_scanned_shadow[i];
704         } else {
705                 s32Error = -ENOENT;
706                 wilc_connecting = 0;
707                 return s32Error;
708         }
709
710         memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
711         memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
712
713         if (sme->crypto.cipher_group != NO_ENCRYPT) {
714                 pcwpa_version = "Default";
715                 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
716                         u8security = ENCRYPT_ENABLED | WEP;
717                         pcgroup_encrypt_val = "WEP40";
718                         pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
719
720                         priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
721                         memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
722
723                         g_key_wep_params.key_len = sme->key_len;
724                         g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
725                         memcpy(g_key_wep_params.key, sme->key, sme->key_len);
726                         g_key_wep_params.key_idx = sme->key_idx;
727                         g_wep_keys_saved = true;
728
729                         wilc_set_wep_default_keyid(vif, sme->key_idx);
730                         wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
731                                                  sme->key_idx);
732                 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)   {
733                         u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
734                         pcgroup_encrypt_val = "WEP104";
735                         pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
736
737                         priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
738                         memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
739
740                         g_key_wep_params.key_len = sme->key_len;
741                         g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
742                         memcpy(g_key_wep_params.key, sme->key, sme->key_len);
743                         g_key_wep_params.key_idx = sme->key_idx;
744                         g_wep_keys_saved = true;
745
746                         wilc_set_wep_default_keyid(vif, sme->key_idx);
747                         wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
748                                                  sme->key_idx);
749                 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)   {
750                         if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
751                                 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
752                                 pcgroup_encrypt_val = "WPA2_TKIP";
753                                 pccipher_group = "TKIP";
754                         } else {
755                                 u8security = ENCRYPT_ENABLED | WPA2 | AES;
756                                 pcgroup_encrypt_val = "WPA2_AES";
757                                 pccipher_group = "AES";
758                         }
759                         pcwpa_version = "WPA_VERSION_2";
760                 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)   {
761                         if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
762                                 u8security = ENCRYPT_ENABLED | WPA | TKIP;
763                                 pcgroup_encrypt_val = "WPA_TKIP";
764                                 pccipher_group = "TKIP";
765                         } else {
766                                 u8security = ENCRYPT_ENABLED | WPA | AES;
767                                 pcgroup_encrypt_val = "WPA_AES";
768                                 pccipher_group = "AES";
769                         }
770                         pcwpa_version = "WPA_VERSION_1";
771
772                 } else {
773                         s32Error = -ENOTSUPP;
774                         netdev_err(dev, "Not supported cipher\n");
775                         wilc_connecting = 0;
776                         return s32Error;
777                 }
778         }
779
780         if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
781             || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
782                 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
783                         if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
784                                 u8security = u8security | TKIP;
785                         } else {
786                                 u8security = u8security | AES;
787                         }
788                 }
789         }
790
791         switch (sme->auth_type) {
792         case NL80211_AUTHTYPE_OPEN_SYSTEM:
793                 tenuAuth_type = OPEN_SYSTEM;
794                 break;
795
796         case NL80211_AUTHTYPE_SHARED_KEY:
797                 tenuAuth_type = SHARED_KEY;
798                 break;
799
800         default:
801                 break;
802         }
803
804         if (sme->crypto.n_akm_suites) {
805                 switch (sme->crypto.akm_suites[0]) {
806                 case WLAN_AKM_SUITE_8021X:
807                         tenuAuth_type = IEEE8021;
808                         break;
809
810                 default:
811                         break;
812                 }
813         }
814
815         curr_channel = pstrNetworkInfo->ch;
816
817         if (!pstrWFIDrv->p2p_connect)
818                 wlan_channel = pstrNetworkInfo->ch;
819
820         wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
821
822         s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
823                                      sme->ssid_len, sme->ie, sme->ie_len,
824                                      CfgConnectResult, (void *)priv,
825                                      u8security, tenuAuth_type,
826                                      pstrNetworkInfo->ch,
827                                      pstrNetworkInfo->join_params);
828         if (s32Error != 0) {
829                 netdev_err(dev, "wilc_set_join_req(): Error\n");
830                 s32Error = -ENOENT;
831                 wilc_connecting = 0;
832                 return s32Error;
833         }
834
835         return s32Error;
836 }
837
838 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
839 {
840         s32 s32Error = 0;
841         struct wilc_priv *priv;
842         struct host_if_drv *pstrWFIDrv;
843         struct wilc_vif *vif;
844         u8 NullBssid[ETH_ALEN] = {0};
845
846         wilc_connecting = 0;
847         priv = wiphy_priv(wiphy);
848         vif = netdev_priv(priv->dev);
849
850         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
851         if (!pstrWFIDrv->p2p_connect)
852                 wlan_channel = INVALID_CHANNEL;
853         wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
854
855         p2p_local_random = 0x01;
856         p2p_recv_random = 0x00;
857         wilc_ie = false;
858         pstrWFIDrv->p2p_timeout = 0;
859
860         s32Error = wilc_disconnect(vif, reason_code);
861         if (s32Error != 0) {
862                 netdev_err(priv->dev, "Error in disconnecting\n");
863                 s32Error = -EINVAL;
864         }
865
866         return s32Error;
867 }
868
869 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
870                    bool pairwise,
871                    const u8 *mac_addr, struct key_params *params)
872
873 {
874         s32 s32Error = 0, KeyLen = params->key_len;
875         struct wilc_priv *priv;
876         const u8 *pu8RxMic = NULL;
877         const u8 *pu8TxMic = NULL;
878         u8 u8mode = NO_ENCRYPT;
879         u8 u8gmode = NO_ENCRYPT;
880         u8 u8pmode = NO_ENCRYPT;
881         enum AUTHTYPE tenuAuth_type = ANY;
882         struct wilc *wl;
883         struct wilc_vif *vif;
884
885         priv = wiphy_priv(wiphy);
886         vif = netdev_priv(netdev);
887         wl = vif->wilc;
888
889         switch (params->cipher) {
890         case WLAN_CIPHER_SUITE_WEP40:
891         case WLAN_CIPHER_SUITE_WEP104:
892                 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
893                         priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
894                         memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
895
896                         tenuAuth_type = OPEN_SYSTEM;
897
898                         if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
899                                 u8mode = ENCRYPT_ENABLED | WEP;
900                         else
901                                 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
902
903                         wilc_add_wep_key_bss_ap(vif, params->key,
904                                                 params->key_len, key_index,
905                                                 u8mode, tenuAuth_type);
906                         break;
907                 }
908                 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
909                         priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
910                         memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
911
912                         wilc_add_wep_key_bss_sta(vif, params->key,
913                                                  params->key_len, key_index);
914                 }
915
916                 break;
917
918         case WLAN_CIPHER_SUITE_TKIP:
919         case WLAN_CIPHER_SUITE_CCMP:
920                 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
921                         if (!priv->wilc_gtk[key_index]) {
922                                 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
923                                 priv->wilc_gtk[key_index]->key = NULL;
924                                 priv->wilc_gtk[key_index]->seq = NULL;
925                         }
926                         if (!priv->wilc_ptk[key_index]) {
927                                 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
928                                 priv->wilc_ptk[key_index]->key = NULL;
929                                 priv->wilc_ptk[key_index]->seq = NULL;
930                         }
931
932
933
934                         if (!pairwise) {
935                                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
936                                         u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
937                                 else
938                                         u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
939
940                                 priv->wilc_groupkey = u8gmode;
941
942                                 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
943                                         pu8TxMic = params->key + 24;
944                                         pu8RxMic = params->key + 16;
945                                         KeyLen = params->key_len - 16;
946                                 }
947                                 kfree(priv->wilc_gtk[key_index]->key);
948
949                                 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
950                                 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
951                                 kfree(priv->wilc_gtk[key_index]->seq);
952
953                                 if ((params->seq_len) > 0) {
954                                         priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
955                                         memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
956                                 }
957
958                                 priv->wilc_gtk[key_index]->cipher = params->cipher;
959                                 priv->wilc_gtk[key_index]->key_len = params->key_len;
960                                 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
961
962                                 wilc_add_rx_gtk(vif, params->key, KeyLen,
963                                                 key_index, params->seq_len,
964                                                 params->seq, pu8RxMic,
965                                                 pu8TxMic, AP_MODE, u8gmode);
966
967                         } else {
968                                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
969                                         u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
970                                 else
971                                         u8pmode = priv->wilc_groupkey | AES;
972
973
974                                 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
975                                         pu8TxMic = params->key + 24;
976                                         pu8RxMic = params->key + 16;
977                                         KeyLen = params->key_len - 16;
978                                 }
979
980                                 kfree(priv->wilc_ptk[key_index]->key);
981
982                                 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
983
984                                 kfree(priv->wilc_ptk[key_index]->seq);
985
986                                 if ((params->seq_len) > 0)
987                                         priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
988
989                                 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
990
991                                 if ((params->seq_len) > 0)
992                                         memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
993
994                                 priv->wilc_ptk[key_index]->cipher = params->cipher;
995                                 priv->wilc_ptk[key_index]->key_len = params->key_len;
996                                 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
997
998                                 wilc_add_ptk(vif, params->key, KeyLen,
999                                              mac_addr, pu8RxMic, pu8TxMic,
1000                                              AP_MODE, u8pmode, key_index);
1001                         }
1002                         break;
1003                 }
1004
1005                 {
1006                         u8mode = 0;
1007                         if (!pairwise) {
1008                                 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1009                                         pu8RxMic = params->key + 24;
1010                                         pu8TxMic = params->key + 16;
1011                                         KeyLen = params->key_len - 16;
1012                                 }
1013
1014                                 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
1015                                         g_add_gtk_key_params.key_idx = key_index;
1016                                         g_add_gtk_key_params.pairwise = pairwise;
1017                                         if (!mac_addr) {
1018                                                 g_add_gtk_key_params.mac_addr = NULL;
1019                                         } else {
1020                                                 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1021                                                 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1022                                         }
1023                                         g_key_gtk_params.key_len = params->key_len;
1024                                         g_key_gtk_params.seq_len = params->seq_len;
1025                                         g_key_gtk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
1026                                         memcpy(g_key_gtk_params.key, params->key, params->key_len);
1027                                         if (params->seq_len > 0) {
1028                                                 g_key_gtk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
1029                                                 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1030                                         }
1031                                         g_key_gtk_params.cipher = params->cipher;
1032                                         g_gtk_keys_saved = true;
1033                                 }
1034
1035                                 wilc_add_rx_gtk(vif, params->key, KeyLen,
1036                                                 key_index, params->seq_len,
1037                                                 params->seq, pu8RxMic,
1038                                                 pu8TxMic, STATION_MODE,
1039                                                 u8mode);
1040                         } else {
1041                                 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1042                                         pu8RxMic = params->key + 24;
1043                                         pu8TxMic = params->key + 16;
1044                                         KeyLen = params->key_len - 16;
1045                                 }
1046
1047                                 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1048                                         g_add_ptk_key_params.key_idx = key_index;
1049                                         g_add_ptk_key_params.pairwise = pairwise;
1050                                         if (!mac_addr) {
1051                                                 g_add_ptk_key_params.mac_addr = NULL;
1052                                         } else {
1053                                                 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1054                                                 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1055                                         }
1056                                         g_key_ptk_params.key_len = params->key_len;
1057                                         g_key_ptk_params.seq_len = params->seq_len;
1058                                         g_key_ptk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
1059                                         memcpy(g_key_ptk_params.key, params->key, params->key_len);
1060                                         if (params->seq_len > 0) {
1061                                                 g_key_ptk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
1062                                                 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1063                                         }
1064                                         g_key_ptk_params.cipher = params->cipher;
1065                                         g_ptk_keys_saved = true;
1066                                 }
1067
1068                                 wilc_add_ptk(vif, params->key, KeyLen,
1069                                              mac_addr, pu8RxMic, pu8TxMic,
1070                                              STATION_MODE, u8mode, key_index);
1071                         }
1072                 }
1073                 break;
1074
1075         default:
1076                 netdev_err(netdev, "Not supported cipher\n");
1077                 s32Error = -ENOTSUPP;
1078         }
1079
1080         return s32Error;
1081 }
1082
1083 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1084                    u8 key_index,
1085                    bool pairwise,
1086                    const u8 *mac_addr)
1087 {
1088         struct wilc_priv *priv;
1089         struct wilc *wl;
1090         struct wilc_vif *vif;
1091
1092         priv = wiphy_priv(wiphy);
1093         vif = netdev_priv(netdev);
1094         wl = vif->wilc;
1095
1096         if (netdev == wl->vif[0]->ndev) {
1097                 g_ptk_keys_saved = false;
1098                 g_gtk_keys_saved = false;
1099                 g_wep_keys_saved = false;
1100
1101                 kfree(g_key_wep_params.key);
1102                 g_key_wep_params.key = NULL;
1103
1104                 if ((priv->wilc_gtk[key_index]) != NULL) {
1105                         kfree(priv->wilc_gtk[key_index]->key);
1106                         priv->wilc_gtk[key_index]->key = NULL;
1107                         kfree(priv->wilc_gtk[key_index]->seq);
1108                         priv->wilc_gtk[key_index]->seq = NULL;
1109
1110                         kfree(priv->wilc_gtk[key_index]);
1111                         priv->wilc_gtk[key_index] = NULL;
1112                 }
1113
1114                 if ((priv->wilc_ptk[key_index]) != NULL) {
1115                         kfree(priv->wilc_ptk[key_index]->key);
1116                         priv->wilc_ptk[key_index]->key = NULL;
1117                         kfree(priv->wilc_ptk[key_index]->seq);
1118                         priv->wilc_ptk[key_index]->seq = NULL;
1119                         kfree(priv->wilc_ptk[key_index]);
1120                         priv->wilc_ptk[key_index] = NULL;
1121                 }
1122
1123                 kfree(g_key_ptk_params.key);
1124                 g_key_ptk_params.key = NULL;
1125                 kfree(g_key_ptk_params.seq);
1126                 g_key_ptk_params.seq = NULL;
1127
1128                 kfree(g_key_gtk_params.key);
1129                 g_key_gtk_params.key = NULL;
1130                 kfree(g_key_gtk_params.seq);
1131                 g_key_gtk_params.seq = NULL;
1132
1133         }
1134
1135         if (key_index >= 0 && key_index <= 3) {
1136                 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
1137                 priv->WILC_WFI_wep_key_len[key_index] = 0;
1138                 wilc_remove_wep_key(vif, key_index);
1139         } else {
1140                 wilc_remove_key(priv->hif_drv, mac_addr);
1141         }
1142
1143         return 0;
1144 }
1145
1146 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1147                    bool pairwise,
1148                    const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1149 {
1150         struct wilc_priv *priv;
1151         struct  key_params key_params;
1152
1153         priv = wiphy_priv(wiphy);
1154
1155
1156         if (!pairwise) {
1157                 key_params.key = priv->wilc_gtk[key_index]->key;
1158                 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1159                 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1160                 key_params.seq = priv->wilc_gtk[key_index]->seq;
1161                 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1162         } else {
1163                 key_params.key = priv->wilc_ptk[key_index]->key;
1164                 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1165                 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1166                 key_params.seq = priv->wilc_ptk[key_index]->seq;
1167                 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1168         }
1169
1170         callback(cookie, &key_params);
1171
1172         return 0;
1173 }
1174
1175 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1176                            bool unicast, bool multicast)
1177 {
1178         struct wilc_priv *priv;
1179         struct wilc_vif *vif;
1180
1181         priv = wiphy_priv(wiphy);
1182         vif = netdev_priv(priv->dev);
1183
1184         wilc_set_wep_default_keyid(vif, key_index);
1185
1186         return 0;
1187 }
1188
1189 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1190                        const u8 *mac, struct station_info *sinfo)
1191 {
1192         struct wilc_priv *priv;
1193         struct wilc_vif *vif;
1194         u32 i = 0;
1195         u32 associatedsta = 0;
1196         u32 inactive_time = 0;
1197         priv = wiphy_priv(wiphy);
1198         vif = netdev_priv(dev);
1199
1200         if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1201                 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1202                         if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1203                                 associatedsta = i;
1204                                 break;
1205                         }
1206                 }
1207
1208                 if (associatedsta == -1) {
1209                         netdev_err(dev, "sta required is not associated\n");
1210                         return -ENOENT;
1211                 }
1212
1213                 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1214
1215                 wilc_get_inactive_time(vif, mac, &inactive_time);
1216                 sinfo->inactive_time = 1000 * inactive_time;
1217         }
1218
1219         if (vif->iftype == STATION_MODE) {
1220                 struct rf_info strStatistics;
1221
1222                 wilc_get_statistics(vif, &strStatistics);
1223
1224                 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1225                                                 BIT(NL80211_STA_INFO_RX_PACKETS) |
1226                                                 BIT(NL80211_STA_INFO_TX_PACKETS) |
1227                                                 BIT(NL80211_STA_INFO_TX_FAILED) |
1228                                                 BIT(NL80211_STA_INFO_TX_BITRATE);
1229
1230                 sinfo->signal = strStatistics.rssi;
1231                 sinfo->rx_packets = strStatistics.rx_cnt;
1232                 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1233                 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1234                 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1235
1236                 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1237                     (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1238                         wilc_enable_tcp_ack_filter(true);
1239                 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1240                         wilc_enable_tcp_ack_filter(false);
1241         }
1242         return 0;
1243 }
1244
1245 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1246                       struct bss_parameters *params)
1247 {
1248         return 0;
1249 }
1250
1251 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1252 {
1253         s32 s32Error = 0;
1254         struct cfg_param_attr pstrCfgParamVal;
1255         struct wilc_priv *priv;
1256         struct wilc_vif *vif;
1257
1258         priv = wiphy_priv(wiphy);
1259         vif = netdev_priv(priv->dev);
1260
1261         pstrCfgParamVal.flag = 0;
1262
1263         if (changed & WIPHY_PARAM_RETRY_SHORT) {
1264                 pstrCfgParamVal.flag  |= RETRY_SHORT;
1265                 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1266         }
1267         if (changed & WIPHY_PARAM_RETRY_LONG) {
1268                 pstrCfgParamVal.flag |= RETRY_LONG;
1269                 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1270         }
1271         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1272                 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1273                 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1274         }
1275
1276         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1277                 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1278                 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1279         }
1280
1281         s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1282         if (s32Error)
1283                 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1284
1285         return s32Error;
1286 }
1287
1288 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1289                      struct cfg80211_pmksa *pmksa)
1290 {
1291         u32 i;
1292         s32 s32Error = 0;
1293         u8 flag = 0;
1294         struct wilc_vif *vif;
1295         struct wilc_priv *priv = wiphy_priv(wiphy);
1296
1297         vif = netdev_priv(priv->dev);
1298
1299
1300         for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1301                 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1302                                  ETH_ALEN)) {
1303                         flag = PMKID_FOUND;
1304                         break;
1305                 }
1306         }
1307         if (i < WILC_MAX_NUM_PMKIDS) {
1308                 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1309                             ETH_ALEN);
1310                 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1311                             PMKID_LEN);
1312                 if (!(flag == PMKID_FOUND))
1313                         priv->pmkid_list.numpmkid++;
1314         } else {
1315                 netdev_err(netdev, "Invalid PMKID index\n");
1316                 s32Error = -EINVAL;
1317         }
1318
1319         if (!s32Error)
1320                 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1321
1322         return s32Error;
1323 }
1324
1325 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1326                      struct cfg80211_pmksa *pmksa)
1327 {
1328         u32 i;
1329         s32 s32Error = 0;
1330
1331         struct wilc_priv *priv = wiphy_priv(wiphy);
1332
1333         for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1334                 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1335                                  ETH_ALEN)) {
1336                         memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1337                         break;
1338                 }
1339         }
1340
1341         if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1342                 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1343                         memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1344                                     priv->pmkid_list.pmkidlist[i + 1].bssid,
1345                                     ETH_ALEN);
1346                         memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1347                                     priv->pmkid_list.pmkidlist[i].pmkid,
1348                                     PMKID_LEN);
1349                 }
1350                 priv->pmkid_list.numpmkid--;
1351         } else {
1352                 s32Error = -EINVAL;
1353         }
1354
1355         return s32Error;
1356 }
1357
1358 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1359 {
1360         struct wilc_priv *priv = wiphy_priv(wiphy);
1361
1362         memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1363
1364         return 0;
1365 }
1366
1367 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1368 {
1369         u32 index = 0;
1370         u32 i = 0, j = 0;
1371
1372         u8 op_channel_attr_index = 0;
1373         u8 channel_list_attr_index = 0;
1374
1375         while (index < len) {
1376                 if (buf[index] == GO_INTENT_ATTR_ID) {
1377                         buf[index + 3] = (buf[index + 3]  & 0x01) | (0x00 << 1);
1378                 }
1379
1380                 if (buf[index] ==  CHANLIST_ATTR_ID)
1381                         channel_list_attr_index = index;
1382                 else if (buf[index] ==  OPERCHAN_ATTR_ID)
1383                         op_channel_attr_index = index;
1384                 index += buf[index + 1] + 3;
1385         }
1386         if (wlan_channel != INVALID_CHANNEL) {
1387                 if (channel_list_attr_index) {
1388                         for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1389                                 if (buf[i] == 0x51) {
1390                                         for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1391                                                 buf[j] = wlan_channel;
1392                                         }
1393                                         break;
1394                                 }
1395                         }
1396                 }
1397
1398                 if (op_channel_attr_index) {
1399                         buf[op_channel_attr_index + 6] = 0x51;
1400                         buf[op_channel_attr_index + 7] = wlan_channel;
1401                 }
1402         }
1403 }
1404
1405 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1406 {
1407         u32 index = 0;
1408         u32 i = 0, j = 0;
1409
1410         u8 op_channel_attr_index = 0;
1411         u8 channel_list_attr_index = 0;
1412
1413         while (index < len) {
1414                 if (buf[index] == GO_INTENT_ATTR_ID) {
1415                         buf[index + 3] = (buf[index + 3]  & 0x01) | (0x0f << 1);
1416
1417                         break;
1418                 }
1419
1420                 if (buf[index] ==  CHANLIST_ATTR_ID)
1421                         channel_list_attr_index = index;
1422                 else if (buf[index] ==  OPERCHAN_ATTR_ID)
1423                         op_channel_attr_index = index;
1424                 index += buf[index + 1] + 3;
1425         }
1426         if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1427                 if (channel_list_attr_index) {
1428                         for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1429                                 if (buf[i] == 0x51) {
1430                                         for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1431                                                 buf[j] = wlan_channel;
1432                                         }
1433                                         break;
1434                                 }
1435                         }
1436                 }
1437
1438                 if (op_channel_attr_index) {
1439                         buf[op_channel_attr_index + 6] = 0x51;
1440                         buf[op_channel_attr_index + 7] = wlan_channel;
1441                 }
1442         }
1443 }
1444
1445 void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
1446 {
1447         struct wilc_priv *priv;
1448         u32 header, pkt_offset;
1449         struct host_if_drv *pstrWFIDrv;
1450         u32 i = 0;
1451         s32 s32Freq;
1452
1453         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1454         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1455
1456         memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1457
1458         pkt_offset = GET_PKT_OFFSET(header);
1459
1460         if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1461                 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1462                         cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1463                         return;
1464                 } else {
1465                         if (pkt_offset & IS_MGMT_STATUS_SUCCES)
1466                                 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1467                         else
1468                                 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1469                         return;
1470                 }
1471         } else {
1472                 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
1473
1474                 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1475                         if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1476                                 netdev_dbg(dev, "Receiving action wrong ch\n");
1477                                 return;
1478                         }
1479                         if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1480                                 switch (buff[ACTION_SUBTYPE_ID]) {
1481                                 case GAS_INTIAL_REQ:
1482                                         break;
1483
1484                                 case GAS_INTIAL_RSP:
1485                                         break;
1486
1487                                 case PUBLIC_ACT_VENDORSPEC:
1488                                         if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1489                                                 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1490                                                         if (!wilc_ie) {
1491                                                                 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1492                                                                         if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1493                                                                                 p2p_recv_random = buff[i + 6];
1494                                                                                 wilc_ie = true;
1495                                                                                 break;
1496                                                                         }
1497                                                                 }
1498                                                         }
1499                                                 }
1500                                                 if (p2p_local_random > p2p_recv_random) {
1501                                                         if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1502                                                               || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1503                                                                 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1504                                                                         if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1505                                                                                 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1506                                                                                 break;
1507                                                                         }
1508                                                                 }
1509                                                         }
1510                                                 } else {
1511                                                         netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1512                                                 }
1513                                         }
1514
1515
1516                                         if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie))    {
1517                                                 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1518                                                 return;
1519                                         }
1520                                         break;
1521
1522                                 default:
1523                                         netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1524                                         break;
1525                                 }
1526                         }
1527                 }
1528
1529                 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1530         }
1531 }
1532
1533 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1534 {
1535         struct p2p_mgmt_data *pv_data = priv;
1536
1537
1538         kfree(pv_data->buff);
1539         kfree(pv_data);
1540 }
1541
1542 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1543 {
1544         struct wilc_priv *priv;
1545
1546         priv = pUserVoid;
1547
1548         priv->bInP2PlistenState = true;
1549
1550         cfg80211_ready_on_channel(priv->wdev,
1551                                   priv->strRemainOnChanParams.u64ListenCookie,
1552                                   priv->strRemainOnChanParams.pstrListenChan,
1553                                   priv->strRemainOnChanParams.u32ListenDuration,
1554                                   GFP_KERNEL);
1555 }
1556
1557 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1558 {
1559         struct wilc_priv *priv;
1560
1561         priv = pUserVoid;
1562
1563         if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1564                 priv->bInP2PlistenState = false;
1565
1566                 cfg80211_remain_on_channel_expired(priv->wdev,
1567                                                    priv->strRemainOnChanParams.u64ListenCookie,
1568                                                    priv->strRemainOnChanParams.pstrListenChan,
1569                                                    GFP_KERNEL);
1570         }
1571 }
1572
1573 static int remain_on_channel(struct wiphy *wiphy,
1574                              struct wireless_dev *wdev,
1575                              struct ieee80211_channel *chan,
1576                              unsigned int duration, u64 *cookie)
1577 {
1578         s32 s32Error = 0;
1579         struct wilc_priv *priv;
1580         struct wilc_vif *vif;
1581
1582         priv = wiphy_priv(wiphy);
1583         vif = netdev_priv(priv->dev);
1584
1585         if (wdev->iftype == NL80211_IFTYPE_AP) {
1586                 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1587                 return s32Error;
1588         }
1589
1590         curr_channel = chan->hw_value;
1591
1592         priv->strRemainOnChanParams.pstrListenChan = chan;
1593         priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1594         priv->strRemainOnChanParams.u32ListenDuration = duration;
1595         priv->strRemainOnChanParams.u32ListenSessionID++;
1596
1597         s32Error = wilc_remain_on_channel(vif,
1598                                 priv->strRemainOnChanParams.u32ListenSessionID,
1599                                 duration, chan->hw_value,
1600                                 WILC_WFI_RemainOnChannelExpired,
1601                                 WILC_WFI_RemainOnChannelReady, (void *)priv);
1602
1603         return s32Error;
1604 }
1605
1606 static int cancel_remain_on_channel(struct wiphy *wiphy,
1607                                     struct wireless_dev *wdev,
1608                                     u64 cookie)
1609 {
1610         s32 s32Error = 0;
1611         struct wilc_priv *priv;
1612         struct wilc_vif *vif;
1613
1614         priv = wiphy_priv(wiphy);
1615         vif = netdev_priv(priv->dev);
1616
1617         s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
1618         return s32Error;
1619 }
1620
1621 static int mgmt_tx(struct wiphy *wiphy,
1622                    struct wireless_dev *wdev,
1623                    struct cfg80211_mgmt_tx_params *params,
1624                    u64 *cookie)
1625 {
1626         struct ieee80211_channel *chan = params->chan;
1627         unsigned int wait = params->wait;
1628         const u8 *buf = params->buf;
1629         size_t len = params->len;
1630         const struct ieee80211_mgmt *mgmt;
1631         struct p2p_mgmt_data *mgmt_tx;
1632         struct wilc_priv *priv;
1633         struct host_if_drv *pstrWFIDrv;
1634         u32 i;
1635         struct wilc_vif *vif;
1636         u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1637
1638         vif = netdev_priv(wdev->netdev);
1639         priv = wiphy_priv(wiphy);
1640         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1641
1642         *cookie = (unsigned long)buf;
1643         priv->u64tx_cookie = *cookie;
1644         mgmt = (const struct ieee80211_mgmt *) buf;
1645
1646         if (ieee80211_is_mgmt(mgmt->frame_control)) {
1647                 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1648                 if (!mgmt_tx)
1649                         return -EFAULT;
1650
1651                 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1652                 if (!mgmt_tx->buff) {
1653                         kfree(mgmt_tx);
1654                         return -ENOMEM;
1655                 }
1656
1657                 memcpy(mgmt_tx->buff, buf, len);
1658                 mgmt_tx->size = len;
1659
1660
1661                 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1662                         wilc_set_mac_chnl_num(vif, chan->hw_value);
1663                         curr_channel = chan->hw_value;
1664                 } else if (ieee80211_is_action(mgmt->frame_control))   {
1665                         if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1666                                 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1667                                     buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1668                                         wilc_set_mac_chnl_num(vif,
1669                                                               chan->hw_value);
1670                                         curr_channel = chan->hw_value;
1671                                 }
1672                                 switch (buf[ACTION_SUBTYPE_ID]) {
1673                                 case GAS_INTIAL_REQ:
1674                                         break;
1675
1676                                 case GAS_INTIAL_RSP:
1677                                         break;
1678
1679                                 case PUBLIC_ACT_VENDORSPEC:
1680                                 {
1681                                         if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1682                                                 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1683                                                         if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1684                                                                 get_random_bytes(&p2p_local_random, 1);
1685                                                                 p2p_local_random++;
1686                                                         }
1687                                                 }
1688
1689                                                 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1690                                                       || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1691                                                         if (p2p_local_random > p2p_recv_random) {
1692                                                                 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1693                                                                         if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1694                                                                                 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1695                                                                                         WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1696                                                                                 else
1697                                                                                         WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1698                                                                                 break;
1699                                                                         }
1700                                                                 }
1701
1702                                                                 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1703                                                                         memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1704                                                                         mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1705                                                                         mgmt_tx->size = buf_len;
1706                                                                 }
1707                                                         }
1708                                                 }
1709
1710                                         } else {
1711                                                 netdev_dbg(vif->ndev, "Not a P2P public action frame\n");
1712                                         }
1713
1714                                         break;
1715                                 }
1716
1717                                 default:
1718                                 {
1719                                         netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1720                                         break;
1721                                 }
1722                                 }
1723                         }
1724
1725                         pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1726                 }
1727
1728                 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1729                                            mgmt_tx->buff, mgmt_tx->size,
1730                                            WILC_WFI_mgmt_tx_complete);
1731         }
1732         return 0;
1733 }
1734
1735 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1736                                struct wireless_dev *wdev,
1737                                u64 cookie)
1738 {
1739         struct wilc_priv *priv;
1740         struct host_if_drv *pstrWFIDrv;
1741
1742         priv = wiphy_priv(wiphy);
1743         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1744         pstrWFIDrv->p2p_timeout = jiffies;
1745
1746         if (!priv->bInP2PlistenState) {
1747                 cfg80211_remain_on_channel_expired(priv->wdev,
1748                                                    priv->strRemainOnChanParams.u64ListenCookie,
1749                                                    priv->strRemainOnChanParams.pstrListenChan,
1750                                                    GFP_KERNEL);
1751         }
1752
1753         return 0;
1754 }
1755
1756 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1757                               u16 frame_type, bool reg)
1758 {
1759         struct wilc_priv *priv;
1760         struct wilc_vif *vif;
1761         struct wilc *wl;
1762
1763         priv = wiphy_priv(wiphy);
1764         vif = netdev_priv(priv->wdev->netdev);
1765         wl = vif->wilc;
1766
1767         if (!frame_type)
1768                 return;
1769
1770         switch (frame_type) {
1771         case PROBE_REQ:
1772         {
1773                 vif->g_struct_frame_reg[0].frame_type = frame_type;
1774                 vif->g_struct_frame_reg[0].reg = reg;
1775         }
1776         break;
1777
1778         case ACTION:
1779         {
1780                 vif->g_struct_frame_reg[1].frame_type = frame_type;
1781                 vif->g_struct_frame_reg[1].reg = reg;
1782         }
1783         break;
1784
1785         default:
1786         {
1787                 break;
1788         }
1789         }
1790
1791         if (!wl->initialized)
1792                 return;
1793         wilc_frame_register(vif, frame_type, reg);
1794 }
1795
1796 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1797                                s32 rssi_thold, u32 rssi_hyst)
1798 {
1799         return 0;
1800 }
1801
1802 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1803                         int idx, u8 *mac, struct station_info *sinfo)
1804 {
1805         struct wilc_priv *priv;
1806         struct wilc_vif *vif;
1807
1808         if (idx != 0)
1809                 return -ENOENT;
1810
1811         priv = wiphy_priv(wiphy);
1812         vif = netdev_priv(priv->dev);
1813
1814         sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1815
1816         wilc_get_rssi(vif, &sinfo->signal);
1817
1818         return 0;
1819 }
1820
1821 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1822                           bool enabled, int timeout)
1823 {
1824         struct wilc_priv *priv;
1825         struct wilc_vif *vif;
1826
1827         if (!wiphy)
1828                 return -ENOENT;
1829
1830         priv = wiphy_priv(wiphy);
1831         vif = netdev_priv(priv->dev);
1832         if (!priv->hif_drv)
1833                 return -EIO;
1834
1835         if (wilc_enable_ps)
1836                 wilc_set_power_mgmt(vif, enabled, timeout);
1837
1838
1839         return 0;
1840 }
1841
1842 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1843                                enum nl80211_iftype type, u32 *flags, struct vif_params *params)
1844 {
1845         struct wilc_priv *priv;
1846         struct wilc_vif *vif;
1847         struct wilc *wl;
1848
1849         vif = netdev_priv(dev);
1850         priv = wiphy_priv(wiphy);
1851         wl = vif->wilc;
1852         p2p_local_random = 0x01;
1853         p2p_recv_random = 0x00;
1854         wilc_ie = false;
1855         wilc_optaining_ip = false;
1856         del_timer(&wilc_during_ip_timer);
1857
1858         switch (type) {
1859         case NL80211_IFTYPE_STATION:
1860                 wilc_connecting = 0;
1861                 dev->ieee80211_ptr->iftype = type;
1862                 priv->wdev->iftype = type;
1863                 vif->monitor_flag = 0;
1864                 vif->iftype = STATION_MODE;
1865                 wilc_set_operation_mode(vif, STATION_MODE);
1866
1867                 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
1868
1869                 wilc_enable_ps = true;
1870                 wilc_set_power_mgmt(vif, 1, 0);
1871                 break;
1872
1873         case NL80211_IFTYPE_P2P_CLIENT:
1874                 wilc_connecting = 0;
1875                 dev->ieee80211_ptr->iftype = type;
1876                 priv->wdev->iftype = type;
1877                 vif->monitor_flag = 0;
1878                 vif->iftype = CLIENT_MODE;
1879                 wilc_set_operation_mode(vif, STATION_MODE);
1880
1881                 wilc_enable_ps = false;
1882                 wilc_set_power_mgmt(vif, 0, 0);
1883                 break;
1884
1885         case NL80211_IFTYPE_AP:
1886                 wilc_enable_ps = false;
1887                 dev->ieee80211_ptr->iftype = type;
1888                 priv->wdev->iftype = type;
1889                 vif->iftype = AP_MODE;
1890
1891                 if (wl->initialized) {
1892                         wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
1893                                                  0);
1894                         wilc_set_operation_mode(vif, AP_MODE);
1895                         wilc_set_power_mgmt(vif, 0, 0);
1896                 }
1897                 break;
1898
1899         case NL80211_IFTYPE_P2P_GO:
1900                 wilc_optaining_ip = true;
1901                 mod_timer(&wilc_during_ip_timer,
1902                           jiffies + msecs_to_jiffies(during_ip_time));
1903                 wilc_set_operation_mode(vif, AP_MODE);
1904                 dev->ieee80211_ptr->iftype = type;
1905                 priv->wdev->iftype = type;
1906                 vif->iftype = GO_MODE;
1907
1908                 wilc_enable_ps = false;
1909                 wilc_set_power_mgmt(vif, 0, 0);
1910                 break;
1911
1912         default:
1913                 netdev_err(dev, "Unknown interface type= %d\n", type);
1914                 return -EINVAL;
1915         }
1916
1917         return 0;
1918 }
1919
1920 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1921                     struct cfg80211_ap_settings *settings)
1922 {
1923         struct cfg80211_beacon_data *beacon = &(settings->beacon);
1924         struct wilc_priv *priv;
1925         s32 s32Error = 0;
1926         struct wilc *wl;
1927         struct wilc_vif *vif;
1928
1929         priv = wiphy_priv(wiphy);
1930         vif = netdev_priv(dev);
1931         wl = vif->wilc;
1932
1933         s32Error = set_channel(wiphy, &settings->chandef);
1934
1935         if (s32Error != 0)
1936                 netdev_err(dev, "Error in setting channel\n");
1937
1938         wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
1939         wilc_set_power_mgmt(vif, 0, 0);
1940
1941         s32Error = wilc_add_beacon(vif, settings->beacon_interval,
1942                                    settings->dtim_period, beacon->head_len,
1943                                    (u8 *)beacon->head, beacon->tail_len,
1944                                    (u8 *)beacon->tail);
1945
1946         return s32Error;
1947 }
1948
1949 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1950                          struct cfg80211_beacon_data *beacon)
1951 {
1952         struct wilc_priv *priv;
1953         struct wilc_vif *vif;
1954         s32 s32Error = 0;
1955
1956         priv = wiphy_priv(wiphy);
1957         vif = netdev_priv(priv->dev);
1958
1959         s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
1960                                    (u8 *)beacon->head, beacon->tail_len,
1961                                    (u8 *)beacon->tail);
1962
1963         return s32Error;
1964 }
1965
1966 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1967 {
1968         s32 s32Error = 0;
1969         struct wilc_priv *priv;
1970         struct wilc_vif *vif;
1971         u8 NullBssid[ETH_ALEN] = {0};
1972
1973         if (!wiphy)
1974                 return -EFAULT;
1975
1976         priv = wiphy_priv(wiphy);
1977         vif = netdev_priv(priv->dev);
1978
1979         wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
1980
1981         s32Error = wilc_del_beacon(vif);
1982
1983         if (s32Error)
1984                 netdev_err(dev, "Host delete beacon fail\n");
1985
1986         return s32Error;
1987 }
1988
1989 static int add_station(struct wiphy *wiphy, struct net_device *dev,
1990                        const u8 *mac, struct station_parameters *params)
1991 {
1992         s32 s32Error = 0;
1993         struct wilc_priv *priv;
1994         struct add_sta_param strStaParams = { {0} };
1995         struct wilc_vif *vif;
1996
1997         if (!wiphy)
1998                 return -EFAULT;
1999
2000         priv = wiphy_priv(wiphy);
2001         vif = netdev_priv(dev);
2002
2003         if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2004                 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2005                 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
2006                 strStaParams.aid = params->aid;
2007                 strStaParams.rates_len = params->supported_rates_len;
2008                 strStaParams.rates = params->supported_rates;
2009
2010                 if (!params->ht_capa) {
2011                         strStaParams.ht_supported = false;
2012                 } else {
2013                         strStaParams.ht_supported = true;
2014                         strStaParams.ht_capa_info = params->ht_capa->cap_info;
2015                         strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2016                         memcpy(strStaParams.ht_supp_mcs_set,
2017                                &params->ht_capa->mcs,
2018                                WILC_SUPP_MCS_SET_SIZE);
2019                         strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2020                         strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2021                         strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2022                 }
2023
2024                 strStaParams.flags_mask = params->sta_flags_mask;
2025                 strStaParams.flags_set = params->sta_flags_set;
2026
2027                 s32Error = wilc_add_station(vif, &strStaParams);
2028                 if (s32Error)
2029                         netdev_err(dev, "Host add station fail\n");
2030         }
2031
2032         return s32Error;
2033 }
2034
2035 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2036                        struct station_del_parameters *params)
2037 {
2038         const u8 *mac = params->mac;
2039         s32 s32Error = 0;
2040         struct wilc_priv *priv;
2041         struct wilc_vif *vif;
2042
2043         if (!wiphy)
2044                 return -EFAULT;
2045
2046         priv = wiphy_priv(wiphy);
2047         vif = netdev_priv(dev);
2048
2049         if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2050                 if (!mac)
2051                         s32Error = wilc_del_allstation(vif,
2052                                      priv->assoc_stainfo.au8Sta_AssociatedBss);
2053
2054                 s32Error = wilc_del_station(vif, mac);
2055
2056                 if (s32Error)
2057                         netdev_err(dev, "Host delete station fail\n");
2058         }
2059         return s32Error;
2060 }
2061
2062 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2063                           const u8 *mac, struct station_parameters *params)
2064 {
2065         s32 s32Error = 0;
2066         struct wilc_priv *priv;
2067         struct add_sta_param strStaParams = { {0} };
2068         struct wilc_vif *vif;
2069
2070         if (!wiphy)
2071                 return -EFAULT;
2072
2073         priv = wiphy_priv(wiphy);
2074         vif = netdev_priv(dev);
2075
2076         if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2077                 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2078                 strStaParams.aid = params->aid;
2079                 strStaParams.rates_len = params->supported_rates_len;
2080                 strStaParams.rates = params->supported_rates;
2081
2082                 if (!params->ht_capa) {
2083                         strStaParams.ht_supported = false;
2084                 } else {
2085                         strStaParams.ht_supported = true;
2086                         strStaParams.ht_capa_info = params->ht_capa->cap_info;
2087                         strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2088                         memcpy(strStaParams.ht_supp_mcs_set,
2089                                &params->ht_capa->mcs,
2090                                WILC_SUPP_MCS_SET_SIZE);
2091                         strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2092                         strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2093                         strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2094                 }
2095
2096                 strStaParams.flags_mask = params->sta_flags_mask;
2097                 strStaParams.flags_set = params->sta_flags_set;
2098
2099                 s32Error = wilc_edit_station(vif, &strStaParams);
2100                 if (s32Error)
2101                         netdev_err(dev, "Host edit station fail\n");
2102         }
2103         return s32Error;
2104 }
2105
2106 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2107                                              const char *name,
2108                                              unsigned char name_assign_type,
2109                                              enum nl80211_iftype type,
2110                                              u32 *flags,
2111                                              struct vif_params *params)
2112 {
2113         struct wilc_vif *vif;
2114         struct wilc_priv *priv;
2115         struct net_device *new_ifc = NULL;
2116
2117         priv = wiphy_priv(wiphy);
2118         vif = netdev_priv(priv->wdev->netdev);
2119
2120
2121         if (type == NL80211_IFTYPE_MONITOR) {
2122                 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2123                 if (new_ifc) {
2124                         vif = netdev_priv(priv->wdev->netdev);
2125                         vif->monitor_flag = 1;
2126                 }
2127         }
2128         return priv->wdev;
2129 }
2130
2131 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2132 {
2133         return 0;
2134 }
2135
2136 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2137 {
2138         struct wilc_priv *priv = wiphy_priv(wiphy);
2139         struct wilc_vif *vif = netdev_priv(priv->dev);
2140
2141         if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2142                 vif->wilc->suspend_event = true;
2143         else
2144                 vif->wilc->suspend_event = false;
2145
2146         return 0;
2147 }
2148
2149 static int wilc_resume(struct wiphy *wiphy)
2150 {
2151         struct wilc_priv *priv = wiphy_priv(wiphy);
2152         struct wilc_vif *vif = netdev_priv(priv->dev);
2153
2154         netdev_info(vif->ndev, "cfg resume\n");
2155         return 0;
2156 }
2157
2158 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2159 {
2160         struct wilc_priv *priv = wiphy_priv(wiphy);
2161         struct wilc_vif *vif = netdev_priv(priv->dev);
2162
2163         netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2164 }
2165
2166 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2167                         enum nl80211_tx_power_setting type, int mbm)
2168 {
2169         int ret;
2170         s32 tx_power = MBM_TO_DBM(mbm);
2171         struct wilc_priv *priv = wiphy_priv(wiphy);
2172         struct wilc_vif *vif = netdev_priv(priv->dev);
2173
2174         if (tx_power < 0)
2175                 tx_power = 0;
2176         else if (tx_power > 18)
2177                 tx_power = 18;
2178         ret = wilc_set_tx_power(vif, tx_power);
2179         if (ret)
2180                 netdev_err(vif->ndev, "Failed to set tx power\n");
2181
2182         return ret;
2183 }
2184
2185 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2186                         int *dbm)
2187 {
2188         int ret;
2189         struct wilc_priv *priv = wiphy_priv(wiphy);
2190         struct wilc_vif *vif = netdev_priv(priv->dev);
2191
2192         ret = wilc_get_tx_power(vif, (u8 *)dbm);
2193         if (ret)
2194                 netdev_err(vif->ndev, "Failed to get tx power\n");
2195
2196         return ret;
2197 }
2198
2199 static struct cfg80211_ops wilc_cfg80211_ops = {
2200         .set_monitor_channel = set_channel,
2201         .scan = scan,
2202         .connect = connect,
2203         .disconnect = disconnect,
2204         .add_key = add_key,
2205         .del_key = del_key,
2206         .get_key = get_key,
2207         .set_default_key = set_default_key,
2208         .add_virtual_intf = add_virtual_intf,
2209         .del_virtual_intf = del_virtual_intf,
2210         .change_virtual_intf = change_virtual_intf,
2211
2212         .start_ap = start_ap,
2213         .change_beacon = change_beacon,
2214         .stop_ap = stop_ap,
2215         .add_station = add_station,
2216         .del_station = del_station,
2217         .change_station = change_station,
2218         .get_station = get_station,
2219         .dump_station = dump_station,
2220         .change_bss = change_bss,
2221         .set_wiphy_params = set_wiphy_params,
2222
2223         .set_pmksa = set_pmksa,
2224         .del_pmksa = del_pmksa,
2225         .flush_pmksa = flush_pmksa,
2226         .remain_on_channel = remain_on_channel,
2227         .cancel_remain_on_channel = cancel_remain_on_channel,
2228         .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2229         .mgmt_tx = mgmt_tx,
2230         .mgmt_frame_register = wilc_mgmt_frame_register,
2231         .set_power_mgmt = set_power_mgmt,
2232         .set_cqm_rssi_config = set_cqm_rssi_config,
2233
2234         .suspend = wilc_suspend,
2235         .resume = wilc_resume,
2236         .set_wakeup = wilc_set_wakeup,
2237         .set_tx_power = set_tx_power,
2238         .get_tx_power = get_tx_power,
2239
2240 };
2241
2242 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2243 {
2244         struct wireless_dev *wdev;
2245
2246         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2247         if (!wdev)
2248                 goto _fail_;
2249
2250         wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2251         if (!wdev->wiphy)
2252                 goto _fail_mem_;
2253
2254         WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2255         WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2256         WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2257         WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2258         WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2259
2260         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2261
2262         return wdev;
2263
2264 _fail_mem_:
2265         kfree(wdev);
2266 _fail_:
2267         return NULL;
2268 }
2269
2270 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2271 {
2272         struct wilc_priv *priv;
2273         struct wireless_dev *wdev;
2274         s32 s32Error = 0;
2275
2276         wdev = WILC_WFI_CfgAlloc();
2277         if (!wdev) {
2278                 netdev_err(net, "wiphy new allocate failed\n");
2279                 return NULL;
2280         }
2281
2282         priv = wdev_priv(wdev);
2283         sema_init(&(priv->SemHandleUpdateStats), 1);
2284         priv->wdev = wdev;
2285         wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2286 #ifdef CONFIG_PM
2287         wdev->wiphy->wowlan = &wowlan_support;
2288 #endif
2289         wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2290         wdev->wiphy->max_scan_ie_len = 1000;
2291         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2292         wdev->wiphy->cipher_suites = cipher_suites;
2293         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2294         wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2295
2296         wdev->wiphy->max_remain_on_channel_duration = 500;
2297         wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2298                 BIT(NL80211_IFTYPE_P2P_CLIENT);
2299         wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2300         wdev->iftype = NL80211_IFTYPE_STATION;
2301
2302         set_wiphy_dev(wdev->wiphy, dev);
2303
2304         s32Error = wiphy_register(wdev->wiphy);
2305         if (s32Error)
2306                 netdev_err(net, "Cannot register wiphy device\n");
2307
2308         priv->dev = net;
2309         return wdev;
2310 }
2311
2312 int wilc_init_host_int(struct net_device *net)
2313 {
2314         int s32Error = 0;
2315
2316         struct wilc_priv *priv;
2317
2318         priv = wdev_priv(net->ieee80211_ptr);
2319         if (op_ifcs == 0) {
2320                 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2321                 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2322         }
2323         op_ifcs++;
2324
2325         priv->gbAutoRateAdjusted = false;
2326
2327         priv->bInP2PlistenState = false;
2328
2329         sema_init(&(priv->hSemScanReq), 1);
2330         s32Error = wilc_init(net, &priv->hif_drv);
2331         if (s32Error)
2332                 netdev_err(net, "Error while initializing hostinterface\n");
2333
2334         return s32Error;
2335 }
2336
2337 int wilc_deinit_host_int(struct net_device *net)
2338 {
2339         int s32Error = 0;
2340         struct wilc_vif *vif;
2341         struct wilc_priv *priv;
2342
2343         priv = wdev_priv(net->ieee80211_ptr);
2344         vif = netdev_priv(priv->dev);
2345
2346         priv->gbAutoRateAdjusted = false;
2347
2348         priv->bInP2PlistenState = false;
2349
2350         op_ifcs--;
2351
2352         s32Error = wilc_deinit(vif);
2353
2354         clear_shadow_scan();
2355         if (op_ifcs == 0)
2356                 del_timer_sync(&wilc_during_ip_timer);
2357
2358         if (s32Error)
2359                 netdev_err(net, "Error while deintializing host interface\n");
2360
2361         return s32Error;
2362 }
2363
2364 void wilc_free_wiphy(struct net_device *net)
2365 {
2366         if (!net)
2367                 return;
2368
2369         if (!net->ieee80211_ptr)
2370                 return;
2371
2372         if (!net->ieee80211_ptr->wiphy)
2373                 return;
2374
2375         wiphy_unregister(net->ieee80211_ptr->wiphy);
2376
2377         wiphy_free(net->ieee80211_ptr->wiphy);
2378         kfree(net->ieee80211_ptr);
2379 }