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