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