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