cfg80211: remove enum ieee80211_band
[cascardo/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             = NL80211_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, NL80211_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, NL80211_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
669         struct wilc_priv *priv;
670         struct host_if_drv *pstrWFIDrv;
671         struct network_info *pstrNetworkInfo = NULL;
672         struct wilc_vif *vif;
673
674         wilc_connecting = 1;
675         priv = wiphy_priv(wiphy);
676         vif = netdev_priv(priv->dev);
677         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
678
679         if (!(strncmp(sme->ssid, "DIRECT-", 7)))
680                 pstrWFIDrv->p2p_connect = 1;
681         else
682                 pstrWFIDrv->p2p_connect = 0;
683
684         for (i = 0; i < last_scanned_cnt; i++) {
685                 if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
686                     memcmp(last_scanned_shadow[i].ssid,
687                            sme->ssid,
688                            sme->ssid_len) == 0) {
689                         if (!sme->bssid)
690                                 break;
691                         else
692                                 if (memcmp(last_scanned_shadow[i].bssid,
693                                            sme->bssid,
694                                            ETH_ALEN) == 0)
695                                         break;
696                 }
697         }
698
699         if (i < last_scanned_cnt) {
700                 pstrNetworkInfo = &last_scanned_shadow[i];
701         } else {
702                 s32Error = -ENOENT;
703                 wilc_connecting = 0;
704                 return s32Error;
705         }
706
707         memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
708         memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
709
710         if (sme->crypto.cipher_group != NO_ENCRYPT) {
711                 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
712                         u8security = ENCRYPT_ENABLED | WEP;
713
714                         priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
715                         memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
716
717                         g_key_wep_params.key_len = sme->key_len;
718                         g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
719                         memcpy(g_key_wep_params.key, sme->key, sme->key_len);
720                         g_key_wep_params.key_idx = sme->key_idx;
721                         g_wep_keys_saved = true;
722
723                         wilc_set_wep_default_keyid(vif, sme->key_idx);
724                         wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
725                                                  sme->key_idx);
726                 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)   {
727                         u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
728
729                         priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
730                         memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
731
732                         g_key_wep_params.key_len = sme->key_len;
733                         g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
734                         memcpy(g_key_wep_params.key, sme->key, sme->key_len);
735                         g_key_wep_params.key_idx = sme->key_idx;
736                         g_wep_keys_saved = true;
737
738                         wilc_set_wep_default_keyid(vif, sme->key_idx);
739                         wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
740                                                  sme->key_idx);
741                 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)   {
742                         if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
743                                 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
744                         } else {
745                                 u8security = ENCRYPT_ENABLED | WPA2 | AES;
746                         }
747                 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)   {
748                         if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
749                                 u8security = ENCRYPT_ENABLED | WPA | TKIP;
750                         } else {
751                                 u8security = ENCRYPT_ENABLED | WPA | AES;
752                         }
753
754                 } else {
755                         s32Error = -ENOTSUPP;
756                         netdev_err(dev, "Not supported cipher\n");
757                         wilc_connecting = 0;
758                         return s32Error;
759                 }
760         }
761
762         if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
763             || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
764                 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
765                         if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
766                                 u8security = u8security | TKIP;
767                         } else {
768                                 u8security = u8security | AES;
769                         }
770                 }
771         }
772
773         switch (sme->auth_type) {
774         case NL80211_AUTHTYPE_OPEN_SYSTEM:
775                 tenuAuth_type = OPEN_SYSTEM;
776                 break;
777
778         case NL80211_AUTHTYPE_SHARED_KEY:
779                 tenuAuth_type = SHARED_KEY;
780                 break;
781
782         default:
783                 break;
784         }
785
786         if (sme->crypto.n_akm_suites) {
787                 switch (sme->crypto.akm_suites[0]) {
788                 case WLAN_AKM_SUITE_8021X:
789                         tenuAuth_type = IEEE8021;
790                         break;
791
792                 default:
793                         break;
794                 }
795         }
796
797         curr_channel = pstrNetworkInfo->ch;
798
799         if (!pstrWFIDrv->p2p_connect)
800                 wlan_channel = pstrNetworkInfo->ch;
801
802         wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
803
804         s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
805                                      sme->ssid_len, sme->ie, sme->ie_len,
806                                      CfgConnectResult, (void *)priv,
807                                      u8security, tenuAuth_type,
808                                      pstrNetworkInfo->ch,
809                                      pstrNetworkInfo->join_params);
810         if (s32Error != 0) {
811                 netdev_err(dev, "wilc_set_join_req(): Error\n");
812                 s32Error = -ENOENT;
813                 wilc_connecting = 0;
814                 return s32Error;
815         }
816
817         return s32Error;
818 }
819
820 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
821 {
822         s32 s32Error = 0;
823         struct wilc_priv *priv;
824         struct host_if_drv *pstrWFIDrv;
825         struct wilc_vif *vif;
826         u8 NullBssid[ETH_ALEN] = {0};
827
828         wilc_connecting = 0;
829         priv = wiphy_priv(wiphy);
830         vif = netdev_priv(priv->dev);
831
832         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
833         if (!pstrWFIDrv->p2p_connect)
834                 wlan_channel = INVALID_CHANNEL;
835         wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
836
837         p2p_local_random = 0x01;
838         p2p_recv_random = 0x00;
839         wilc_ie = false;
840         pstrWFIDrv->p2p_timeout = 0;
841
842         s32Error = wilc_disconnect(vif, reason_code);
843         if (s32Error != 0) {
844                 netdev_err(priv->dev, "Error in disconnecting\n");
845                 s32Error = -EINVAL;
846         }
847
848         return s32Error;
849 }
850
851 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
852                    bool pairwise,
853                    const u8 *mac_addr, struct key_params *params)
854
855 {
856         s32 s32Error = 0, KeyLen = params->key_len;
857         struct wilc_priv *priv;
858         const u8 *pu8RxMic = NULL;
859         const u8 *pu8TxMic = NULL;
860         u8 u8mode = NO_ENCRYPT;
861         u8 u8gmode = NO_ENCRYPT;
862         u8 u8pmode = NO_ENCRYPT;
863         enum AUTHTYPE tenuAuth_type = ANY;
864         struct wilc *wl;
865         struct wilc_vif *vif;
866
867         priv = wiphy_priv(wiphy);
868         vif = netdev_priv(netdev);
869         wl = vif->wilc;
870
871         switch (params->cipher) {
872         case WLAN_CIPHER_SUITE_WEP40:
873         case WLAN_CIPHER_SUITE_WEP104:
874                 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
875                         priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
876                         memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
877
878                         tenuAuth_type = OPEN_SYSTEM;
879
880                         if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
881                                 u8mode = ENCRYPT_ENABLED | WEP;
882                         else
883                                 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
884
885                         wilc_add_wep_key_bss_ap(vif, params->key,
886                                                 params->key_len, key_index,
887                                                 u8mode, tenuAuth_type);
888                         break;
889                 }
890                 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
891                         priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
892                         memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
893
894                         wilc_add_wep_key_bss_sta(vif, params->key,
895                                                  params->key_len, key_index);
896                 }
897
898                 break;
899
900         case WLAN_CIPHER_SUITE_TKIP:
901         case WLAN_CIPHER_SUITE_CCMP:
902                 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
903                         if (!priv->wilc_gtk[key_index]) {
904                                 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
905                                 priv->wilc_gtk[key_index]->key = NULL;
906                                 priv->wilc_gtk[key_index]->seq = NULL;
907                         }
908                         if (!priv->wilc_ptk[key_index]) {
909                                 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
910                                 priv->wilc_ptk[key_index]->key = NULL;
911                                 priv->wilc_ptk[key_index]->seq = NULL;
912                         }
913
914
915
916                         if (!pairwise) {
917                                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
918                                         u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
919                                 else
920                                         u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
921
922                                 priv->wilc_groupkey = u8gmode;
923
924                                 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
925                                         pu8TxMic = params->key + 24;
926                                         pu8RxMic = params->key + 16;
927                                         KeyLen = params->key_len - 16;
928                                 }
929                                 kfree(priv->wilc_gtk[key_index]->key);
930
931                                 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
932                                 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
933                                 kfree(priv->wilc_gtk[key_index]->seq);
934
935                                 if ((params->seq_len) > 0) {
936                                         priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
937                                         memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
938                                 }
939
940                                 priv->wilc_gtk[key_index]->cipher = params->cipher;
941                                 priv->wilc_gtk[key_index]->key_len = params->key_len;
942                                 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
943
944                                 wilc_add_rx_gtk(vif, params->key, KeyLen,
945                                                 key_index, params->seq_len,
946                                                 params->seq, pu8RxMic,
947                                                 pu8TxMic, AP_MODE, u8gmode);
948
949                         } else {
950                                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
951                                         u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
952                                 else
953                                         u8pmode = priv->wilc_groupkey | AES;
954
955
956                                 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
957                                         pu8TxMic = params->key + 24;
958                                         pu8RxMic = params->key + 16;
959                                         KeyLen = params->key_len - 16;
960                                 }
961
962                                 kfree(priv->wilc_ptk[key_index]->key);
963
964                                 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
965
966                                 kfree(priv->wilc_ptk[key_index]->seq);
967
968                                 if ((params->seq_len) > 0)
969                                         priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
970
971                                 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
972
973                                 if ((params->seq_len) > 0)
974                                         memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
975
976                                 priv->wilc_ptk[key_index]->cipher = params->cipher;
977                                 priv->wilc_ptk[key_index]->key_len = params->key_len;
978                                 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
979
980                                 wilc_add_ptk(vif, params->key, KeyLen,
981                                              mac_addr, pu8RxMic, pu8TxMic,
982                                              AP_MODE, u8pmode, key_index);
983                         }
984                         break;
985                 }
986
987                 {
988                         u8mode = 0;
989                         if (!pairwise) {
990                                 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
991                                         pu8RxMic = params->key + 24;
992                                         pu8TxMic = params->key + 16;
993                                         KeyLen = params->key_len - 16;
994                                 }
995
996                                 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
997                                         g_add_gtk_key_params.key_idx = key_index;
998                                         g_add_gtk_key_params.pairwise = pairwise;
999                                         if (!mac_addr) {
1000                                                 g_add_gtk_key_params.mac_addr = NULL;
1001                                         } else {
1002                                                 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1003                                                 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1004                                         }
1005                                         g_key_gtk_params.key_len = params->key_len;
1006                                         g_key_gtk_params.seq_len = params->seq_len;
1007                                         g_key_gtk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
1008                                         memcpy(g_key_gtk_params.key, params->key, params->key_len);
1009                                         if (params->seq_len > 0) {
1010                                                 g_key_gtk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
1011                                                 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1012                                         }
1013                                         g_key_gtk_params.cipher = params->cipher;
1014                                         g_gtk_keys_saved = true;
1015                                 }
1016
1017                                 wilc_add_rx_gtk(vif, params->key, KeyLen,
1018                                                 key_index, params->seq_len,
1019                                                 params->seq, pu8RxMic,
1020                                                 pu8TxMic, STATION_MODE,
1021                                                 u8mode);
1022                         } else {
1023                                 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1024                                         pu8RxMic = params->key + 24;
1025                                         pu8TxMic = params->key + 16;
1026                                         KeyLen = params->key_len - 16;
1027                                 }
1028
1029                                 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1030                                         g_add_ptk_key_params.key_idx = key_index;
1031                                         g_add_ptk_key_params.pairwise = pairwise;
1032                                         if (!mac_addr) {
1033                                                 g_add_ptk_key_params.mac_addr = NULL;
1034                                         } else {
1035                                                 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1036                                                 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1037                                         }
1038                                         g_key_ptk_params.key_len = params->key_len;
1039                                         g_key_ptk_params.seq_len = params->seq_len;
1040                                         g_key_ptk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
1041                                         memcpy(g_key_ptk_params.key, params->key, params->key_len);
1042                                         if (params->seq_len > 0) {
1043                                                 g_key_ptk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
1044                                                 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1045                                         }
1046                                         g_key_ptk_params.cipher = params->cipher;
1047                                         g_ptk_keys_saved = true;
1048                                 }
1049
1050                                 wilc_add_ptk(vif, params->key, KeyLen,
1051                                              mac_addr, pu8RxMic, pu8TxMic,
1052                                              STATION_MODE, u8mode, key_index);
1053                         }
1054                 }
1055                 break;
1056
1057         default:
1058                 netdev_err(netdev, "Not supported cipher\n");
1059                 s32Error = -ENOTSUPP;
1060         }
1061
1062         return s32Error;
1063 }
1064
1065 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1066                    u8 key_index,
1067                    bool pairwise,
1068                    const u8 *mac_addr)
1069 {
1070         struct wilc_priv *priv;
1071         struct wilc *wl;
1072         struct wilc_vif *vif;
1073
1074         priv = wiphy_priv(wiphy);
1075         vif = netdev_priv(netdev);
1076         wl = vif->wilc;
1077
1078         if (netdev == wl->vif[0]->ndev) {
1079                 g_ptk_keys_saved = false;
1080                 g_gtk_keys_saved = false;
1081                 g_wep_keys_saved = false;
1082
1083                 kfree(g_key_wep_params.key);
1084                 g_key_wep_params.key = NULL;
1085
1086                 if ((priv->wilc_gtk[key_index]) != NULL) {
1087                         kfree(priv->wilc_gtk[key_index]->key);
1088                         priv->wilc_gtk[key_index]->key = NULL;
1089                         kfree(priv->wilc_gtk[key_index]->seq);
1090                         priv->wilc_gtk[key_index]->seq = NULL;
1091
1092                         kfree(priv->wilc_gtk[key_index]);
1093                         priv->wilc_gtk[key_index] = NULL;
1094                 }
1095
1096                 if ((priv->wilc_ptk[key_index]) != NULL) {
1097                         kfree(priv->wilc_ptk[key_index]->key);
1098                         priv->wilc_ptk[key_index]->key = NULL;
1099                         kfree(priv->wilc_ptk[key_index]->seq);
1100                         priv->wilc_ptk[key_index]->seq = NULL;
1101                         kfree(priv->wilc_ptk[key_index]);
1102                         priv->wilc_ptk[key_index] = NULL;
1103                 }
1104
1105                 kfree(g_key_ptk_params.key);
1106                 g_key_ptk_params.key = NULL;
1107                 kfree(g_key_ptk_params.seq);
1108                 g_key_ptk_params.seq = NULL;
1109
1110                 kfree(g_key_gtk_params.key);
1111                 g_key_gtk_params.key = NULL;
1112                 kfree(g_key_gtk_params.seq);
1113                 g_key_gtk_params.seq = NULL;
1114
1115         }
1116
1117         if (key_index >= 0 && key_index <= 3) {
1118                 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
1119                 priv->WILC_WFI_wep_key_len[key_index] = 0;
1120                 wilc_remove_wep_key(vif, key_index);
1121         } else {
1122                 wilc_remove_key(priv->hif_drv, mac_addr);
1123         }
1124
1125         return 0;
1126 }
1127
1128 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1129                    bool pairwise,
1130                    const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1131 {
1132         struct wilc_priv *priv;
1133         struct  key_params key_params;
1134
1135         priv = wiphy_priv(wiphy);
1136
1137
1138         if (!pairwise) {
1139                 key_params.key = priv->wilc_gtk[key_index]->key;
1140                 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1141                 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1142                 key_params.seq = priv->wilc_gtk[key_index]->seq;
1143                 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1144         } else {
1145                 key_params.key = priv->wilc_ptk[key_index]->key;
1146                 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1147                 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1148                 key_params.seq = priv->wilc_ptk[key_index]->seq;
1149                 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1150         }
1151
1152         callback(cookie, &key_params);
1153
1154         return 0;
1155 }
1156
1157 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1158                            bool unicast, bool multicast)
1159 {
1160         struct wilc_priv *priv;
1161         struct wilc_vif *vif;
1162
1163         priv = wiphy_priv(wiphy);
1164         vif = netdev_priv(priv->dev);
1165
1166         wilc_set_wep_default_keyid(vif, key_index);
1167
1168         return 0;
1169 }
1170
1171 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1172                        const u8 *mac, struct station_info *sinfo)
1173 {
1174         struct wilc_priv *priv;
1175         struct wilc_vif *vif;
1176         u32 i = 0;
1177         u32 associatedsta = 0;
1178         u32 inactive_time = 0;
1179         priv = wiphy_priv(wiphy);
1180         vif = netdev_priv(dev);
1181
1182         if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1183                 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1184                         if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1185                                 associatedsta = i;
1186                                 break;
1187                         }
1188                 }
1189
1190                 if (associatedsta == -1) {
1191                         netdev_err(dev, "sta required is not associated\n");
1192                         return -ENOENT;
1193                 }
1194
1195                 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1196
1197                 wilc_get_inactive_time(vif, mac, &inactive_time);
1198                 sinfo->inactive_time = 1000 * inactive_time;
1199         }
1200
1201         if (vif->iftype == STATION_MODE) {
1202                 struct rf_info strStatistics;
1203
1204                 wilc_get_statistics(vif, &strStatistics);
1205
1206                 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1207                                                 BIT(NL80211_STA_INFO_RX_PACKETS) |
1208                                                 BIT(NL80211_STA_INFO_TX_PACKETS) |
1209                                                 BIT(NL80211_STA_INFO_TX_FAILED) |
1210                                                 BIT(NL80211_STA_INFO_TX_BITRATE);
1211
1212                 sinfo->signal = strStatistics.rssi;
1213                 sinfo->rx_packets = strStatistics.rx_cnt;
1214                 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1215                 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1216                 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1217
1218                 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1219                     (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1220                         wilc_enable_tcp_ack_filter(true);
1221                 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1222                         wilc_enable_tcp_ack_filter(false);
1223         }
1224         return 0;
1225 }
1226
1227 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1228                       struct bss_parameters *params)
1229 {
1230         return 0;
1231 }
1232
1233 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1234 {
1235         s32 s32Error = 0;
1236         struct cfg_param_attr pstrCfgParamVal;
1237         struct wilc_priv *priv;
1238         struct wilc_vif *vif;
1239
1240         priv = wiphy_priv(wiphy);
1241         vif = netdev_priv(priv->dev);
1242
1243         pstrCfgParamVal.flag = 0;
1244
1245         if (changed & WIPHY_PARAM_RETRY_SHORT) {
1246                 pstrCfgParamVal.flag  |= RETRY_SHORT;
1247                 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1248         }
1249         if (changed & WIPHY_PARAM_RETRY_LONG) {
1250                 pstrCfgParamVal.flag |= RETRY_LONG;
1251                 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1252         }
1253         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1254                 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1255                 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1256         }
1257
1258         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1259                 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1260                 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1261         }
1262
1263         s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1264         if (s32Error)
1265                 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1266
1267         return s32Error;
1268 }
1269
1270 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1271                      struct cfg80211_pmksa *pmksa)
1272 {
1273         u32 i;
1274         s32 s32Error = 0;
1275         u8 flag = 0;
1276         struct wilc_vif *vif;
1277         struct wilc_priv *priv = wiphy_priv(wiphy);
1278
1279         vif = netdev_priv(priv->dev);
1280
1281
1282         for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1283                 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1284                                  ETH_ALEN)) {
1285                         flag = PMKID_FOUND;
1286                         break;
1287                 }
1288         }
1289         if (i < WILC_MAX_NUM_PMKIDS) {
1290                 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1291                             ETH_ALEN);
1292                 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1293                             PMKID_LEN);
1294                 if (!(flag == PMKID_FOUND))
1295                         priv->pmkid_list.numpmkid++;
1296         } else {
1297                 netdev_err(netdev, "Invalid PMKID index\n");
1298                 s32Error = -EINVAL;
1299         }
1300
1301         if (!s32Error)
1302                 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1303
1304         return s32Error;
1305 }
1306
1307 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1308                      struct cfg80211_pmksa *pmksa)
1309 {
1310         u32 i;
1311         s32 s32Error = 0;
1312
1313         struct wilc_priv *priv = wiphy_priv(wiphy);
1314
1315         for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1316                 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1317                                  ETH_ALEN)) {
1318                         memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1319                         break;
1320                 }
1321         }
1322
1323         if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1324                 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1325                         memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1326                                     priv->pmkid_list.pmkidlist[i + 1].bssid,
1327                                     ETH_ALEN);
1328                         memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1329                                     priv->pmkid_list.pmkidlist[i].pmkid,
1330                                     PMKID_LEN);
1331                 }
1332                 priv->pmkid_list.numpmkid--;
1333         } else {
1334                 s32Error = -EINVAL;
1335         }
1336
1337         return s32Error;
1338 }
1339
1340 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1341 {
1342         struct wilc_priv *priv = wiphy_priv(wiphy);
1343
1344         memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1345
1346         return 0;
1347 }
1348
1349 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1350 {
1351         u32 index = 0;
1352         u32 i = 0, j = 0;
1353
1354         u8 op_channel_attr_index = 0;
1355         u8 channel_list_attr_index = 0;
1356
1357         while (index < len) {
1358                 if (buf[index] == GO_INTENT_ATTR_ID) {
1359                         buf[index + 3] = (buf[index + 3]  & 0x01) | (0x00 << 1);
1360                 }
1361
1362                 if (buf[index] ==  CHANLIST_ATTR_ID)
1363                         channel_list_attr_index = index;
1364                 else if (buf[index] ==  OPERCHAN_ATTR_ID)
1365                         op_channel_attr_index = index;
1366                 index += buf[index + 1] + 3;
1367         }
1368         if (wlan_channel != INVALID_CHANNEL) {
1369                 if (channel_list_attr_index) {
1370                         for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1371                                 if (buf[i] == 0x51) {
1372                                         for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1373                                                 buf[j] = wlan_channel;
1374                                         }
1375                                         break;
1376                                 }
1377                         }
1378                 }
1379
1380                 if (op_channel_attr_index) {
1381                         buf[op_channel_attr_index + 6] = 0x51;
1382                         buf[op_channel_attr_index + 7] = wlan_channel;
1383                 }
1384         }
1385 }
1386
1387 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1388 {
1389         u32 index = 0;
1390         u32 i = 0, j = 0;
1391
1392         u8 op_channel_attr_index = 0;
1393         u8 channel_list_attr_index = 0;
1394
1395         while (index < len) {
1396                 if (buf[index] == GO_INTENT_ATTR_ID) {
1397                         buf[index + 3] = (buf[index + 3]  & 0x01) | (0x0f << 1);
1398
1399                         break;
1400                 }
1401
1402                 if (buf[index] ==  CHANLIST_ATTR_ID)
1403                         channel_list_attr_index = index;
1404                 else if (buf[index] ==  OPERCHAN_ATTR_ID)
1405                         op_channel_attr_index = index;
1406                 index += buf[index + 1] + 3;
1407         }
1408         if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1409                 if (channel_list_attr_index) {
1410                         for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1411                                 if (buf[i] == 0x51) {
1412                                         for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1413                                                 buf[j] = wlan_channel;
1414                                         }
1415                                         break;
1416                                 }
1417                         }
1418                 }
1419
1420                 if (op_channel_attr_index) {
1421                         buf[op_channel_attr_index + 6] = 0x51;
1422                         buf[op_channel_attr_index + 7] = wlan_channel;
1423                 }
1424         }
1425 }
1426
1427 void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
1428 {
1429         struct wilc_priv *priv;
1430         u32 header, pkt_offset;
1431         struct host_if_drv *pstrWFIDrv;
1432         u32 i = 0;
1433         s32 s32Freq;
1434
1435         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1436         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1437
1438         memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1439
1440         pkt_offset = GET_PKT_OFFSET(header);
1441
1442         if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1443                 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1444                         cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1445                         return;
1446                 } else {
1447                         if (pkt_offset & IS_MGMT_STATUS_SUCCES)
1448                                 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1449                         else
1450                                 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1451                         return;
1452                 }
1453         } else {
1454                 s32Freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ);
1455
1456                 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1457                         if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1458                                 netdev_dbg(dev, "Receiving action wrong ch\n");
1459                                 return;
1460                         }
1461                         if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1462                                 switch (buff[ACTION_SUBTYPE_ID]) {
1463                                 case GAS_INTIAL_REQ:
1464                                         break;
1465
1466                                 case GAS_INTIAL_RSP:
1467                                         break;
1468
1469                                 case PUBLIC_ACT_VENDORSPEC:
1470                                         if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1471                                                 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1472                                                         if (!wilc_ie) {
1473                                                                 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1474                                                                         if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1475                                                                                 p2p_recv_random = buff[i + 6];
1476                                                                                 wilc_ie = true;
1477                                                                                 break;
1478                                                                         }
1479                                                                 }
1480                                                         }
1481                                                 }
1482                                                 if (p2p_local_random > p2p_recv_random) {
1483                                                         if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1484                                                               || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1485                                                                 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1486                                                                         if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1487                                                                                 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1488                                                                                 break;
1489                                                                         }
1490                                                                 }
1491                                                         }
1492                                                 } else {
1493                                                         netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1494                                                 }
1495                                         }
1496
1497
1498                                         if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie))    {
1499                                                 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1500                                                 return;
1501                                         }
1502                                         break;
1503
1504                                 default:
1505                                         netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1506                                         break;
1507                                 }
1508                         }
1509                 }
1510
1511                 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1512         }
1513 }
1514
1515 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1516 {
1517         struct p2p_mgmt_data *pv_data = priv;
1518
1519
1520         kfree(pv_data->buff);
1521         kfree(pv_data);
1522 }
1523
1524 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1525 {
1526         struct wilc_priv *priv;
1527
1528         priv = pUserVoid;
1529
1530         priv->bInP2PlistenState = true;
1531
1532         cfg80211_ready_on_channel(priv->wdev,
1533                                   priv->strRemainOnChanParams.u64ListenCookie,
1534                                   priv->strRemainOnChanParams.pstrListenChan,
1535                                   priv->strRemainOnChanParams.u32ListenDuration,
1536                                   GFP_KERNEL);
1537 }
1538
1539 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1540 {
1541         struct wilc_priv *priv;
1542
1543         priv = pUserVoid;
1544
1545         if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1546                 priv->bInP2PlistenState = false;
1547
1548                 cfg80211_remain_on_channel_expired(priv->wdev,
1549                                                    priv->strRemainOnChanParams.u64ListenCookie,
1550                                                    priv->strRemainOnChanParams.pstrListenChan,
1551                                                    GFP_KERNEL);
1552         }
1553 }
1554
1555 static int remain_on_channel(struct wiphy *wiphy,
1556                              struct wireless_dev *wdev,
1557                              struct ieee80211_channel *chan,
1558                              unsigned int duration, u64 *cookie)
1559 {
1560         s32 s32Error = 0;
1561         struct wilc_priv *priv;
1562         struct wilc_vif *vif;
1563
1564         priv = wiphy_priv(wiphy);
1565         vif = netdev_priv(priv->dev);
1566
1567         if (wdev->iftype == NL80211_IFTYPE_AP) {
1568                 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1569                 return s32Error;
1570         }
1571
1572         curr_channel = chan->hw_value;
1573
1574         priv->strRemainOnChanParams.pstrListenChan = chan;
1575         priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1576         priv->strRemainOnChanParams.u32ListenDuration = duration;
1577         priv->strRemainOnChanParams.u32ListenSessionID++;
1578
1579         s32Error = wilc_remain_on_channel(vif,
1580                                 priv->strRemainOnChanParams.u32ListenSessionID,
1581                                 duration, chan->hw_value,
1582                                 WILC_WFI_RemainOnChannelExpired,
1583                                 WILC_WFI_RemainOnChannelReady, (void *)priv);
1584
1585         return s32Error;
1586 }
1587
1588 static int cancel_remain_on_channel(struct wiphy *wiphy,
1589                                     struct wireless_dev *wdev,
1590                                     u64 cookie)
1591 {
1592         s32 s32Error = 0;
1593         struct wilc_priv *priv;
1594         struct wilc_vif *vif;
1595
1596         priv = wiphy_priv(wiphy);
1597         vif = netdev_priv(priv->dev);
1598
1599         s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
1600         return s32Error;
1601 }
1602
1603 static int mgmt_tx(struct wiphy *wiphy,
1604                    struct wireless_dev *wdev,
1605                    struct cfg80211_mgmt_tx_params *params,
1606                    u64 *cookie)
1607 {
1608         struct ieee80211_channel *chan = params->chan;
1609         unsigned int wait = params->wait;
1610         const u8 *buf = params->buf;
1611         size_t len = params->len;
1612         const struct ieee80211_mgmt *mgmt;
1613         struct p2p_mgmt_data *mgmt_tx;
1614         struct wilc_priv *priv;
1615         struct host_if_drv *pstrWFIDrv;
1616         u32 i;
1617         struct wilc_vif *vif;
1618         u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1619
1620         vif = netdev_priv(wdev->netdev);
1621         priv = wiphy_priv(wiphy);
1622         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1623
1624         *cookie = (unsigned long)buf;
1625         priv->u64tx_cookie = *cookie;
1626         mgmt = (const struct ieee80211_mgmt *) buf;
1627
1628         if (ieee80211_is_mgmt(mgmt->frame_control)) {
1629                 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1630                 if (!mgmt_tx)
1631                         return -EFAULT;
1632
1633                 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1634                 if (!mgmt_tx->buff) {
1635                         kfree(mgmt_tx);
1636                         return -ENOMEM;
1637                 }
1638
1639                 memcpy(mgmt_tx->buff, buf, len);
1640                 mgmt_tx->size = len;
1641
1642
1643                 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1644                         wilc_set_mac_chnl_num(vif, chan->hw_value);
1645                         curr_channel = chan->hw_value;
1646                 } else if (ieee80211_is_action(mgmt->frame_control))   {
1647                         if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1648                                 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1649                                     buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1650                                         wilc_set_mac_chnl_num(vif,
1651                                                               chan->hw_value);
1652                                         curr_channel = chan->hw_value;
1653                                 }
1654                                 switch (buf[ACTION_SUBTYPE_ID]) {
1655                                 case GAS_INTIAL_REQ:
1656                                         break;
1657
1658                                 case GAS_INTIAL_RSP:
1659                                         break;
1660
1661                                 case PUBLIC_ACT_VENDORSPEC:
1662                                 {
1663                                         if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1664                                                 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1665                                                         if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1666                                                                 get_random_bytes(&p2p_local_random, 1);
1667                                                                 p2p_local_random++;
1668                                                         }
1669                                                 }
1670
1671                                                 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1672                                                       || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1673                                                         if (p2p_local_random > p2p_recv_random) {
1674                                                                 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1675                                                                         if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1676                                                                                 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1677                                                                                         WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1678                                                                                 else
1679                                                                                         WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1680                                                                                 break;
1681                                                                         }
1682                                                                 }
1683
1684                                                                 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1685                                                                         memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1686                                                                         mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1687                                                                         mgmt_tx->size = buf_len;
1688                                                                 }
1689                                                         }
1690                                                 }
1691
1692                                         } else {
1693                                                 netdev_dbg(vif->ndev, "Not a P2P public action frame\n");
1694                                         }
1695
1696                                         break;
1697                                 }
1698
1699                                 default:
1700                                 {
1701                                         netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1702                                         break;
1703                                 }
1704                                 }
1705                         }
1706
1707                         pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1708                 }
1709
1710                 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1711                                            mgmt_tx->buff, mgmt_tx->size,
1712                                            WILC_WFI_mgmt_tx_complete);
1713         }
1714         return 0;
1715 }
1716
1717 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1718                                struct wireless_dev *wdev,
1719                                u64 cookie)
1720 {
1721         struct wilc_priv *priv;
1722         struct host_if_drv *pstrWFIDrv;
1723
1724         priv = wiphy_priv(wiphy);
1725         pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1726         pstrWFIDrv->p2p_timeout = jiffies;
1727
1728         if (!priv->bInP2PlistenState) {
1729                 cfg80211_remain_on_channel_expired(priv->wdev,
1730                                                    priv->strRemainOnChanParams.u64ListenCookie,
1731                                                    priv->strRemainOnChanParams.pstrListenChan,
1732                                                    GFP_KERNEL);
1733         }
1734
1735         return 0;
1736 }
1737
1738 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1739                               u16 frame_type, bool reg)
1740 {
1741         struct wilc_priv *priv;
1742         struct wilc_vif *vif;
1743         struct wilc *wl;
1744
1745         priv = wiphy_priv(wiphy);
1746         vif = netdev_priv(priv->wdev->netdev);
1747         wl = vif->wilc;
1748
1749         if (!frame_type)
1750                 return;
1751
1752         switch (frame_type) {
1753         case PROBE_REQ:
1754         {
1755                 vif->g_struct_frame_reg[0].frame_type = frame_type;
1756                 vif->g_struct_frame_reg[0].reg = reg;
1757         }
1758         break;
1759
1760         case ACTION:
1761         {
1762                 vif->g_struct_frame_reg[1].frame_type = frame_type;
1763                 vif->g_struct_frame_reg[1].reg = reg;
1764         }
1765         break;
1766
1767         default:
1768         {
1769                 break;
1770         }
1771         }
1772
1773         if (!wl->initialized)
1774                 return;
1775         wilc_frame_register(vif, frame_type, reg);
1776 }
1777
1778 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1779                                s32 rssi_thold, u32 rssi_hyst)
1780 {
1781         return 0;
1782 }
1783
1784 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1785                         int idx, u8 *mac, struct station_info *sinfo)
1786 {
1787         struct wilc_priv *priv;
1788         struct wilc_vif *vif;
1789
1790         if (idx != 0)
1791                 return -ENOENT;
1792
1793         priv = wiphy_priv(wiphy);
1794         vif = netdev_priv(priv->dev);
1795
1796         sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1797
1798         wilc_get_rssi(vif, &sinfo->signal);
1799
1800         return 0;
1801 }
1802
1803 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1804                           bool enabled, int timeout)
1805 {
1806         struct wilc_priv *priv;
1807         struct wilc_vif *vif;
1808
1809         if (!wiphy)
1810                 return -ENOENT;
1811
1812         priv = wiphy_priv(wiphy);
1813         vif = netdev_priv(priv->dev);
1814         if (!priv->hif_drv)
1815                 return -EIO;
1816
1817         if (wilc_enable_ps)
1818                 wilc_set_power_mgmt(vif, enabled, timeout);
1819
1820
1821         return 0;
1822 }
1823
1824 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1825                                enum nl80211_iftype type, u32 *flags, struct vif_params *params)
1826 {
1827         struct wilc_priv *priv;
1828         struct wilc_vif *vif;
1829         struct wilc *wl;
1830
1831         vif = netdev_priv(dev);
1832         priv = wiphy_priv(wiphy);
1833         wl = vif->wilc;
1834         p2p_local_random = 0x01;
1835         p2p_recv_random = 0x00;
1836         wilc_ie = false;
1837         wilc_optaining_ip = false;
1838         del_timer(&wilc_during_ip_timer);
1839
1840         switch (type) {
1841         case NL80211_IFTYPE_STATION:
1842                 wilc_connecting = 0;
1843                 dev->ieee80211_ptr->iftype = type;
1844                 priv->wdev->iftype = type;
1845                 vif->monitor_flag = 0;
1846                 vif->iftype = STATION_MODE;
1847                 wilc_set_operation_mode(vif, STATION_MODE);
1848
1849                 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
1850
1851                 wilc_enable_ps = true;
1852                 wilc_set_power_mgmt(vif, 1, 0);
1853                 break;
1854
1855         case NL80211_IFTYPE_P2P_CLIENT:
1856                 wilc_connecting = 0;
1857                 dev->ieee80211_ptr->iftype = type;
1858                 priv->wdev->iftype = type;
1859                 vif->monitor_flag = 0;
1860                 vif->iftype = CLIENT_MODE;
1861                 wilc_set_operation_mode(vif, STATION_MODE);
1862
1863                 wilc_enable_ps = false;
1864                 wilc_set_power_mgmt(vif, 0, 0);
1865                 break;
1866
1867         case NL80211_IFTYPE_AP:
1868                 wilc_enable_ps = false;
1869                 dev->ieee80211_ptr->iftype = type;
1870                 priv->wdev->iftype = type;
1871                 vif->iftype = AP_MODE;
1872
1873                 if (wl->initialized) {
1874                         wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
1875                                                  0);
1876                         wilc_set_operation_mode(vif, AP_MODE);
1877                         wilc_set_power_mgmt(vif, 0, 0);
1878                 }
1879                 break;
1880
1881         case NL80211_IFTYPE_P2P_GO:
1882                 wilc_optaining_ip = true;
1883                 mod_timer(&wilc_during_ip_timer,
1884                           jiffies + msecs_to_jiffies(during_ip_time));
1885                 wilc_set_operation_mode(vif, AP_MODE);
1886                 dev->ieee80211_ptr->iftype = type;
1887                 priv->wdev->iftype = type;
1888                 vif->iftype = GO_MODE;
1889
1890                 wilc_enable_ps = false;
1891                 wilc_set_power_mgmt(vif, 0, 0);
1892                 break;
1893
1894         default:
1895                 netdev_err(dev, "Unknown interface type= %d\n", type);
1896                 return -EINVAL;
1897         }
1898
1899         return 0;
1900 }
1901
1902 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1903                     struct cfg80211_ap_settings *settings)
1904 {
1905         struct cfg80211_beacon_data *beacon = &(settings->beacon);
1906         struct wilc_priv *priv;
1907         s32 s32Error = 0;
1908         struct wilc *wl;
1909         struct wilc_vif *vif;
1910
1911         priv = wiphy_priv(wiphy);
1912         vif = netdev_priv(dev);
1913         wl = vif->wilc;
1914
1915         s32Error = set_channel(wiphy, &settings->chandef);
1916
1917         if (s32Error != 0)
1918                 netdev_err(dev, "Error in setting channel\n");
1919
1920         wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
1921         wilc_set_power_mgmt(vif, 0, 0);
1922
1923         s32Error = wilc_add_beacon(vif, settings->beacon_interval,
1924                                    settings->dtim_period, beacon->head_len,
1925                                    (u8 *)beacon->head, beacon->tail_len,
1926                                    (u8 *)beacon->tail);
1927
1928         return s32Error;
1929 }
1930
1931 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1932                          struct cfg80211_beacon_data *beacon)
1933 {
1934         struct wilc_priv *priv;
1935         struct wilc_vif *vif;
1936         s32 s32Error = 0;
1937
1938         priv = wiphy_priv(wiphy);
1939         vif = netdev_priv(priv->dev);
1940
1941         s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
1942                                    (u8 *)beacon->head, beacon->tail_len,
1943                                    (u8 *)beacon->tail);
1944
1945         return s32Error;
1946 }
1947
1948 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1949 {
1950         s32 s32Error = 0;
1951         struct wilc_priv *priv;
1952         struct wilc_vif *vif;
1953         u8 NullBssid[ETH_ALEN] = {0};
1954
1955         if (!wiphy)
1956                 return -EFAULT;
1957
1958         priv = wiphy_priv(wiphy);
1959         vif = netdev_priv(priv->dev);
1960
1961         wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
1962
1963         s32Error = wilc_del_beacon(vif);
1964
1965         if (s32Error)
1966                 netdev_err(dev, "Host delete beacon fail\n");
1967
1968         return s32Error;
1969 }
1970
1971 static int add_station(struct wiphy *wiphy, struct net_device *dev,
1972                        const u8 *mac, struct station_parameters *params)
1973 {
1974         s32 s32Error = 0;
1975         struct wilc_priv *priv;
1976         struct add_sta_param strStaParams = { {0} };
1977         struct wilc_vif *vif;
1978
1979         if (!wiphy)
1980                 return -EFAULT;
1981
1982         priv = wiphy_priv(wiphy);
1983         vif = netdev_priv(dev);
1984
1985         if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1986                 memcpy(strStaParams.bssid, mac, ETH_ALEN);
1987                 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
1988                 strStaParams.aid = params->aid;
1989                 strStaParams.rates_len = params->supported_rates_len;
1990                 strStaParams.rates = params->supported_rates;
1991
1992                 if (!params->ht_capa) {
1993                         strStaParams.ht_supported = false;
1994                 } else {
1995                         strStaParams.ht_supported = true;
1996                         strStaParams.ht_capa_info = params->ht_capa->cap_info;
1997                         strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
1998                         memcpy(strStaParams.ht_supp_mcs_set,
1999                                &params->ht_capa->mcs,
2000                                WILC_SUPP_MCS_SET_SIZE);
2001                         strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2002                         strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2003                         strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2004                 }
2005
2006                 strStaParams.flags_mask = params->sta_flags_mask;
2007                 strStaParams.flags_set = params->sta_flags_set;
2008
2009                 s32Error = wilc_add_station(vif, &strStaParams);
2010                 if (s32Error)
2011                         netdev_err(dev, "Host add station fail\n");
2012         }
2013
2014         return s32Error;
2015 }
2016
2017 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2018                        struct station_del_parameters *params)
2019 {
2020         const u8 *mac = params->mac;
2021         s32 s32Error = 0;
2022         struct wilc_priv *priv;
2023         struct wilc_vif *vif;
2024
2025         if (!wiphy)
2026                 return -EFAULT;
2027
2028         priv = wiphy_priv(wiphy);
2029         vif = netdev_priv(dev);
2030
2031         if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2032                 if (!mac)
2033                         s32Error = wilc_del_allstation(vif,
2034                                      priv->assoc_stainfo.au8Sta_AssociatedBss);
2035
2036                 s32Error = wilc_del_station(vif, mac);
2037
2038                 if (s32Error)
2039                         netdev_err(dev, "Host delete station fail\n");
2040         }
2041         return s32Error;
2042 }
2043
2044 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2045                           const u8 *mac, struct station_parameters *params)
2046 {
2047         s32 s32Error = 0;
2048         struct wilc_priv *priv;
2049         struct add_sta_param strStaParams = { {0} };
2050         struct wilc_vif *vif;
2051
2052         if (!wiphy)
2053                 return -EFAULT;
2054
2055         priv = wiphy_priv(wiphy);
2056         vif = netdev_priv(dev);
2057
2058         if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2059                 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2060                 strStaParams.aid = params->aid;
2061                 strStaParams.rates_len = params->supported_rates_len;
2062                 strStaParams.rates = params->supported_rates;
2063
2064                 if (!params->ht_capa) {
2065                         strStaParams.ht_supported = false;
2066                 } else {
2067                         strStaParams.ht_supported = true;
2068                         strStaParams.ht_capa_info = params->ht_capa->cap_info;
2069                         strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2070                         memcpy(strStaParams.ht_supp_mcs_set,
2071                                &params->ht_capa->mcs,
2072                                WILC_SUPP_MCS_SET_SIZE);
2073                         strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2074                         strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2075                         strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2076                 }
2077
2078                 strStaParams.flags_mask = params->sta_flags_mask;
2079                 strStaParams.flags_set = params->sta_flags_set;
2080
2081                 s32Error = wilc_edit_station(vif, &strStaParams);
2082                 if (s32Error)
2083                         netdev_err(dev, "Host edit station fail\n");
2084         }
2085         return s32Error;
2086 }
2087
2088 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2089                                              const char *name,
2090                                              unsigned char name_assign_type,
2091                                              enum nl80211_iftype type,
2092                                              u32 *flags,
2093                                              struct vif_params *params)
2094 {
2095         struct wilc_vif *vif;
2096         struct wilc_priv *priv;
2097         struct net_device *new_ifc = NULL;
2098
2099         priv = wiphy_priv(wiphy);
2100         vif = netdev_priv(priv->wdev->netdev);
2101
2102
2103         if (type == NL80211_IFTYPE_MONITOR) {
2104                 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2105                 if (new_ifc) {
2106                         vif = netdev_priv(priv->wdev->netdev);
2107                         vif->monitor_flag = 1;
2108                 }
2109         }
2110         return priv->wdev;
2111 }
2112
2113 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2114 {
2115         return 0;
2116 }
2117
2118 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2119 {
2120         struct wilc_priv *priv = wiphy_priv(wiphy);
2121         struct wilc_vif *vif = netdev_priv(priv->dev);
2122
2123         if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2124                 vif->wilc->suspend_event = true;
2125         else
2126                 vif->wilc->suspend_event = false;
2127
2128         return 0;
2129 }
2130
2131 static int wilc_resume(struct wiphy *wiphy)
2132 {
2133         struct wilc_priv *priv = wiphy_priv(wiphy);
2134         struct wilc_vif *vif = netdev_priv(priv->dev);
2135
2136         netdev_info(vif->ndev, "cfg resume\n");
2137         return 0;
2138 }
2139
2140 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2141 {
2142         struct wilc_priv *priv = wiphy_priv(wiphy);
2143         struct wilc_vif *vif = netdev_priv(priv->dev);
2144
2145         netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2146 }
2147
2148 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2149                         enum nl80211_tx_power_setting type, int mbm)
2150 {
2151         int ret;
2152         s32 tx_power = MBM_TO_DBM(mbm);
2153         struct wilc_priv *priv = wiphy_priv(wiphy);
2154         struct wilc_vif *vif = netdev_priv(priv->dev);
2155
2156         if (tx_power < 0)
2157                 tx_power = 0;
2158         else if (tx_power > 18)
2159                 tx_power = 18;
2160         ret = wilc_set_tx_power(vif, tx_power);
2161         if (ret)
2162                 netdev_err(vif->ndev, "Failed to set tx power\n");
2163
2164         return ret;
2165 }
2166
2167 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2168                         int *dbm)
2169 {
2170         int ret;
2171         struct wilc_priv *priv = wiphy_priv(wiphy);
2172         struct wilc_vif *vif = netdev_priv(priv->dev);
2173         struct wilc *wl;
2174
2175         wl = vif->wilc;
2176
2177         /* If firmware is not started, return. */
2178         if (!wl->initialized)
2179                 return -EIO;
2180
2181         ret = wilc_get_tx_power(vif, (u8 *)dbm);
2182         if (ret)
2183                 netdev_err(vif->ndev, "Failed to get tx power\n");
2184
2185         return ret;
2186 }
2187
2188 static struct cfg80211_ops wilc_cfg80211_ops = {
2189         .set_monitor_channel = set_channel,
2190         .scan = scan,
2191         .connect = connect,
2192         .disconnect = disconnect,
2193         .add_key = add_key,
2194         .del_key = del_key,
2195         .get_key = get_key,
2196         .set_default_key = set_default_key,
2197         .add_virtual_intf = add_virtual_intf,
2198         .del_virtual_intf = del_virtual_intf,
2199         .change_virtual_intf = change_virtual_intf,
2200
2201         .start_ap = start_ap,
2202         .change_beacon = change_beacon,
2203         .stop_ap = stop_ap,
2204         .add_station = add_station,
2205         .del_station = del_station,
2206         .change_station = change_station,
2207         .get_station = get_station,
2208         .dump_station = dump_station,
2209         .change_bss = change_bss,
2210         .set_wiphy_params = set_wiphy_params,
2211
2212         .set_pmksa = set_pmksa,
2213         .del_pmksa = del_pmksa,
2214         .flush_pmksa = flush_pmksa,
2215         .remain_on_channel = remain_on_channel,
2216         .cancel_remain_on_channel = cancel_remain_on_channel,
2217         .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2218         .mgmt_tx = mgmt_tx,
2219         .mgmt_frame_register = wilc_mgmt_frame_register,
2220         .set_power_mgmt = set_power_mgmt,
2221         .set_cqm_rssi_config = set_cqm_rssi_config,
2222
2223         .suspend = wilc_suspend,
2224         .resume = wilc_resume,
2225         .set_wakeup = wilc_set_wakeup,
2226         .set_tx_power = set_tx_power,
2227         .get_tx_power = get_tx_power,
2228
2229 };
2230
2231 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2232 {
2233         struct wireless_dev *wdev;
2234
2235         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2236         if (!wdev)
2237                 goto _fail_;
2238
2239         wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2240         if (!wdev->wiphy)
2241                 goto _fail_mem_;
2242
2243         WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2244         WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2245         WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2246         WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2247         WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2248
2249         wdev->wiphy->bands[NL80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2250
2251         return wdev;
2252
2253 _fail_mem_:
2254         kfree(wdev);
2255 _fail_:
2256         return NULL;
2257 }
2258
2259 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2260 {
2261         struct wilc_priv *priv;
2262         struct wireless_dev *wdev;
2263         s32 s32Error = 0;
2264
2265         wdev = WILC_WFI_CfgAlloc();
2266         if (!wdev) {
2267                 netdev_err(net, "wiphy new allocate failed\n");
2268                 return NULL;
2269         }
2270
2271         priv = wdev_priv(wdev);
2272         sema_init(&(priv->SemHandleUpdateStats), 1);
2273         priv->wdev = wdev;
2274         wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2275 #ifdef CONFIG_PM
2276         wdev->wiphy->wowlan = &wowlan_support;
2277 #endif
2278         wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2279         wdev->wiphy->max_scan_ie_len = 1000;
2280         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2281         wdev->wiphy->cipher_suites = cipher_suites;
2282         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2283         wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2284
2285         wdev->wiphy->max_remain_on_channel_duration = 500;
2286         wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2287                 BIT(NL80211_IFTYPE_P2P_CLIENT);
2288         wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2289         wdev->iftype = NL80211_IFTYPE_STATION;
2290
2291         set_wiphy_dev(wdev->wiphy, dev);
2292
2293         s32Error = wiphy_register(wdev->wiphy);
2294         if (s32Error)
2295                 netdev_err(net, "Cannot register wiphy device\n");
2296
2297         priv->dev = net;
2298         return wdev;
2299 }
2300
2301 int wilc_init_host_int(struct net_device *net)
2302 {
2303         int s32Error = 0;
2304
2305         struct wilc_priv *priv;
2306
2307         priv = wdev_priv(net->ieee80211_ptr);
2308         if (op_ifcs == 0) {
2309                 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2310                 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2311         }
2312         op_ifcs++;
2313
2314         priv->gbAutoRateAdjusted = false;
2315
2316         priv->bInP2PlistenState = false;
2317
2318         sema_init(&(priv->hSemScanReq), 1);
2319         s32Error = wilc_init(net, &priv->hif_drv);
2320         if (s32Error)
2321                 netdev_err(net, "Error while initializing hostinterface\n");
2322
2323         return s32Error;
2324 }
2325
2326 int wilc_deinit_host_int(struct net_device *net)
2327 {
2328         int s32Error = 0;
2329         struct wilc_vif *vif;
2330         struct wilc_priv *priv;
2331
2332         priv = wdev_priv(net->ieee80211_ptr);
2333         vif = netdev_priv(priv->dev);
2334
2335         priv->gbAutoRateAdjusted = false;
2336
2337         priv->bInP2PlistenState = false;
2338
2339         op_ifcs--;
2340
2341         s32Error = wilc_deinit(vif);
2342
2343         clear_shadow_scan();
2344         if (op_ifcs == 0)
2345                 del_timer_sync(&wilc_during_ip_timer);
2346
2347         if (s32Error)
2348                 netdev_err(net, "Error while deintializing host interface\n");
2349
2350         return s32Error;
2351 }
2352
2353 void wilc_free_wiphy(struct net_device *net)
2354 {
2355         if (!net)
2356                 return;
2357
2358         if (!net->ieee80211_ptr)
2359                 return;
2360
2361         if (!net->ieee80211_ptr->wiphy)
2362                 return;
2363
2364         wiphy_unregister(net->ieee80211_ptr->wiphy);
2365
2366         wiphy_free(net->ieee80211_ptr->wiphy);
2367         kfree(net->ieee80211_ptr);
2368 }