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