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