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