wlan_cfg80211: Add SOFTAP WPS type to support WPS in tethering
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / net / wireless / sc2331 / wlan_cfg80211.c
1 /*
2  * Copyright (C) 2014 Spreadtrum Communications Inc.
3  *
4  * Authors:<jinglong.chen@spreadtrum.com>
5  * Owner:
6  *      jinglong.chen
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include "wlan_common.h"
19 #include "wlan_cfg80211.h"
20 #include "wlan_cmd.h"
21
22 #define RATETAB_ENT(_rate, _rateid, _flags)                             \
23 {                                                                       \
24         .bitrate        = (_rate),                                      \
25         .hw_value       = (_rateid),                                    \
26         .flags          = (_flags),                                     \
27 }
28
29 #define CHAN2G(_channel, _freq, _flags) {                               \
30         .band                   = IEEE80211_BAND_2GHZ,                  \
31         .center_freq            = (_freq),                              \
32         .hw_value               = (_channel),                           \
33         .flags                  = (_flags),                             \
34         .max_antenna_gain       = 0,                                    \
35         .max_power              = 30,                                   \
36 }
37
38 #define CHAN5G(_channel, _flags) {                                      \
39         .band                   = IEEE80211_BAND_5GHZ,                  \
40         .center_freq            = 5000 + (5 * (_channel)),              \
41         .hw_value               = (_channel),                           \
42         .flags                  = (_flags),                             \
43         .max_antenna_gain       = 0,                                    \
44         .max_power              = 30,                                   \
45 }
46
47 static struct ieee80211_rate itm_rates[] = {
48         RATETAB_ENT(10, 0x1, 0),
49         RATETAB_ENT(20, 0x2, 0),
50         RATETAB_ENT(55, 0x5, 0),
51         RATETAB_ENT(110, 0xb, 0),
52         RATETAB_ENT(60, 0x6, 0),
53         RATETAB_ENT(90, 0x9, 0),
54         RATETAB_ENT(120, 0xc, 0),
55         RATETAB_ENT(180, 0x12, 0),
56         RATETAB_ENT(240, 0x18, 0),
57         RATETAB_ENT(360, 0x24, 0),
58         RATETAB_ENT(480, 0x30, 0),
59         RATETAB_ENT(540, 0x36, 0),
60
61         RATETAB_ENT(65, 0x80, 0),
62         RATETAB_ENT(130, 0x81, 0),
63         RATETAB_ENT(195, 0x82, 0),
64         RATETAB_ENT(260, 0x83, 0),
65         RATETAB_ENT(390, 0x84, 0),
66         RATETAB_ENT(520, 0x85, 0),
67         RATETAB_ENT(585, 0x86, 0),
68         RATETAB_ENT(650, 0x87, 0),
69         RATETAB_ENT(130, 0x88, 0),
70         RATETAB_ENT(260, 0x89, 0),
71         RATETAB_ENT(390, 0x8a, 0),
72         RATETAB_ENT(520, 0x8b, 0),
73         RATETAB_ENT(780, 0x8c, 0),
74         RATETAB_ENT(1040, 0x8d, 0),
75         RATETAB_ENT(1170, 0x8e, 0),
76         RATETAB_ENT(1300, 0x8f, 0),
77 };
78
79 #define ITM_G_RATE_NUM  28
80 #define itm_g_rates             (itm_rates)
81 #define ITM_A_RATE_NUM  24
82 #define itm_a_rates             (itm_rates + 4)
83
84 #define itm_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
85                         IEEE80211_HT_CAP_SGI_20          | \
86                         IEEE80211_HT_CAP_SGI_40)
87
88 static struct ieee80211_channel itm_2ghz_channels[] = {
89         CHAN2G(1, 2412, 0),
90         CHAN2G(2, 2417, 0),
91         CHAN2G(3, 2422, 0),
92         CHAN2G(4, 2427, 0),
93         CHAN2G(5, 2432, 0),
94         CHAN2G(6, 2437, 0),
95         CHAN2G(7, 2442, 0),
96         CHAN2G(8, 2447, 0),
97         CHAN2G(9, 2452, 0),
98         CHAN2G(10, 2457, 0),
99         CHAN2G(11, 2462, 0),
100         CHAN2G(12, 2467, 0),
101         CHAN2G(13, 2472, 0),
102         CHAN2G(14, 2484, 0),
103 };
104
105 /*static struct ieee80211_channel itm_5ghz_channels[] =
106 {
107         CHAN5G(34, 0), CHAN5G(36, 0),
108         CHAN5G(38, 0), CHAN5G(40, 0),
109         CHAN5G(42, 0), CHAN5G(44, 0),
110         CHAN5G(46, 0), CHAN5G(48, 0),
111         CHAN5G(52, 0), CHAN5G(56, 0),
112         CHAN5G(60, 0), CHAN5G(64, 0),
113         CHAN5G(100, 0), CHAN5G(104, 0),
114         CHAN5G(108, 0), CHAN5G(112, 0),
115         CHAN5G(116, 0), CHAN5G(120, 0),
116         CHAN5G(124, 0), CHAN5G(128, 0),
117         CHAN5G(132, 0), CHAN5G(136, 0),
118         CHAN5G(140, 0), CHAN5G(149, 0),
119         CHAN5G(153, 0), CHAN5G(157, 0),
120         CHAN5G(161, 0), CHAN5G(165, 0),
121         CHAN5G(184, 0), CHAN5G(188, 0),
122         CHAN5G(192, 0), CHAN5G(196, 0),
123         CHAN5G(200, 0), CHAN5G(204, 0),
124         CHAN5G(208, 0), CHAN5G(212, 0),
125         CHAN5G(216, 0),
126 };*/
127
128 static struct ieee80211_supported_band itm_band_2ghz = {
129         .n_channels = ARRAY_SIZE(itm_2ghz_channels),
130         .channels = itm_2ghz_channels,
131         .n_bitrates = ITM_G_RATE_NUM,
132         .bitrates = itm_g_rates,
133         .ht_cap.cap = itm_g_htcap,
134         .ht_cap.ht_supported = true,
135 };
136
137 /*static struct ieee80211_supported_band itm_band_5ghz = {
138         .n_channels = ARRAY_SIZE(itm_5ghz_channels),
139         .channels = itm_5ghz_channels,
140         .n_bitrates = ITM_A_RATE_NUM,
141         .bitrates = itm_a_rates,
142         .ht_cap.cap = itm_g_htcap,
143         .ht_cap.ht_supported = true,
144 };*/
145
146 static const u32 itm_cipher_suites[] = {
147         WLAN_CIPHER_SUITE_WEP40,
148         WLAN_CIPHER_SUITE_WEP104,
149         WLAN_CIPHER_SUITE_TKIP,
150         WLAN_CIPHER_SUITE_CCMP,
151         WLAN_CIPHER_SUITE_SMS4,
152 #ifdef BSS_ACCESS_POINT_MODE
153         WLAN_CIPHER_SUITE_ITM_CCMP,
154         WLAN_CIPHER_SUITE_ITM_TKIP,
155 #endif
156 };
157
158 /* Supported mgmt frame types to be advertised to cfg80211 */
159 static const struct ieee80211_txrx_stypes
160  itm_mgmt_stypes[NUM_NL80211_IFTYPES] = {
161         [NL80211_IFTYPE_STATION] = {
162                                     .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
163                                     BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
164                                     .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
165                                     BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
166                                     },
167         [NL80211_IFTYPE_AP] = {
168                                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
169                                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
170                                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
171                                BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
172                                },
173         [NL80211_IFTYPE_P2P_CLIENT] = {
174                                        .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
175                                        BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
176                                        .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
177                                        BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
178                                        },
179         [NL80211_IFTYPE_P2P_GO] = {
180                                    .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
181                                    BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
182                                    .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
183                                    BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
184                                    },
185 /* Supported mgmt frame types for p2p*/
186         [NL80211_IFTYPE_ADHOC] = {
187                                   .tx = 0xffff,
188                                   .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
189                                   },
190         [NL80211_IFTYPE_STATION] = {
191                                     .tx = 0xffff,
192                                     .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
193                                     BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
194                                     },
195         [NL80211_IFTYPE_AP] = {
196                                .tx = 0xffff,
197                                .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
198                                BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
199                                BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
200                                BIT(IEEE80211_STYPE_DISASSOC >> 4) |
201                                BIT(IEEE80211_STYPE_AUTH >> 4) |
202                                BIT(IEEE80211_STYPE_DEAUTH >> 4) |
203                                BIT(IEEE80211_STYPE_ACTION >> 4)
204                                },
205         [NL80211_IFTYPE_AP_VLAN] = {
206                                     /* copy AP */
207                                     .tx = 0xffff,
208                                     .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
209                                     BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
210                                     BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
211                                     BIT(IEEE80211_STYPE_DISASSOC >> 4) |
212                                     BIT(IEEE80211_STYPE_AUTH >> 4) |
213                                     BIT(IEEE80211_STYPE_DEAUTH >> 4) |
214                                     BIT(IEEE80211_STYPE_ACTION >> 4)
215                                     },
216         [NL80211_IFTYPE_P2P_CLIENT] = {
217                                        .tx = 0xffff,
218                                        .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
219                                        BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
220                                        },
221         [NL80211_IFTYPE_P2P_GO] = {
222                                    .tx = 0xffff,
223                                    .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
224                                    BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
225                                    BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
226                                    BIT(IEEE80211_STYPE_DISASSOC >> 4) |
227                                    BIT(IEEE80211_STYPE_AUTH >> 4) |
228                                    BIT(IEEE80211_STYPE_DEAUTH >> 4) |
229                                    BIT(IEEE80211_STYPE_ACTION >> 4)
230                                    },
231 };
232
233 #define WLAN_EID_VENDOR_SPECIFIC 221
234
235 void get_ssid(unsigned char *data, unsigned char *ssid)
236 {
237         unsigned char len = 0;
238         unsigned char i = 0;
239         unsigned char j = 0;
240
241         len = data[37];
242         j = 38;
243
244         if (len >= 33)
245                 len = 0;
246
247         for (i = 0; i < len; i++, j++)
248                 ssid[i] = data[j];
249         ssid[len] = '\0';
250 }
251
252 void get_bssid(unsigned char *data, unsigned char *bssid)
253 {
254         if (1 == ((data[1] & 0x02) >> 1))
255                 memcpy(bssid, data + 10, 6);
256         else if ((data[1] & 0x01) == 1)
257                 memcpy(bssid, data + 4, 6);
258         else
259                 memcpy(bssid, data + 16, 6);
260         return;
261 }
262
263 #ifdef WIFI_DIRECT_SUPPORT
264
265 struct ieee80211_channel global_channel;
266 u64 global_cookie;
267
268 static int get_file_size(struct file *f)
269 {
270         int error = -EBADF;
271         struct kstat stat;
272 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
273         error = vfs_getattr(&f->f_path, &stat);
274 #else
275         error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, &stat);
276 #endif
277         if (error == 0) {
278                 return stat.size;
279         } else {
280                 pr_err("get conf file stat error\n");
281                 return error;
282         }
283 }
284
285 #define P2P_MODE_PATH "/data/misc/wifi/fwpath"
286 int itm_get_p2p_mode_from_file(void)
287 {
288         struct file *fp = 0;
289         mm_segment_t fs;
290         int size = 0;
291         loff_t pos = 0;
292         u8 *buf;
293         int ret = false;
294         fp = filp_open(P2P_MODE_PATH, O_RDONLY, 0);
295         if (IS_ERR(fp)) {
296                 pr_err("open %s file error\n", P2P_MODE_PATH);
297                 goto end;
298         }
299         fs = get_fs();
300         set_fs(KERNEL_DS);
301         size = get_file_size(fp);
302         if (size <= 0) {
303                 pr_err("load file:%s error\n", P2P_MODE_PATH);
304                 goto error;
305         }
306         buf = kzalloc(size + 1, GFP_KERNEL);
307         vfs_read(fp, buf, size, &pos);
308         if (strcmp(buf, "p2p_mode") == 0)
309                 ret = true;
310         kfree(buf);
311 error:
312         filp_close(fp, NULL);
313         set_fs(fs);
314 end:
315         return ret;
316 }
317
318 static bool itm_find_p2p_ie(const u8 *ie, size_t ie_len, u8 *p2p_ie,
319                             size_t *p2p_ie_len)
320 {
321         bool flags = false;
322         u16 index = 0;
323 /*Find out P2P IE.*/
324
325         if (NULL == ie || ie_len <= 0 || NULL == p2p_ie)
326                 return flags;
327
328         while (index < ie_len) {
329                 if (P2P_IE_ID == ie[index]) {
330                         *p2p_ie_len = ie[index + 1];
331                         if (ie_len >= *p2p_ie_len &&
332                             P2P_IE_OUI_BYTE0 == ie[index + 2] &&
333                             P2P_IE_OUI_BYTE1 == ie[index + 3] &&
334                             P2P_IE_OUI_BYTE2 == ie[index + 4] &&
335                             P2P_IE_OUI_TYPE == ie[index + 5]) {
336                                 memcpy(p2p_ie, ie + index, *p2p_ie_len + 2);
337                                 *p2p_ie_len += 2;
338                                 return true;
339                         }
340                 }
341                 index++;
342         }
343
344         return false;
345 }
346
347 static int wlan_cfg80211_remain_on_channel(struct wiphy *wiphy,
348 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
349                                            struct wireless_dev *dev,
350 #else
351                                            struct net_device *dev,
352 #endif
353                                            struct ieee80211_channel
354                                            *channel,
355                                            unsigned int duration, u64 *cookie)
356 {
357         wlan_vif_t *vif;
358         unsigned char vif_id;
359         int ret;
360
361         enum nl80211_channel_type channel_type = 0;
362         vif = ndev_to_vif(dev->netdev);
363         vif_id = vif->id;
364         if (ITM_NONE_MODE == vif->mode)
365                 return -EAGAIN;
366         printkd("[%s][%d] enter\n", __func__, vif_id);
367         memcpy(&global_channel, channel, sizeof(struct ieee80211_channel));
368         global_cookie = *cookie;
369         printkd("remain on channel duration is %d\n", duration);
370         /* send remain chan */
371         ret =
372             wlan_cmd_remain_chan(vif_id, channel, channel_type, duration,
373                                  cookie);
374         if (OK != ret)
375                 return -1;
376
377         /* report remain chan */
378         cfg80211_ready_on_channel(dev, *cookie, channel, duration, GFP_KERNEL);
379         return 0;
380 }
381
382 static int wlan_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
383 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
384                                                   struct wireless_dev *dev,
385 #else
386                                                   struct net_device *dev,
387 #endif
388                                                   u64 cookie)
389 {
390         int ret;
391         wlan_vif_t *vif;
392         unsigned char vif_id;
393         vif = ndev_to_vif(dev->netdev);
394         vif_id = vif->id;
395         if (ITM_NONE_MODE == vif->mode)
396                 return -EAGAIN;
397         printkd("[%s][%d] enter\n", __func__, vif_id);
398         ret = wlan_cmd_cancel_remain_chan(vif_id, cookie);
399         if (OK != ret)
400                 return ERROR;
401         return OK;
402 }
403
404 static int wlan_cfg80211_del_station(struct wiphy *wiphy,
405                                      struct net_device *ndev, u8 *mac)
406 {
407         wlan_vif_t *vif;
408         unsigned char vif_id;
409         vif = ndev_to_vif(ndev);
410         vif_id = vif->id;
411
412         if (!mac) {
413                 wiphy_dbg(wiphy, "Ignore NULL MAC address!\n");
414                 goto out;
415         }
416
417         wiphy_info(wiphy, "%s %pM\n", __func__, mac);
418         wlan_cmd_disassoc(vif_id, mac, WLAN_REASON_DEAUTH_LEAVING);
419 out:
420         return 0;
421 }
422
423 static void register_frame_work_fun(struct work_struct *work)
424 {
425         unsigned char vif_id;
426         struct wlan_cmd_register_frame_t data;
427         register_frame_param_t *param =
428             container_of(work, register_frame_param_t, work);
429         data.type = param->frame_type;
430         data.reg = param->reg ? 1 : 0;
431         param->frame_type = 0xffff;
432         param->reg = 0;
433         vif_id = ((wlan_vif_t *) (param->vif))->id;
434         wlan_cmd_register_frame(vif_id, &data);
435         return;
436 }
437
438 void init_register_frame_param(wlan_vif_t *vif)
439 {
440         register_frame_param_t *param;
441         param = &(vif->cfg80211.register_frame);
442         param->frame_type = 0xffff;
443         param->reg = 0;
444         param->vif = (void *)vif;
445         INIT_WORK(&(param->work), register_frame_work_fun);
446 }
447
448 static int register_frame(wlan_vif_t *vif, unsigned short frame_type, bool reg)
449 {
450         vif->cfg80211.register_frame.frame_type = frame_type;
451         vif->cfg80211.register_frame.reg = reg;
452         schedule_work(&(vif->cfg80211.register_frame.work));
453         return 0;
454 }
455
456 void cfg80211_report_remain_on_channel_expired(unsigned char vif_id,
457                                                unsigned char *data,
458                                                unsigned short len)
459 {
460         wlan_vif_t *vif;
461         vif = id_to_vif(vif_id);
462         cfg80211_remain_on_channel_expired(&(vif->wdev), global_cookie,
463                                            &global_channel, GFP_KERNEL);
464         return;
465 }
466
467 static void send_deauth_work_func(struct work_struct *work)
468 {
469         wlan_vif_t *vif;
470         struct deauth_info *info;
471
472         info = container_of(work, struct deauth_info, work);
473         vif = container_of(info, wlan_vif_t, deauth_info);
474         cfg80211_send_deauth(vif->ndev, info->mac, info->len);
475
476         return;
477 }
478
479 void init_send_deauth_work(wlan_vif_t *vif)
480 {
481         struct deauth_info *info;
482         info = &vif->deauth_info;
483         memset(info, 0, sizeof(*info));
484         INIT_WORK(&info->work, send_deauth_work_func);
485 }
486
487 void cfg80211_report_mgmt_deauth(unsigned char vif_id, unsigned char *data,
488                                  unsigned short len)
489 {
490         wlan_vif_t *vif = id_to_vif(vif_id);
491         memcpy(&vif->deauth_info.len, data, 2);
492         if (vif->deauth_info.len > sizeof(vif->deauth_info.mac)) {
493                 ASSERT("%s len:%d > max:%d\n", __func__,
494                        vif->deauth_info.len, sizeof(vif->deauth_info.mac));
495                 return;
496         }
497
498         memcpy(vif->deauth_info.mac, data + 2, vif->deauth_info.len);
499         schedule_work(&vif->deauth_info.work);
500
501         return;
502 }
503
504 void cfg80211_report_mgmt_disassoc(unsigned char vif_id, unsigned char *data,
505                                    unsigned short len)
506 {
507         u8 *mac_ptr, *index;
508         u16 mac_len;
509         wlan_vif_t *vif = id_to_vif(vif_id);
510
511         index = data;
512         memcpy(&mac_len, index, 2);
513         index += 2;
514         mac_ptr = index;
515         cfg80211_send_disassoc(vif->ndev, mac_ptr, mac_len);
516 }
517
518 void cfg80211_report_station(unsigned char vif_id, unsigned char *data,
519                              unsigned short len)
520 {
521         u8 connect_ap;
522         u8 *req_ptr, *index;
523         u16 req_len, mac_len;
524         u8 *sta_mac;
525         u32 event_len;
526         int left;
527         struct station_info sinfo;
528         wlan_vif_t *vif = id_to_vif(vif_id);
529         struct wiphy *wiphy = vif->wdev.wiphy;
530
531         event_len = len;
532         index = data;
533
534         left = event_len;
535
536         /* The first byte of event data is connection */
537         memcpy(&connect_ap, index, 1);
538         index++;
539         left--;
540
541         /* The second  byte of event data is mac */
542         memcpy(&mac_len, index, 2);
543         index += 2;
544         left -= 2;
545
546         if (mac_len != 6) {
547                 printkd("channel len %d not equal 6 bytes\n", mac_len);
548                 return;
549         }
550
551         sta_mac = index;
552         index += mac_len;
553         left -= mac_len;
554
555         if (!left) {
556                 printkd("There is no associa req frame!\n");
557                 return;
558         }
559
560         /* The third event data is associate request */
561         memcpy(&req_len, index, 2);
562         index += 2;
563         left -= 2;
564
565         req_ptr = index;
566         left -= req_len;
567
568         memset(&sinfo, 0, sizeof(struct station_info));
569         sinfo.assoc_req_ies = req_ptr;
570         sinfo.assoc_req_ies_len = req_len;
571         sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
572
573         if (connect_ap) {
574                 cfg80211_new_sta(vif->ndev, sta_mac, &sinfo, GFP_KERNEL);
575                 wiphy_info(wiphy, "New station (" MACSTR ") connected\n",
576                            MAC2STR(sta_mac));
577         } else {
578                 cfg80211_del_sta(vif->ndev, sta_mac, GFP_KERNEL);
579                 wiphy_info(wiphy, "A station (" MACSTR ") disconnected\n",
580                            MAC2STR(sta_mac));
581         }
582 }
583
584 void cfg80211_report_frame(unsigned char vif_id, unsigned char *data,
585                            unsigned short len)
586 {
587         unsigned short mac_len;
588         unsigned char *mac_ptr = NULL;
589         unsigned char channel = 0, type = 0;
590         int freq;
591         struct wlan_event_report_frame_t *report_frame = NULL;
592         wlan_vif_t *vif = id_to_vif(vif_id);
593
594         report_frame = (struct wlan_event_report_frame_t *)data;
595         channel = report_frame->channel;
596         type = report_frame->frame_type;
597         freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
598         mac_ptr = (unsigned char *)(report_frame + 1);
599         mac_len = report_frame->frame_len;
600         printkd("%s, frame_len:%d\n", __func__, mac_len);
601         cfg80211_rx_mgmt(&(vif->wdev), freq, 0, mac_ptr, mac_len, GFP_KERNEL);
602 }
603
604 #endif /*WIFI_DIRECT_SUPPORT */
605
606 static bool itm_is_wps_ie(const unsigned char *pos)
607 {
608         return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
609                 pos[1] >= 4 &&
610                 pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
611                 pos[5] == 0x04);
612 }
613
614 static bool itm_find_wpsie(const unsigned char *ies, size_t ies_len,
615                            unsigned char *buf, size_t *wps_len)
616 {
617         const unsigned char *pos;
618         size_t len = 0;
619         bool flags = false;
620
621         /*
622          * Filter out RSN/WPA IE(s)
623          */
624         if (ies && ies_len) {
625                 pos = ies;
626
627                 while (pos + 1 < ies + ies_len) {
628                         if (pos + 2 + pos[1] > ies + ies_len)
629                                 break;
630
631                         if (itm_is_wps_ie(pos)) {
632                                 memcpy(buf + len, pos, 2 + pos[1]);
633                                 len += 2 + pos[1];
634                                 flags = true;
635                         }
636
637                         pos += 2 + pos[1];
638                 }
639         }
640
641         *wps_len = len;
642         return flags;
643 }
644
645 static bool itm_find_ft_ie(const unsigned char *ies, size_t ies_len,
646                            unsigned char *buf, size_t *ie_len)
647 {
648         const unsigned char *pos;
649         size_t len = 0;
650         bool flags = false;
651         if (ies && ies_len) {
652                 pos = ies;
653                 while (pos + 1 < ies + ies_len) {
654                         if (pos + 2 + pos[1] > ies + ies_len)
655                                 break;
656                         if ((WLAN_11R_FT_IE_ID == pos[0])
657                             || (WLAN_11R_MD_IE_ID == pos[0])) {
658                                 memcpy(buf + len, pos, 2 + pos[1]);
659                                 len += 2 + pos[1];
660                                 flags = true;
661                         }
662
663                         pos += 2 + pos[1];
664                 }
665         }
666         *ie_len = len;
667         return flags;
668 }
669
670 static int itm_wlan_add_cipher_key(wlan_vif_t *vif, bool pairwise,
671                                    unsigned char key_index, unsigned int cipher,
672                                    const unsigned char *key_seq,
673                                    const unsigned char *macaddr)
674 {
675         unsigned char pn_key[16] = {
676                 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
677                 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36
678         };
679         int ret;
680         unsigned char vif_id;
681         vif_id = vif->id;
682         printkd("%s()\n", __func__);
683         if (vif->cfg80211.key_len[pairwise][0]
684             || vif->cfg80211.key_len[pairwise][1]
685             || vif->cfg80211.key_len[pairwise][2]
686             || vif->cfg80211.key_len[pairwise][3]) {
687                 /* Only set wep keys if we have at least one of them.
688                    pairwise: 0:GTK 1:PTK */
689                 switch (cipher) {
690                 case WLAN_CIPHER_SUITE_WEP40:
691                         vif->cfg80211.cipher_type = WEP40;
692                         break;
693                 case WLAN_CIPHER_SUITE_WEP104:
694                         vif->cfg80211.cipher_type = WEP104;
695                         break;
696                 case WLAN_CIPHER_SUITE_TKIP:
697                         vif->cfg80211.cipher_type = TKIP;
698                         break;
699                 case WLAN_CIPHER_SUITE_CCMP:
700                         vif->cfg80211.cipher_type = CCMP;
701                         break;
702                 case WLAN_CIPHER_SUITE_SMS4:
703                         vif->cfg80211.cipher_type = WAPI;
704                         break;
705                 default:
706                         printkd("Invalid cipher select: %d\n",
707                                 vif->cfg80211.cipher_type);
708                         return -EINVAL;
709                 }
710                 memcpy(vif->cfg80211.key_txrsc[pairwise], pn_key,
711                        sizeof(pn_key));
712                 ret =
713                     wlan_cmd_add_key(vif_id,
714                                      vif->cfg80211.key[pairwise][key_index],
715                                      vif->cfg80211.key_len[pairwise][key_index],
716                                      pairwise, key_index, key_seq,
717                                      vif->cfg80211.cipher_type, macaddr);
718                 if (ret < 0) {
719                         printkd("wlan_cmd_add_key failed %d\n", ret);
720                         return ret;
721                 }
722         }
723         return 0;
724 }
725
726 u8 sprdwl_find_ssid_count(wlan_vif_t *vif)
727 {
728         buf_scan_frame_t *scan_buf = NULL;
729         int i;
730         int count = 0;
731         struct wiphy *wiphy = vif->wdev.wiphy;
732
733         if (!vif->cfg80211.scan_frame_array)
734                 return 0;
735
736         for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++) {
737                 scan_buf = (buf_scan_frame_t *) (vif->cfg80211.scan_frame_array
738                                                  +
739                                                  i * sizeof(buf_scan_frame_t));
740
741                 if (0xff != scan_buf->live)
742                         continue;
743
744                 if (0 == scan_buf->ssid[0])
745                         continue;
746
747                 if (0 !=
748                     memcmp(vif->cfg80211.ssid, scan_buf->ssid,
749                            vif->cfg80211.ssid_len))
750                         continue;
751
752                 count++;
753         }
754
755         wiphy_info(wiphy, "the same ssid num %d with current connect ssid",
756                    count);
757
758         return count;
759 }
760
761 static int wlan_cfg80211_scan(struct wiphy *wiphy,
762 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
763                               struct net_device *dev,
764 #endif
765                               struct cfg80211_scan_request *request)
766 {
767         wlan_vif_t *vif;
768         unsigned char vif_id;
769         struct wireless_dev *wdev;
770         struct cfg80211_ssid *ssids;
771         struct wlan_cmd_scan_ssid *scan_ssids;
772         int scan_ssids_len = 0;
773         unsigned char *data = NULL;
774         unsigned int i, n, j;
775         int ret;
776         unsigned char channels[16] = { 0 };
777
778         ssids = request->ssids;
779         wdev = request->wdev;
780         vif = ndev_to_vif(wdev->netdev);
781         vif_id = vif->id;
782         if (ITM_NONE_MODE == vif->mode)
783                 return -EAGAIN;
784         printkd("[%s][%d] enter\n", __func__, vif_id);
785         if (vif->cfg80211.scan_request) {
786                 printkd("Already scanning\n");
787                 return -EAGAIN;
788         }
789         /* check we are client side */
790         switch (wdev->iftype) {
791         case NL80211_IFTYPE_AP:
792                 break;
793                 /*      case NL80211_IFTYPE_P2P_CLIENT:
794                    case NL80211_IFTYPE_P2P_GO:
795                  */
796         case NL80211_IFTYPE_STATION:
797                 break;
798         case NL80211_IFTYPE_P2P_CLIENT:
799         case NL80211_IFTYPE_P2P_GO:
800         case NL80211_IFTYPE_P2P_DEVICE:
801                 break;
802         default:
803                 {
804                         printkd("%s(), end\n", __func__);
805                         return -EOPNOTSUPP;
806                 }
807         }
808
809         /* set wps ie */
810         if (request->ie_len > 0) {
811                 if (request->ie_len > 255) {
812                         printkd("%s invalid ie len(%d)\n", __func__,
813                                 request->ie_len);
814                         return -EOPNOTSUPP;
815                 }
816                 ret =
817                     wlan_cmd_set_wps_ie(vif_id, WPS_REQ_IE, request->ie,
818                                         request->ie_len);
819                 if (ret) {
820                         printkd("wlan_cmd_set_wps_ie failed with ret %d\n",
821                                 ret);
822                         printkd("%s(), end\n", __func__);
823                         return ret;
824                 }
825         } else {
826                 printkd("%s request->ie_len is 0\n", __func__);
827         }
828
829         vif->cfg80211.hidden_ssid_scan = false;
830         n = min(request->n_ssids, 9);
831         if (n) {
832                 data = kzalloc(512, GFP_KERNEL);
833                 if (!data) {
834                         printkd("%s failed to alloc for combo ssid\n",
835                                 __func__);
836                         return -2;
837                 }
838                 scan_ssids = (struct wlan_cmd_scan_ssid *)data;
839                 for (i = 0; i < n; i++) {
840                         if (!ssids[i].ssid_len)
841                                 continue;
842                         scan_ssids->len = ssids[i].ssid_len;
843                         memcpy(scan_ssids->ssid, ssids[i].ssid,
844                                ssids[i].ssid_len);
845                         scan_ssids_len += (ssids[i].ssid_len
846                                            + sizeof(scan_ssids->len));
847                         scan_ssids = (struct wlan_cmd_scan_ssid *)
848                             (data + scan_ssids_len);
849
850                         if (vif->cfg80211.hidden_ssid_scan == false)
851                                 vif->cfg80211.hidden_ssid_scan = true;
852                 }
853         }
854
855         printkd("hidden ssid scanning: %d\n", vif->cfg80211.hidden_ssid_scan);
856
857         n = min(request->n_channels, 14);
858         if (n > 15)
859                 n = 15;
860         for (i = 0, j = 0; i < n; i++) {
861                 int ch = request->channels[i]->hw_value;
862                 if (ch == 0) {
863                         printkd("Scan requested for unknown frequency %dMhz\n",
864                                 request->channels[i]->center_freq);
865                         continue;
866                 }
867                 channels[j + 1] = ch;
868                 j++;
869         }
870         channels[0] = j;
871
872         /* Arm scan timeout timer */
873         mod_timer(&vif->cfg80211.scan_timeout,
874                   jiffies + ITM_SCAN_TIMER_INTERVAL_MS * HZ / 1000);
875         vif->cfg80211.scan_request = request;
876
877         ret = wlan_cmd_scan(vif_id, data, channels, scan_ssids_len);
878         if (ret) {
879                 printkd("wlan_cmd_scan failed with ret %d\n", ret);
880                 kfree(data);
881                 return ret;
882         }
883
884 #ifdef CONFIG_HAS_WAKELOCK
885         if (vif->cfg80211.scan_done_lock.link.next == LIST_POISON1 ||
886             vif->cfg80211.scan_done_lock.link.prev == LIST_POISON2)
887                 wake_lock(&vif->cfg80211.scan_done_lock);
888 #endif
889         kfree(data);
890         printkd("%s(), ok!\n", __func__);
891         return 0;
892 }
893
894 static int wlan_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
895                                  struct cfg80211_connect_params *sme)
896 {
897         wlan_vif_t *vif;
898         unsigned char vif_id;
899         struct wireless_dev *wdev;
900         int ret;
901         unsigned int cipher = 0;
902         unsigned char key_mgmt = 0;
903         int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40)
904             || (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104);
905         bool is_wapi = false;
906         int auth_type = 0;
907         unsigned char *buf = NULL;
908         size_t wps_len = 0;
909         unsigned short p2p_len = 0;
910         size_t ftie_len = 0;
911         vif = ndev_to_vif(ndev);
912         vif_id = vif->id;
913         wdev = &(vif->wdev);
914         if (ITM_NONE_MODE == vif->mode)
915                 return -EAGAIN;
916         printkd("[%s][%d] enter\n", __func__, vif_id);
917         printkd("%s(), Begin connect: %s\n", __func__, sme->ssid);
918
919         /* To avoid confused wapi frame */
920         vif->cfg80211.cipher_type = NONE;
921         /* Get request status, type, bss, ie and so on */
922         /* Set appending ie */
923         /* Set wps ie */
924         if (sme->ie_len > 0) {
925                 if (sme->ie_len > 255) {
926                         printkd("%s invalid sme->len(%d)\n", __func__,
927                                 sme->ie_len);
928                         return -EOPNOTSUPP;
929                 }
930                 buf = kmalloc(sme->ie_len, GFP_KERNEL);
931                 if (NULL == buf) {
932                         printkd("%s(), end\n", __func__);
933                         return -ENOMEM;
934                 }
935                 if (itm_find_wpsie(sme->ie, sme->ie_len, buf, &wps_len) == true) {
936                         ret =
937                             wlan_cmd_set_wps_ie(vif_id, WPS_ASSOC_IE, buf,
938                                                 wps_len);
939                         if (ret) {
940                                 printkd
941                                     ("wlan_cmd_set_wps_ie failed with ret %d\n",
942                                      ret);
943                                 return ret;
944                         }
945                 }
946         }
947 #ifdef WIFI_DIRECT_SUPPORT
948         if (itm_find_p2p_ie(sme->ie, sme->ie_len, buf, &p2p_len) == true) {
949                 ret = wlan_cmd_set_p2p_ie(vif_id, P2P_ASSOC_IE, buf, p2p_len);
950                 if (ret) {
951                         printkd("wlan_cmd_set_p2p_ie failed with ret %d\n",
952                                 ret);
953                         return ret;
954                 }
955         }
956 #endif /*WIFI_DIRECT_SUPPORT */
957 #ifdef WLAN_11R_SUPPORT
958         if (itm_find_ft_ie(sme->ie, sme->ie_len, buf, &ftie_len)) {
959                 ret = wlan_cmd_set_ft_ie(vif_id, buf, ftie_len);
960                 if (ret) {
961                         printkd("wlan_cmd_set_ft_ie failed with ret %d\n", ret);
962                 }
963         }
964 #endif
965         /* Set WPA version */
966         printkd("Set wpa_versions %#x\n", sme->crypto.wpa_versions);
967         ret = wlan_cmd_set_wpa_version(vif_id, sme->crypto.wpa_versions);
968         if (ret < 0) {
969                 printkd("wlan_cmd_set_wpa_version failed with ret %d\n", ret);
970                 printkd("%s(), end\n", __func__);
971                 return ret;
972         }
973
974         /* Set Auth type */
975         printkd("Set auth_type %#x\n", sme->auth_type);
976         /* Set the authorisation */
977         if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
978             ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
979                 auth_type = ITM_AUTH_OPEN;
980         else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
981                  ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
982                 auth_type = ITM_AUTH_SHARED;
983         ret = wlan_cmd_set_auth_type(vif_id, auth_type);
984         if (ret < 0) {
985                 printkd("wlan_cmd_set_auth_type failed with ret %d\n", ret);
986                 return ret;
987         }
988         /* Set cipher - pairewise and group */
989         printkd("n_ciphers_pairwise %d\n", sme->crypto.n_ciphers_pairwise);
990         if (sme->crypto.n_ciphers_pairwise) {
991                 switch (sme->crypto.ciphers_pairwise[0]) {
992                 case WLAN_CIPHER_SUITE_WEP40:
993                         cipher = WEP40;
994                         break;
995                 case WLAN_CIPHER_SUITE_WEP104:
996                         cipher = WEP104;
997                         break;
998                 case WLAN_CIPHER_SUITE_TKIP:
999                         cipher = TKIP;
1000                         break;
1001                 case WLAN_CIPHER_SUITE_CCMP:
1002                         cipher = CCMP;
1003                         break;
1004                         /* WAPI cipher is not processed by CP2 */
1005                 case WLAN_CIPHER_SUITE_SMS4:
1006                         cipher = WAPI;
1007                         is_wapi = true;
1008                         break;
1009                 default:
1010                         printkd("Unicast cipher suite 0x%x is not supported\n",
1011                                 sme->crypto.ciphers_pairwise[0]);
1012                         printkd("%s(), end\n", __func__);
1013                         kfree(buf);
1014                         return -ENOTSUPP;
1015                 }
1016
1017                 if (is_wapi != true) {
1018                         ret =
1019                             wlan_cmd_set_cipher(vif_id, cipher,
1020                                                 WIFI_CMD_SET_PAIRWISE_CIPHER);
1021                         if (ret < 0) {
1022                                 printkd
1023                                     ("set_cipher_cmd pairwise failed with ret %d\n",
1024                                      ret);
1025                                 printkd("%s(), end\n", __func__);
1026                                 return ret;
1027                         }
1028                 }
1029         } else {
1030                 /*No pairewise cipher */
1031                 printkd("No pairewise cipher\n");
1032         }
1033
1034         /* Set group cipher */
1035         switch (sme->crypto.cipher_group) {
1036         case NONE:
1037                 cipher = NONE;
1038                 break;
1039         case WLAN_CIPHER_SUITE_WEP40:
1040                 cipher = WEP40;
1041                 break;
1042         case WLAN_CIPHER_SUITE_WEP104:
1043                 cipher = WEP104;
1044                 break;
1045         case WLAN_CIPHER_SUITE_TKIP:
1046                 cipher = TKIP;
1047                 break;
1048         case WLAN_CIPHER_SUITE_CCMP:
1049                 cipher = CCMP;
1050                 break;
1051         default:
1052                 printkd("Group cipher suite 0x%x is not supported\n",
1053                         sme->crypto.cipher_group);
1054                 printkd("%s(), end\n", __func__);
1055                 kfree(buf);
1056                 return -ENOTSUPP;
1057         }
1058
1059         if (is_wapi != true) {
1060                 ret =
1061                     wlan_cmd_set_cipher(vif_id, cipher,
1062                                         WIFI_CMD_SET_GROUP_CIPHER);
1063                 if (ret < 0) {
1064                         printkd("set_cipher_cmd group failed with ret %d\n",
1065                                 ret);
1066                         printkd("%s(), end\n", __func__);
1067                         return ret;
1068                 }
1069         }
1070
1071         /* FIXME */
1072         /* Set Auth type again because of CP2 process's differece */
1073         printkd("Set auth_type %#x\n", sme->auth_type);
1074         /* Set the authorisation */
1075         if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
1076             ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
1077                 auth_type = ITM_AUTH_OPEN;
1078         else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
1079                  ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
1080                 auth_type = ITM_AUTH_SHARED;
1081         ret = wlan_cmd_set_auth_type(vif_id, auth_type);
1082         if (ret < 0) {
1083                 printkd("wlan_cmd_set_auth_type failed with ret %d\n", ret);
1084                 printkd("%s(), end\n", __func__);
1085                 return ret;
1086         }
1087
1088         /* Set auth key management (akm) */
1089         printkd("akm_suites %#x\n", sme->crypto.n_akm_suites);
1090         if (sme->crypto.n_akm_suites) {
1091                 if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_PSK)
1092                         key_mgmt = AKM_SUITE_PSK;
1093                 else if (WLAN_AKM_SUITE_FT_PSK == sme->crypto.akm_suites[0])
1094                         key_mgmt = AKM_SUITE_FT_PSK;
1095                 else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
1096                         key_mgmt = AKM_SUITE_8021X;
1097                 /* WAPI akm is not processed by CP2 */
1098                 else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_CERT)
1099                         key_mgmt = AKM_SUITE_WAPI_CERT;
1100                 else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_PSK)
1101                         key_mgmt = AKM_SUITE_WAPI_PSK;
1102                 else if (WLAN_AKM_SUITE_FT_8021X == sme->crypto.akm_suites[0])
1103                         key_mgmt = AKM_SUITE_FT_8021X;
1104                 else {
1105                 }
1106                 ret = wlan_cmd_set_key_management(vif_id, key_mgmt);
1107                 if (ret < 0) {
1108                         printkd("wlan_cmd_set_key_management failed %d\n", ret);
1109                         printkd("%s(), end\n", __func__);
1110                         return ret;
1111                 }
1112         }
1113
1114         /* Set PSK */
1115         if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40 ||
1116             sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104 ||
1117             sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP40 ||
1118             sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP104) {
1119                 printkd("Don't need to set PSK since driver is using WEP\n");
1120                 vif->cfg80211.key_index[GROUP] = sme->key_idx;
1121                 vif->cfg80211.key_len[GROUP][sme->key_idx] = sme->key_len;
1122                 memcpy(vif->cfg80211.key[GROUP][sme->key_idx], sme->key,
1123                        sme->key_len);
1124                 ret =
1125                     itm_wlan_add_cipher_key(vif, 0, sme->key_idx,
1126                                             sme->crypto.ciphers_pairwise[0],
1127                                             NULL, NULL);
1128                 if (ret < 0) {
1129                         printkd("itm_wlan_add_key failed %d\n", ret);
1130                         printkd("%s(), end\n", __func__);
1131                         kfree(buf);
1132                         return ret;
1133                 }
1134         } else {
1135                 unsigned char psk[32];
1136                 int key_len = 0;
1137                 if (wdev->iftype == NL80211_IFTYPE_AP) {
1138                         ret = hostap_conf_load(HOSTAP_CONF_FILE_NAME, psk);
1139                         if (ret) {
1140                                 printkd("load hostap failed with ret %d\n",
1141                                         ret);
1142                                 printkd("%s(), end\n", __func__);
1143                                 return ret;
1144                         }
1145                         key_len = sizeof(psk);
1146                 } else {
1147                         if (sme->key_len > 32) {
1148                                 printkd("Invalid key len (%d)\n", sme->key_len);
1149                                 printkd("%s(), end\n", __func__);
1150                                 kfree(buf);
1151                                 return -EINVAL;
1152                         }
1153                         memcpy(psk, sme->key, sme->key_len);
1154                         key_len = sme->key_len;
1155                 }
1156                 ret = wlan_cmd_set_psk(vif_id, psk, key_len);
1157                 if (ret < 0) {
1158                         printkd("set_psk_cmd failed with ret %d\n", ret);
1159                         printkd("%s(), end\n", __func__);
1160                         return ret;
1161                 }
1162         }
1163
1164         /* Auth RX unencrypted EAPOL is not implemented, do nothing */
1165         /* Set channel */
1166         if (sme->channel != NULL) {
1167                 printkd("Settting channel to %d\n",
1168                         ieee80211_frequency_to_channel(sme->
1169                                                        channel->center_freq));
1170                 ret =
1171                     wlan_cmd_set_channel(vif_id,
1172                                          ieee80211_frequency_to_channel
1173                                          (sme->channel->center_freq));
1174                 if (ret < 0) {
1175                         printkd("wlan_cmd_set_channel failed with ret %d\n",
1176                                 ret);
1177                         printkd("%s(), end\n", __func__);
1178                         return ret;
1179                 }
1180         } else {
1181                 printkd("Channel is not specified\n");
1182         }
1183
1184         /* Set BSSID */
1185         if (sme->bssid != NULL) {
1186                 ret = wlan_cmd_set_bssid(vif_id, sme->bssid);
1187                 if (ret < 0) {
1188                         printkd("wlan_cmd_set_bssid failed with ret %d\n", ret);
1189                         printkd("%s(), end\n", __func__);
1190                         return ret;
1191                 }
1192                 memcpy(vif->cfg80211.bssid, sme->bssid, 6);
1193         } else {
1194                 printkd("BSSID is not specified\n");
1195         }
1196
1197         /* Special process for WEP(WEP key must be set before itm_set_essid) */
1198         if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40 ||
1199             sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
1200                 printkd("Setting WEP group cipher\n");
1201                 if (sme->key_len <= 0) {
1202                         printkd("No key is specified\n");
1203                 } else {
1204                         if (sme->key_len != WLAN_KEY_LEN_WEP104 &&
1205                             sme->key_len != WLAN_KEY_LEN_WEP40) {
1206                                 printkd("Invalid key length for WEP\n");
1207                                 printkd("%s(), end\n", __func__);
1208                                 return -EINVAL;
1209                         }
1210
1211                         wlan_cmd_set_key(vif_id, sme->key_idx);
1212                 }
1213         }
1214         /* Set ESSID */
1215         if (sme->ssid != NULL) {
1216                 printkd("sme->ssid:%s\n", sme->ssid);
1217                 ret = wlan_cmd_set_essid(vif_id, sme->ssid, (int)sme->ssid_len);
1218                 if (ret < 0) {
1219                         printkd("wlan_cmd_set_essid failed with ret %d\n", ret);
1220                         printkd("%s(), end\n", __func__);
1221                         kfree(buf);
1222                         return ret;
1223                 }
1224                 memcpy(vif->cfg80211.ssid, sme->ssid, sme->ssid_len);
1225                 vif->cfg80211.ssid_len = sme->ssid_len;
1226         }
1227         vif->cfg80211.connect_status = ITM_CONNECTING;
1228         kfree(buf);
1229         printkd("%s(), ok\n", __func__);
1230         return ret;
1231 }
1232
1233 static int wlan_cfg80211_disconnect(struct wiphy *wiphy,
1234                                     struct net_device *ndev,
1235                                     unsigned short reason_code)
1236 {
1237         wlan_vif_t *vif;
1238         unsigned char vif_id;
1239         struct cfg80211_bss *bss = NULL;
1240         bool found = false;
1241         int ret;
1242         vif = ndev_to_vif(ndev);
1243         vif_id = vif->id;
1244         if (ITM_NONE_MODE == vif->mode)
1245                 return -EAGAIN;
1246         printkd("[%s][%d] enter\n", __func__, vif_id);
1247         printkd("Begin disconnect: %s\n", vif->cfg80211.ssid);
1248
1249         ret = wlan_cmd_disconnect(vif_id, reason_code);
1250         if (ret < 0) {
1251                 printkd("swifi_disconnect_cmd failed with ret %d\n", ret);
1252         }
1253         memset(vif->cfg80211.ssid, 0, sizeof(vif->cfg80211.ssid));
1254         return ret;
1255 }
1256
1257 static int wlan_cfg80211_add_key(struct wiphy *wiphy,
1258                                  struct net_device *netdev, u8 idx,
1259                                  bool pairwise, const u8 *mac_addr,
1260                                  struct key_params *params)
1261 {
1262         wlan_vif_t *vif;
1263         unsigned char vif_id;
1264         int ret;
1265         unsigned char key[32];
1266         vif = ndev_to_vif(netdev);
1267         vif_id = vif->id;
1268         if (ITM_NONE_MODE == vif->mode)
1269                 return -EAGAIN;
1270         printkd("[%s][%d] enter\n", __func__, vif_id);
1271
1272         vif->cfg80211.key_index[pairwise] = idx;
1273         vif->cfg80211.key_len[pairwise][idx] = params->key_len;
1274         memcpy(vif->cfg80211.key[pairwise][idx], params->key, params->key_len);
1275         ret =
1276             itm_wlan_add_cipher_key(vif, pairwise, idx, params->cipher,
1277                                     params->seq, mac_addr);
1278         if (ret < 0) {
1279                 printkd("%s failed to add cipher key!\n", __func__);
1280                 return ret;
1281         }
1282
1283         return 0;
1284 }
1285
1286 static int wlan_cfg80211_del_key(struct wiphy *wiphy,
1287                                  struct net_device *ndev,
1288                                  unsigned char key_index, bool pairwise,
1289                                  const unsigned char *mac_addr)
1290 {
1291         wlan_vif_t *vif;
1292         unsigned char vif_id;
1293
1294         vif = ndev_to_vif(ndev);
1295         vif_id = vif->id;
1296         if (ITM_NONE_MODE == vif->mode)
1297                 return -EAGAIN;
1298         printkd("[%s][%d] enter\n", __func__, vif_id);
1299         if (key_index > WLAN_MAX_KEY_INDEX) {
1300                 printkd("key index %d out of bounds\n", key_index);
1301                 return -ENOENT;
1302         }
1303         if (!vif->cfg80211.key_len[pairwise][key_index]) {
1304                 printkd("index %d is empty\n", key_index);
1305                 return 0;
1306         }
1307         vif->cfg80211.key_len[pairwise][key_index] = 0;
1308         vif->cfg80211.cipher_type = NONE;
1309
1310         return wlan_cmd_del_key(vif_id, key_index, mac_addr);
1311 }
1312
1313 static int wlan_cfg80211_set_default_key(struct wiphy *wiphy,
1314                                          struct net_device *ndev,
1315                                          unsigned char key_index, bool unicast,
1316                                          bool multicast)
1317 {
1318         int ret;
1319         wlan_vif_t *vif;
1320         unsigned char vif_id;
1321         vif = ndev_to_vif(ndev);
1322         vif_id = vif->id;
1323         if (ITM_NONE_MODE == vif->mode)
1324                 return -EAGAIN;
1325         printkd("[%s][%d] enter\n", __func__, vif_id);
1326         if (key_index < 0 || key_index > 3) {
1327                 printkd("Invalid key index %d\n", key_index);
1328                 return -EINVAL;
1329         }
1330         ret = wlan_cmd_set_key(vif_id, key_index);
1331         if (ret < 0) {
1332                 printkd("wlan_cmd_set_key failed\n");
1333                 return ret;
1334         }
1335
1336         return 0;
1337 }
1338
1339 static int wlan_cfg80211_set_wiphy_params(struct wiphy *wiphy,
1340                                           unsigned int changed)
1341 {
1342         int ret;
1343         wlan_vif_t *vif;
1344         unsigned char vif_id;
1345         vif_id = NETIF_0_ID;
1346         vif = id_to_vif(vif_id);
1347         if (ITM_NONE_MODE == vif->mode)
1348                 return -EAGAIN;
1349         printkd("[%s][%d] enter\n", __func__, vif_id);
1350         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1351                 ret = wlan_cmd_set_rts(vif_id, wiphy->rts_threshold);
1352                 if (ret != 0) {
1353                         printkd("wlan_cmd_set_rts failed\n");
1354                         return -EIO;
1355                 }
1356         }
1357
1358         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1359                 ret = wlan_cmd_set_frag(vif_id, wiphy->frag_threshold);
1360                 if (ret != 0) {
1361                         printkd("wlan_cmd_set_frag failed\n");
1362                         return -EIO;
1363                 }
1364         }
1365         return 0;
1366 }
1367
1368 static int wlan_cfg80211_get_station(struct wiphy *wiphy,
1369                                      struct net_device *dev, unsigned char *mac,
1370                                      struct station_info *sinfo)
1371 {
1372         unsigned char signal, noise;
1373         int rate, ret, i, failed;
1374         wlan_vif_t *vif;
1375         unsigned char vif_id;
1376         static int cfg80211_get_station_time;
1377         static char cfg80211_get_station_signal;
1378         static int cfg80211_get_station_txrate;
1379         static int cfg80211_get_station_txfailed;
1380
1381         vif = ndev_to_vif(dev);
1382         vif_id = vif->id;
1383         if (ITM_NONE_MODE == vif->mode)
1384                 return -EAGAIN;
1385         if (NULL == sinfo) {
1386                 printke("[%s][sinfo null]\n", __func__);
1387                 return -EAGAIN;
1388         }
1389
1390         sinfo->filled |=
1391             STATION_INFO_TX_BYTES | STATION_INFO_TX_PACKETS |
1392             STATION_INFO_RX_BYTES | STATION_INFO_RX_PACKETS;
1393         sinfo->tx_bytes = vif->ndev->stats.tx_bytes;
1394         sinfo->tx_packets = vif->ndev->stats.tx_packets;
1395         sinfo->rx_bytes = vif->ndev->stats.rx_bytes;
1396         sinfo->rx_packets = vif->ndev->stats.rx_packets;
1397
1398         if (0 != cfg80211_get_station_time) {
1399                 sinfo->signal = cfg80211_get_station_signal;
1400                 sinfo->filled |= STATION_INFO_SIGNAL;
1401                 sinfo->txrate.legacy = cfg80211_get_station_txrate;
1402                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1403                 sinfo->tx_failed = cfg80211_get_station_txfailed;
1404                 sinfo->filled |= STATION_INFO_TX_FAILED;
1405                 if (2 == cfg80211_get_station_time) {
1406                         cfg80211_get_station_time = 0;
1407                 } else {
1408                         cfg80211_get_station_time++;
1409                 }
1410                 return 0;
1411         }
1412
1413         ret = wlan_cmd_get_rssi(vif_id, &signal, &noise);
1414         if (OK == ret) {
1415                 sinfo->signal = signal;
1416                 sinfo->filled |= STATION_INFO_SIGNAL;
1417         } else {
1418                 printkd("wlan_cmd_get_rssi error!\n");
1419                 return -EIO;
1420         }
1421
1422         ret = wlan_cmd_get_txrate_txfailed(vif_id, &rate, &failed);
1423         if (OK == ret) {
1424                 sinfo->tx_failed = failed;
1425                 sinfo->filled |=
1426                     STATION_INFO_TX_BITRATE | STATION_INFO_TX_FAILED;
1427         } else {
1428                 printkd("wlan_cmd_get_txrate_txfailed error!\n");
1429                 return -EIO;
1430         }
1431
1432         if (!(rate & 0x7f)) {
1433                 sinfo->txrate.legacy = 10;
1434         } else {
1435                 for (i = 0; i < ARRAY_SIZE(itm_rates); i++) {
1436                         if (rate == itm_rates[i].hw_value) {
1437                                 sinfo->txrate.legacy = itm_rates[i].bitrate;
1438                                 if (rate & 0x80)
1439                                         sinfo->txrate.mcs =
1440                                             itm_rates[i].hw_value;
1441                                 break;
1442                         }
1443                 }
1444                 if (i >= ARRAY_SIZE(itm_rates))
1445                         sinfo->txrate.legacy = 10;
1446         }
1447         cfg80211_get_station_signal = sinfo->signal;
1448         cfg80211_get_station_txrate = sinfo->txrate.legacy;
1449         cfg80211_get_station_txfailed = sinfo->tx_failed;
1450         cfg80211_get_station_time++;
1451
1452         return 0;
1453 }
1454
1455 static int wlan_cfg80211_set_pmksa(struct wiphy *wiphy,
1456                                    struct net_device *netdev,
1457                                    struct cfg80211_pmksa *pmksa)
1458 {
1459         int ret;
1460         wlan_vif_t *vif;
1461         unsigned char vif_id;
1462         vif = ndev_to_vif(netdev);
1463         vif_id = vif->id;
1464         if (ITM_NONE_MODE == vif->mode)
1465                 return -EAGAIN;
1466         printkd("[%s][%d] enter\n", __func__, vif_id);
1467         ret =
1468             wlan_cmd_pmksa(vif_id, pmksa->bssid, pmksa->pmkid,
1469                            WIFI_CMD_SET_PMKSA);
1470         return ret;
1471 }
1472
1473 static int wlan_cfg80211_del_pmksa(struct wiphy *wiphy,
1474                                    struct net_device *netdev,
1475                                    struct cfg80211_pmksa *pmksa)
1476 {
1477         int ret;
1478         wlan_vif_t *vif;
1479         unsigned char vif_id;
1480         vif = ndev_to_vif(netdev);
1481         vif_id = vif->id;
1482         if (ITM_NONE_MODE == vif->mode)
1483                 return -EAGAIN;
1484         printkd("[%s][%d] enter\n", __func__, vif_id);
1485         ret =
1486             wlan_cmd_pmksa(vif_id, pmksa->bssid, pmksa->pmkid,
1487                            WIFI_CMD_DEL_PMKSA);
1488         return ret;
1489 }
1490
1491 static int wlan_cfg80211_flush_pmksa(struct wiphy *wiphy,
1492                                      struct net_device *netdev)
1493 {
1494         int ret;
1495         wlan_vif_t *vif;
1496         unsigned char vif_id;
1497         vif = ndev_to_vif(netdev);
1498         vif_id = vif->id;
1499         if (ITM_NONE_MODE == vif->mode)
1500                 return -EAGAIN;
1501         printkd("[%s][%d] enter\n", __func__, vif_id);
1502         ret =
1503             wlan_cmd_pmksa(vif_id, vif->cfg80211.bssid, NULL,
1504                            WIFI_CMD_FLUSH_PMKSA);
1505         return ret;
1506 }
1507
1508 void cfg80211_report_connect_result(unsigned char vif_id, unsigned char *pData,
1509                                     int len)
1510 {
1511         unsigned char *req_ie_ptr, *resp_ie_ptr, *bssid_ptr, *pos, *value_ptr;
1512         unsigned char status_code = 0;
1513         unsigned short bssid_len;
1514         unsigned char req_ie_len;
1515         unsigned short resp_ie_len;
1516         unsigned int event_len;
1517         int left;
1518         unsigned char reassociate_rsp_flag = 0;
1519
1520         wlan_vif_t *vif = id_to_vif(vif_id);
1521         printkd("%s(), enter\n", __func__);
1522         event_len = len;
1523         /* status_len 2 + status_code 1 = 3 bytes */
1524         if (event_len < 3) {
1525                 printkd("filled event len(%d) is not a valid len\n", event_len);
1526                 goto out;
1527         }
1528         pos = kmalloc(event_len, GFP_KERNEL);
1529         if (pos == NULL) {
1530                 printkd("[%s][%d][%d]\n", __func__, __LINE__, event_len);
1531                 if (event_len > 16384)
1532                         BUG_ON(1);
1533                 goto out;
1534         }
1535         /* The first byte of event data is status and len */
1536         memcpy(pos, pData, event_len);
1537         /* msg byte format
1538          * byte [0] the length for status_code,here is 1
1539          * byte [1] reassociate_rsp_flag
1540          * byte [2] status_code
1541          * ..... other data
1542          */
1543         if (1 != *pos) {
1544                 ASSERT("msg first byte err:%d != 1", (int)*pos);
1545                 kfree(pos);
1546                 goto out;
1547         }
1548         reassociate_rsp_flag = *(pos + 1);
1549         status_code = *(pos + 2);
1550
1551         /* FIXME later the status code should be reported by CP2 */
1552         if (status_code != 0) {
1553                 printkd("%s, Connect is failled (%d)\n", __func__, status_code);
1554                 kfree(pos);
1555                 goto out;
1556         }
1557
1558         value_ptr = pos + 3;
1559         left = event_len - 3;
1560         /* BSSID is 6 + len is 2 = 8 */
1561         if (left < 8) {
1562                 printkd("%s(), Do not have a vaild bssid\n", __func__);
1563                 kfree(pos);
1564                 goto out;
1565         }
1566         memcpy(&bssid_len, value_ptr, 2);
1567         left -= 2;
1568         bssid_ptr = value_ptr + 2;
1569         left -= bssid_len;
1570
1571         if (!left) {
1572                 printkd("%s(), There is no req_ie frame!\n", __func__);
1573                 kfree(pos);
1574                 goto out;
1575         }
1576         req_ie_len = *(unsigned char *)(bssid_ptr + bssid_len);
1577         left -= 1;
1578         req_ie_ptr = bssid_ptr + bssid_len + 1;
1579         left -= req_ie_len;
1580         if (!left) {
1581                 printkd("%s(), There is no resp_ie frame!\n", __func__);
1582                 kfree(pos);
1583                 goto out;
1584         }
1585         resp_ie_len =
1586             *(unsigned char *)(req_ie_ptr + req_ie_len) +
1587             *(unsigned char *)(req_ie_ptr + req_ie_len + 1);
1588         resp_ie_ptr = req_ie_ptr + req_ie_len + 2;
1589
1590         if ((vif->cfg80211.connect_status == ITM_CONNECTING)
1591             || (1 == reassociate_rsp_flag)) {
1592                 /* inform connect result to cfg80211 */
1593                 vif->cfg80211.connect_status = ITM_CONNECTED;
1594                 if (1 == reassociate_rsp_flag) {
1595                         vif->wdev.sme_state = CFG80211_SME_CONNECTING;
1596                 }
1597                 cfg80211_connect_result(vif->ndev, bssid_ptr, req_ie_ptr,
1598                                         req_ie_len, resp_ie_ptr, resp_ie_len,
1599                                         WLAN_STATUS_SUCCESS, GFP_KERNEL);
1600                 if (!netif_carrier_ok(vif->ndev)) {
1601                         printkd("%s(), netif_carrier_on, ssid:%s\n", __func__,
1602                                 vif->cfg80211.ssid);
1603                         netif_carrier_on(vif->ndev);
1604                         netif_wake_queue(vif->ndev);
1605                 }
1606         }
1607         kfree(pos);
1608         printkd("%s(), ok\n", __func__);
1609         return;
1610 out:
1611         if (vif->cfg80211.scan_request
1612             && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1)) {
1613                 del_timer_sync(&vif->cfg80211.scan_timeout);
1614                 cfg80211_scan_done(vif->cfg80211.scan_request, true);
1615                 vif->cfg80211.scan_request = NULL;
1616 #ifdef CONFIG_HAS_WAKELOCK
1617                 if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 &&
1618                     vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1619                         wake_unlock(&vif->cfg80211.scan_done_lock);
1620 #endif
1621                 atomic_dec(&vif->cfg80211.scan_status);
1622         }
1623         if (vif->cfg80211.connect_status == ITM_CONNECTING) {
1624                 cfg80211_connect_result(vif->ndev, vif->cfg80211.bssid, NULL, 0,
1625                                         NULL, 0,
1626                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
1627                                         GFP_KERNEL);
1628         } else if (vif->cfg80211.connect_status == ITM_CONNECTED) {
1629                 cfg80211_disconnected(vif->ndev, status_code, NULL, 0,
1630                                       GFP_KERNEL);
1631         }
1632
1633         printkd("%s(), err\n", __func__);
1634         return;
1635 }
1636
1637 void cfg80211_unlink_ssid(unsigned char vif_id, unsigned char *bssid, unsigned char *ssid, int ssid_len)
1638 {
1639                 int i;
1640                 struct cfg80211_bss *bss = NULL;
1641                 struct wiphy *wiphy = NULL;
1642                 wlan_vif_t *vif;
1643                 buf_scan_frame_t *scan_buf;
1644
1645                 vif = id_to_vif(vif_id);
1646                 wiphy = vif->wdev.wiphy;
1647                 bss = cfg80211_get_bss(wiphy, NULL,bssid,ssid,ssid_len,WLAN_CAPABILITY_ESS,WLAN_CAPABILITY_ESS);
1648                 if(bss)
1649                 {
1650                         cfg80211_unlink_bss(wiphy, bss);
1651                         vif->beacon_loss = 0;
1652                         printkd("[%s][unlink][%s]\n",__func__, ssid);
1653                 }
1654                 for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++)
1655                 {
1656                         scan_buf = (buf_scan_frame_t *) (vif->
1657                                                   cfg80211.scan_frame_array +
1658                                                   i * sizeof(buf_scan_frame_t));
1659                         if (0xff != scan_buf->live)
1660                                 continue;
1661                         if (0 != memcmp(bssid, scan_buf->bssid, 6))
1662                                 continue;
1663                         if(ssid_len != strlen(scan_buf->ssid) )
1664                                 continue;
1665                         if( 0 != strncmp(ssid, scan_buf->ssid, ssid_len) )
1666                                 continue;
1667                         memset((char *)(scan_buf), 0, sizeof(buf_scan_frame_t) );
1668                         printkd("[%s][clear][%s]\n",__func__, ssid);
1669                         break;
1670                 }
1671                 return;
1672 }
1673
1674 void cfg80211_report_disconnect_done(unsigned char vif_id, unsigned char *pData,
1675                                      int len)
1676 {
1677         struct cfg80211_bss *bss = NULL;
1678         unsigned short reason_code = 0;
1679         bool found = false;
1680         wlan_vif_t *vif = id_to_vif(vif_id);
1681         printkd("%s()\n", __func__);
1682
1683         cfg80211_unlink_ssid(vif_id, vif->cfg80211.bssid, vif->cfg80211.ssid, vif->cfg80211.ssid_len );
1684
1685         /* This should filled if disconnect reason is not only one */
1686         memcpy(&reason_code, pData, 2);
1687         if (vif->cfg80211.scan_request
1688             && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1)) {
1689                 del_timer_sync(&vif->cfg80211.scan_timeout);
1690                 cfg80211_scan_done(vif->cfg80211.scan_request, true);
1691                 vif->cfg80211.scan_request = NULL;
1692 #ifdef CONFIG_HAS_WAKELOCK
1693                 if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1
1694                     && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1695                         wake_unlock(&vif->cfg80211.scan_done_lock);
1696 #endif
1697                 atomic_dec(&vif->cfg80211.scan_status);
1698         }
1699         if (vif->cfg80211.connect_status == ITM_CONNECTING) {
1700                 cfg80211_connect_result(vif->ndev,
1701                                         vif->cfg80211.bssid, NULL, 0,
1702                                         NULL, 0,
1703                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
1704                                         GFP_KERNEL);
1705         } else if (vif->cfg80211.connect_status == ITM_CONNECTED) {
1706                 if (reason_code == AP_LEAVING   /*||
1707                                                    reason_code == AP_DEAUTH */) {
1708                         do {
1709                                 bss = cfg80211_get_bss(vif->wdev.wiphy, NULL,
1710                                                        vif->cfg80211.bssid,
1711                                                        vif->cfg80211.ssid,
1712                                                        vif->cfg80211.ssid_len,
1713                                                        WLAN_CAPABILITY_ESS,
1714                                                        WLAN_CAPABILITY_ESS);
1715                                 if (bss) {
1716                                         cfg80211_unlink_bss(vif->wdev.wiphy,
1717                                                             bss);
1718                                         found = true;
1719                                 } else {
1720                                         found = false;
1721                                 }
1722                         } while (found);
1723                 }
1724                 cfg80211_disconnected(vif->ndev, reason_code,
1725                                       NULL, 0, GFP_KERNEL);
1726         }
1727
1728         vif->cfg80211.connect_status = ITM_DISCONNECTED;
1729         if (netif_carrier_ok(vif->ndev)) {
1730                 printkd("netif_carrier_off\n");
1731                 netif_carrier_off(vif->ndev);
1732                 netif_stop_queue(vif->ndev);
1733         }
1734         return;
1735 }
1736
1737 static void wlan_scan_timeout(unsigned long data)
1738 {
1739         wlan_vif_t *vif = (wlan_vif_t *) data;
1740         vif->cfg80211.hidden_ssid_scan = false;
1741         printkd("%s()\n", __func__);
1742         if (vif->cfg80211.scan_request
1743             && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1)) {
1744                 printkd("scan timer expired!\n");
1745                 cfg80211_scan_done(vif->cfg80211.scan_request, true);
1746                 vif->cfg80211.scan_request = NULL;
1747 #ifdef CONFIG_HAS_WAKELOCK
1748                 if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1
1749                     && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1750                         wake_unlock(&vif->cfg80211.scan_done_lock);
1751 #endif
1752                 atomic_dec(&vif->cfg80211.scan_status);
1753                 printkd("%s()  end\n", __func__);
1754
1755                 return;
1756         }
1757
1758         printkd("%s()  end, wrong scan timer expired!\n", __func__);
1759         return;
1760 }
1761
1762 void cfg80211_report_scan_done(unsigned char vif_id, unsigned char *pData,
1763                                int len, bool aborted)
1764 {
1765         struct ieee80211_mgmt *mgmt;
1766         struct ieee80211_channel *channel;
1767         struct ieee80211_supported_band *band;
1768         struct wiphy *wiphy;
1769         struct cfg80211_bss *itm_bss = NULL;
1770         unsigned char ssid[33] = { 0 };
1771         unsigned char bssid[6] = { 0 };
1772         unsigned int mgmt_len = 0;
1773         unsigned short channel_num, channel_len;
1774         unsigned short rssi_len;
1775         short rssi;
1776         int signal;
1777         int freq;
1778         unsigned int left = len;
1779         wlan_vif_t *vif = id_to_vif(vif_id);
1780         const unsigned char *pos = pData;
1781
1782         wiphy = vif->wdev.wiphy;
1783         printkd("%s()\n", __func__);
1784         if (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 0) {
1785                 printkd("scan event is aborted\n");
1786                 return;
1787         }
1788
1789         if (!vif->cfg80211.scan_request) {
1790                 printkd("vif->cfg80211.scan_request is null\n");
1791                 atomic_dec(&vif->cfg80211.scan_status);
1792                 return;
1793         }
1794
1795         if (left < 10 || aborted) {
1796                 printkd("filled event len(%d) is not a valid len\n", len);
1797                 goto out;
1798         }
1799
1800         mgmt = kmalloc(left, GFP_KERNEL);
1801         if (mgmt == NULL) {
1802                 printkd("[%s][%d]\n", __func__, left);
1803                 goto out;
1804         }
1805         while (left >= 10) {
1806                 /* must use memcpy to protect unaligned */
1807                 /* The formate of frame is len(two bytes) + data */
1808                 memcpy(&channel_len, pos, 2);
1809                 pos += 2;
1810                 left -= 2;
1811                 if (channel_len > 2) {
1812                         ASSERT("channel_len %u > 2\n", channel_len);
1813                         kfree(mgmt);
1814                         goto out;
1815                 }
1816                 memcpy(&channel_num, pos, channel_len);
1817                 pos += channel_len;
1818                 left -= channel_len;
1819                 /* The second two value of frame is rssi */
1820                 memcpy(&rssi_len, pos, 2);
1821                 pos += 2;
1822                 left -= 2;
1823                 memcpy(&rssi, pos, rssi_len);
1824                 pos += rssi_len;
1825                 left -= rssi_len;
1826                 /* The third two value of frame is following data len */
1827                 memcpy(&mgmt_len, pos, 2);
1828                 pos += 2;
1829                 left -= 2;
1830
1831                 if (mgmt_len > left) {
1832                         printkd("mgmt_len(0x%08x) > left(0x%08x)!\n", mgmt_len,
1833                                 left);
1834                         kfree(mgmt);
1835                         goto out;
1836                 }
1837
1838                 /* The following is real data */
1839                 memcpy(mgmt, pos, mgmt_len);
1840                 left -= mgmt_len;
1841                 pos += mgmt_len;
1842
1843                 /* FIXME Now only support 2GHZ */
1844                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
1845                 freq = ieee80211_channel_to_frequency(channel_num, band->band);
1846                 channel = ieee80211_get_channel(wiphy, freq);
1847                 if (!channel) {
1848                         printkd("freq is %d\n", freq);
1849                         continue;
1850                 }
1851                 signal = rssi;
1852                 /*printkd("[report][%s][%d][%d]\n",ssid, channel_num, signal); */
1853                 itm_bss =
1854                     cfg80211_inform_bss_frame(wiphy, channel, mgmt,
1855                                               le16_to_cpu(mgmt_len), signal,
1856                                               GFP_KERNEL);
1857
1858                 if (unlikely(!itm_bss))
1859                         printkd("cfg80211_inform_bss_frame error\n");
1860 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
1861                 cfg80211_put_bss(wiphy, itm_bss);
1862 #else
1863                 cfg80211_put_bss(itm_bss);
1864 #endif
1865         }
1866
1867         if (left) {
1868                 kfree(mgmt);
1869                 goto out;
1870         }
1871
1872         kfree(mgmt);
1873         del_timer_sync(&vif->cfg80211.scan_timeout);
1874         cfg80211_scan_done(vif->cfg80211.scan_request, aborted);
1875         vif->cfg80211.scan_request = NULL;
1876 #ifdef CONFIG_HAS_WAKELOCK
1877         if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1
1878             && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1879                 wake_unlock(&vif->cfg80211.scan_done_lock);
1880 #endif
1881         atomic_dec(&vif->cfg80211.scan_status);
1882
1883         printkd("%s(), ok!\n", __func__);
1884         return;
1885
1886 out:
1887         del_timer_sync(&vif->cfg80211.scan_timeout);
1888         cfg80211_scan_done(vif->cfg80211.scan_request, true);
1889         vif->cfg80211.scan_request = NULL;
1890 #ifdef CONFIG_HAS_WAKELOCK
1891         if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 &&
1892             vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1893                 wake_unlock(&vif->cfg80211.scan_done_lock);
1894 #endif
1895         atomic_dec(&vif->cfg80211.scan_status);
1896
1897         printkd("%s(), err\n", __func__);
1898         return;
1899 }
1900
1901 void cfg80211_report_scan_frame(unsigned char vif_id, unsigned char *pData,
1902                                 int len)
1903 {
1904         struct cfg80211_bss *bss = NULL;
1905         int i, report_null;
1906         wlan_vif_t *vif;
1907         buf_scan_frame_t *scan_buf;
1908         wlan_event_scan_rsp_t *event;
1909         unsigned char *msa;
1910         unsigned char ssid[33] = { 0 };
1911         unsigned char bssid[6] = { 0 };
1912
1913         struct ieee80211_channel *channel = NULL;
1914         struct ieee80211_supported_band *band = NULL;
1915         struct wiphy *wiphy = NULL;
1916         struct cfg80211_bss *itm_bss = NULL;
1917         struct ieee80211_mgmt *mgmt = NULL;
1918         u8 *ie;
1919         size_t ielen;
1920         u16 capability, beacon_interval;
1921         int freq, signal;
1922         u64 tsf;
1923
1924         vif = id_to_vif(vif_id);
1925         wiphy = vif->wdev.wiphy;
1926         event = (wlan_event_scan_rsp_t *) (pData);
1927         if (((event->frame_len + sizeof(wlan_event_scan_rsp_t)) > len)
1928             || (event->ops > 2)) {
1929                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
1930                 return;
1931         }
1932         if (0 == event->ops) {
1933                 if (event->frame_len < 37) {
1934                         printkd("[%s %d][line %d err]\n", __func__, vif_id,
1935                                 __LINE__);
1936                         return;
1937                 }
1938                 msa = (unsigned char *)(event + 1);
1939                 get_ssid(msa, ssid);
1940                 get_bssid(msa, bssid);
1941                 /*if (0 == strlen(ssid)) {
1942                    printkd("[%s %d][line %d err]\n", __func__, vif_id,
1943                    __LINE__);
1944                    return;
1945                    } */
1946                 if (vif->cfg80211.hidden_ssid_scan && (0 == strlen(ssid))) {
1947                         printkd("SSID len is 0\n");
1948                         return;
1949                 }
1950
1951
1952                 if (1024 < event->frame_len) {
1953                         printkd("[%s %d][line %d err]\n", __func__, vif_id,
1954                                 __LINE__);
1955                         return;
1956                 }
1957                 for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++) {
1958                         scan_buf =
1959                             (buf_scan_frame_t *) (vif->
1960                                                   cfg80211.scan_frame_array +
1961                                                   i * sizeof(buf_scan_frame_t));
1962                         if (0xff != scan_buf->live)
1963                                 continue;
1964                         if (0 != memcmp(bssid, scan_buf->bssid, 6))
1965                                 continue;
1966                         strcpy(scan_buf->ssid, ssid);
1967                         memcpy(scan_buf->msa, msa, event->frame_len);
1968                         scan_buf->msa_len = event->frame_len;
1969                         scan_buf->channel = event->channel;
1970                         scan_buf->signal = event->signal;
1971                         scan_buf->live = 0xff;
1972                         scan_buf->keep = 1;
1973                         return;
1974                 }
1975                 for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++) {
1976                         scan_buf =
1977                             (buf_scan_frame_t *) (vif->
1978                                                   cfg80211.scan_frame_array +
1979                                                   i * sizeof(buf_scan_frame_t));
1980                         if (0xff == scan_buf->live)
1981                                 continue;
1982                         memcpy(scan_buf->bssid, bssid, 6);
1983                         strcpy(scan_buf->ssid, ssid);
1984                         memcpy(scan_buf->msa, msa, event->frame_len);
1985                         scan_buf->msa_len = event->frame_len;
1986                         scan_buf->channel = event->channel;
1987                         scan_buf->signal = event->signal;
1988                         scan_buf->keep = 1;
1989                         scan_buf->live = 0xff;
1990                         printkd("[netif:%d find_ssid][%s][%d][%d]\n", vif_id,
1991                                 scan_buf->ssid, scan_buf->channel,
1992                                 scan_buf->signal);
1993                         return;
1994                 }
1995                 return;
1996         }
1997         if (1 != event->ops) {
1998                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
1999                 return;
2000         }
2001         if (!vif->cfg80211.scan_request) {
2002                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
2003                 atomic_dec(&vif->cfg80211.scan_status);
2004                 return;
2005         }
2006         if (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 0) {
2007                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
2008                 return;
2009         }
2010         if (!vif->cfg80211.scan_request) {
2011                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
2012                 atomic_dec(&vif->cfg80211.scan_status);
2013                 return;
2014         }
2015         report_null = -1;
2016         band = wiphy->bands[IEEE80211_BAND_2GHZ];
2017         for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++) {
2018                 scan_buf =
2019                     (buf_scan_frame_t *) (vif->cfg80211.scan_frame_array +
2020                                           i * sizeof(buf_scan_frame_t));
2021                 if (0xff != scan_buf->live)
2022                         continue;
2023                 if (0 == scan_buf->keep) {
2024                         printkd("[netif:%d leave_ssid][%s][%d][%d]\n", vif_id,
2025                                 scan_buf->ssid, event->channel, event->signal);
2026                         memset((char *)scan_buf, 0, sizeof(buf_scan_frame_t));
2027                         continue;
2028                 }
2029                 scan_buf->keep--;
2030                 freq =
2031                     ieee80211_channel_to_frequency(scan_buf->channel,
2032                                                    band->band);
2033                 channel = ieee80211_get_channel(wiphy, freq);
2034                 if (!channel) {
2035                         printkd("[%s %d][line %d err]\n", __func__, vif_id,
2036                                 __LINE__);
2037                         continue;
2038                 }
2039                 mgmt = (struct ieee80211_mgmt *)(&scan_buf->msa[0]);
2040                 tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
2041                 capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
2042                 beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
2043                 ie = mgmt->u.probe_resp.variable;
2044                 ielen =
2045                     le16_to_cpu(scan_buf->msa_len) -
2046                     offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
2047                 signal = scan_buf->signal;
2048                 signal = signal * 100;
2049                 wiphy_dbg(wiphy, "   %s, " MACSTR ", channel %2u, signal %d\n",
2050                            ieee80211_is_probe_resp(mgmt->frame_control)
2051                            ? "proberesp" : "beacon   ",
2052                            MAC2STR(mgmt->bssid), scan_buf->channel,
2053                            scan_buf->signal);
2054                 itm_bss =
2055                     cfg80211_inform_bss(wiphy, channel, mgmt->bssid, tsf,
2056                                         capability, beacon_interval, ie, ielen,
2057                                         signal, GFP_KERNEL);
2058                 if (unlikely(!itm_bss))
2059                         printkd("[%s %d][line %d err]\n", __func__, vif_id,
2060                                 __LINE__);
2061 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2062                 cfg80211_put_bss(wiphy, itm_bss);
2063 #else
2064                 cfg80211_put_bss(itm_bss);
2065 #endif
2066                 report_null = 0;
2067         }
2068
2069         if (vif->beacon_loss) {
2070                 bss = cfg80211_get_bss(wiphy, NULL,
2071                                        vif->cfg80211.bssid,
2072                                        vif->cfg80211.ssid,
2073                                        vif->cfg80211.ssid_len,
2074                                        WLAN_CAPABILITY_ESS,
2075                                        WLAN_CAPABILITY_ESS);
2076                 if (bss) {
2077                         cfg80211_unlink_bss(wiphy, bss);
2078                         wiphy_info(wiphy, "find beacon loss event " MACSTR "",
2079                                    MAC2STR(bss->bssid));
2080                         vif->beacon_loss = 0;
2081                 }
2082         }
2083
2084         if (-1 == report_null) {
2085                 printkd("[%s %d][report-ssid][NULL]\n", __func__, vif_id);
2086         }
2087         del_timer_sync(&vif->cfg80211.scan_timeout);
2088         cfg80211_scan_done(vif->cfg80211.scan_request, false);
2089         vif->cfg80211.scan_request = NULL;
2090         vif->cfg80211.hidden_ssid_scan = false;
2091 #ifdef CONFIG_HAS_WAKELOCK
2092         if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1
2093             && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
2094                 wake_unlock(&vif->cfg80211.scan_done_lock);
2095 #endif
2096         atomic_dec(&vif->cfg80211.scan_status);
2097         /*memset(vif->cfg80211.scan_frame_array, 0, */
2098         /*MAX_SCAN_FRAME_BUF_NUM * sizeof(buf_scan_frame_t)); */
2099         printkd("[%s %d] ok!\n", __func__, vif_id);
2100         return;
2101 }
2102
2103 void cfg80211_report_mic_failure(unsigned char vif_id,
2104                                  unsigned char *pdata, int len)
2105 {
2106         struct wlan_event_mic_failure *mic_failure;
2107         wlan_vif_t *vif;
2108
2109         mic_failure = (struct wlan_event_mic_failure *)pdata;
2110         vif = id_to_vif(vif_id);
2111         if (vif) {
2112                 /* debug info,Pls remove it in the future */
2113                 printkd
2114                     ("[%s %d] is_mcast:0x%x key_id: 0x%x bssid: %x %x %x %x %x %x\n",
2115                      __func__, vif_id, mic_failure->is_mcast,
2116                      mic_failure->key_id, vif->cfg80211.bssid[0],
2117                      vif->cfg80211.bssid[1], vif->cfg80211.bssid[2],
2118                      vif->cfg80211.bssid[3], vif->cfg80211.bssid[4],
2119                      vif->cfg80211.bssid[5]);
2120                 cfg80211_michael_mic_failure(vif->ndev, vif->cfg80211.bssid,
2121                                              (mic_failure->is_mcast ?
2122                                               NL80211_KEYTYPE_GROUP :
2123                                               NL80211_KEYTYPE_PAIRWISE),
2124                                              mic_failure->key_id, NULL,
2125                                              GFP_KERNEL);
2126         }
2127 }
2128
2129 void cfg80211_report_cqm_low(unsigned char vif_id,
2130                              unsigned char *pdata, int len)
2131 {
2132         wlan_vif_t *vif = id_to_vif(vif_id);
2133
2134         if (vif) {
2135                 struct wiphy *wiphy = vif->wdev.wiphy;
2136                 wiphy_info(wiphy, "Recv NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW");
2137                 if (sprdwl_find_ssid_count(vif) >= 2) {
2138                         cfg80211_cqm_rssi_notify(vif->ndev,
2139                                                  NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
2140                                                  GFP_KERNEL);
2141                 }
2142         }
2143 }
2144
2145 void cfg80211_report_cqm_high(unsigned char vif_id,
2146                               unsigned char *pdata, int len)
2147 {
2148         wlan_vif_t *vif = id_to_vif(vif_id);
2149
2150         if (vif) {
2151                 struct wiphy *wiphy = vif->wdev.wiphy;
2152                 wiphy_info(wiphy,
2153                            "Recv  NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH");
2154                 if (sprdwl_find_ssid_count(vif) >= 2) {
2155                         cfg80211_cqm_rssi_notify(vif->ndev,
2156                                                  NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
2157                                                  GFP_KERNEL);
2158                 }
2159         }
2160 }
2161
2162 void cfg80211_report_cqm_beacon_loss(unsigned char vif_id,
2163                                      unsigned char *pdata, int len)
2164 {
2165         wlan_vif_t *vif = id_to_vif(vif_id);
2166         cfg80211_unlink_ssid(vif_id, vif->cfg80211.bssid, vif->cfg80211.ssid, vif->cfg80211.ssid_len );
2167         if (vif) {
2168                 struct wiphy *wiphy = vif->wdev.wiphy;
2169                 wiphy_info(wiphy, "Recv NL80211_CQM_RSSI_BEACON_LOSS_EVENT");
2170                 vif->beacon_loss = 1;
2171                 /*
2172                    TODO wpa_supplicant not support the event ,
2173                    so we workaround this issue
2174                  */
2175                 cfg80211_cqm_rssi_notify(vif->ndev,
2176                                          NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
2177                                          GFP_KERNEL);
2178         }
2179 }
2180
2181 void cfg80211_report_version(unsigned char vif_id,
2182                              unsigned char *pdata, int len)
2183 {
2184         unsigned char wifi_info[100] = { 0 };
2185         struct file *fp = 0;
2186         loff_t *pos;
2187         printkd
2188             ("[wifi driver version is 0x%04x] [cp version is 0x%04x date is 0x%04x]\n",
2189              g_wlan.version, *((int *)(pdata + 4)), *((int *)pdata));
2190
2191         fp = filp_open(WIFI_VERSION_FILE, O_CREAT | O_RDWR, 0666);
2192         if (IS_ERR(fp)) {
2193                 printke("%s %d err\n", __func__, __LINE__);
2194                 goto EXIT;
2195         }
2196         pos = &(fp->f_pos);
2197         sprintf(wifi_info,
2198                 "[wifi driver version is 0x%04x] [cp version is 0x%2x date is 0x%04x]",
2199                 g_wlan.version, *((int *)(pdata + 4)), *((int *)pdata));
2200         vfs_write(fp, wifi_info, strlen(wifi_info), pos);
2201
2202 EXIT:
2203         if (!(IS_ERR(fp)))
2204                 filp_close(fp, NULL);
2205         return OK;
2206 }
2207
2208 void cfg80211_report_mlme_tx_status(unsigned char vif_id,
2209                                     unsigned char *pdata, int len)
2210 {
2211         struct wlan_report_mgmt_tx_status *tx_status = NULL;
2212         wlan_vif_t *vif;
2213
2214         vif = id_to_vif(vif_id);
2215         tx_status = (struct wlan_report_mgmt_tx_status *)pdata;
2216         printkd("[%s]: index: %lld\n", __func__, tx_status->cookie);
2217         printkd("data len is %d\n", len);
2218         hex_dump("receive is:", strlen("receive is:"), pdata, len);
2219         cfg80211_mgmt_tx_status(&vif->wdev, tx_status->cookie, tx_status->buf,
2220                                 tx_status->len, tx_status->ack, GFP_KERNEL);
2221         printkd("cfg80211_mgmt_tx_status end\n");
2222 }
2223
2224 static int wlan_cfg80211_mgmt_tx(struct wiphy *wiphy,
2225 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2226                                  struct wireless_dev *wdev,
2227 #else
2228                                  struct net_device *ndev,
2229 #endif
2230 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || \
2231         defined(COMPAT_KERNEL_RELEASE))
2232                                  struct ieee80211_channel *chan, bool offchan,
2233 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
2234                                  enum nl80211_channel_type channel_type,
2235                                  bool channel_type_valid,
2236 #endif
2237                                  unsigned int wait,
2238 #else                           /*(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) */
2239                                  struct ieee80211_channel *chan,
2240                                  enum nl80211_channel_type channel_type,
2241 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || \
2242         defined(COMPAT_KERNEL_RELEASE)
2243                                  bool channel_type_valid,
2244 #endif
2245 #endif                          /*(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) */
2246                                  const u8 *buf, size_t len,
2247 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
2248                                  bool no_cck,
2249 #endif
2250 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
2251                                  bool dont_wait_for_ack,
2252 #endif
2253                                  u64 *cookie)
2254 {
2255         int ret = -1;
2256         wlan_vif_t *vif;
2257         unsigned char vif_id;
2258         static u64 mgmt_index = 0;
2259
2260         mgmt_index++;
2261         vif = ndev_to_vif(wdev->netdev);
2262         vif_id = vif->id;
2263         if (ITM_NONE_MODE == vif->mode) {
2264                 printke("%s err\n", __func__);
2265                 return -EAGAIN;
2266         }
2267
2268         printkd("[%s][%d]enter\n", __func__, vif_id);
2269         printkd("[%s], index: %lld, cookie: %lld\n", __func__, mgmt_index,
2270                 *cookie);
2271         *cookie = mgmt_index;
2272         if (len > 0) {
2273                 ret =
2274                     wlan_cmd_set_tx_mgmt(vif_id, chan, dont_wait_for_ack, wait,
2275                                          cookie, buf, len);
2276                 if (ret) {
2277                         if (dont_wait_for_ack == false)
2278                                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len,
2279                                                         0, GFP_KERNEL);
2280                         printkd("[%s] Failed to set tx mgmt!\n", __func__);
2281                         return ret;
2282                 }
2283         }
2284         return ret;
2285 }
2286
2287 static void wlan_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
2288 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2289                                               struct wireless_dev *wdev,
2290 #else
2291                                               struct net_device *ndev,
2292 #endif
2293                                               u16 frame_type, bool reg)
2294 {
2295         wlan_vif_t *vif;
2296         unsigned char vif_id;
2297         vif = ndev_to_vif(wdev->netdev);
2298         vif_id = vif->id;
2299         if (ITM_NONE_MODE == vif->mode)
2300                 return;
2301         if (NETIF_0_ID == vif_id)
2302                 return;
2303         printkd("[%s][%d]\n", __func__, vif_id);
2304         register_frame(vif, frame_type, reg);
2305         return;
2306 }
2307
2308 static int wlan_change_beacon(wlan_vif_t *vif,
2309                               struct cfg80211_beacon_data *beacon)
2310 {
2311         u16 ie_len;
2312         u8 *ie_ptr;
2313         int ret = 0;
2314         unsigned char vif_id = vif->id;
2315
2316         printkd("%s enter\n", __func__);
2317
2318         if (vif->id == NETIF_0_ID) {
2319                 /* send beacon extra ies */
2320                 if (beacon->beacon_ies != NULL) {
2321                         printkd("begin send beacon extra ies\n");
2322
2323                         ret = wlan_cmd_set_wps_ie(vif_id,
2324                                         SOFTAP_WPS_BEACON_IE,
2325                                         beacon->beacon_ies,
2326                                         beacon->beacon_ies_len);
2327                         if (ret) {
2328                                 printkd("wlan_cmd_set_wps_ie failed with %d\n", ret);
2329                                 return ret;
2330                         } else {
2331                                 printkd("send beacon extra ies successfully\n");
2332                         }
2333                 }
2334
2335                 /* send probe response ies */
2336                 if (beacon->proberesp_ies != NULL) {
2337                         printkd("begin send probe response extra ies\n");
2338
2339                         ret = wlan_cmd_set_wps_ie(vif_id,
2340                                         SOFTAP_WPS_PROBERESP_IE,
2341                                         beacon->proberesp_ies,
2342                                         beacon->proberesp_ies_len);
2343                         if (ret) {
2344                                 printkd("wlan_cmd_set_wps_ie failed with %d\n", ret);
2345                                 return ret;
2346                         } else {
2347                                 printkd("send proberesp_ies successfully\n");
2348                         }
2349                 }
2350
2351                 /* send associate response ies */
2352                 if (beacon->assocresp_ies != NULL) {
2353                         printkd("begin send associate response extra ies\n");
2354
2355                         ret = wlan_cmd_set_wps_ie(vif_id,
2356                                         SOFTAP_WPS_ASSOCRESP_IE,
2357                                         beacon->assocresp_ies,
2358                                         beacon->assocresp_ies_len);
2359                         if (ret) {
2360                                 printkd("wlan_cmd_set_wps_ie failed with %d\n", ret);
2361                                 return ret;
2362                         } else {
2363                                 printkd("send assocresp_iessuccessfully\n");
2364                         }
2365                 }
2366
2367                 return ret;
2368         }
2369
2370 #ifdef WIFI_DIRECT_SUPPORT
2371         /* send beacon extra ies */
2372         if (beacon->head != NULL) {
2373                 ie_len = beacon->head_len;
2374                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2375                 if (ie_ptr == NULL) {
2376                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2377                         return -EINVAL;
2378                 }
2379                 memcpy(ie_ptr, beacon->head, ie_len);
2380                 printkd("begin send beacon head ies\n");
2381
2382                 ret =
2383                     wlan_cmd_set_p2p_ie(vif_id, P2P_BEACON_IE_HEAD, ie_ptr,
2384                                         ie_len);
2385                 if (ret) {
2386                         printkd
2387                             ("itm_wlan_set_p2p_ie beacon_ies head failed with ret %d\n",
2388                              ret);
2389                 } else {
2390                         printkd("send beacon head ies successfully\n");
2391                 }
2392
2393                 kfree(ie_ptr);
2394         }
2395
2396         /* send beacon extra ies */
2397         if (beacon->tail != NULL) {
2398                 ie_len = beacon->tail_len;
2399
2400                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2401                 if (ie_ptr == NULL) {
2402                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2403                         return -EINVAL;
2404                 }
2405                 memcpy(ie_ptr, beacon->tail, ie_len);
2406                 printkd("begin send beacon tail ies\n");
2407
2408                 ret = wlan_cmd_set_p2p_ie(vif_id,
2409                                           P2P_BEACON_IE_TAIL, ie_ptr, ie_len);
2410                 if (ret) {
2411                         printkd
2412                             ("wlan_cmd_set_p2p_ie beacon_ies tail failed with ret %d\n",
2413                              ret);
2414                 } else {
2415                         printkd("send beacon tail ies successfully\n");
2416                 }
2417
2418                 kfree(ie_ptr);
2419         }
2420
2421         /* send probe response ies */
2422
2423         /* send beacon extra ies */
2424         if (beacon->beacon_ies != NULL) {
2425                 ie_len = beacon->beacon_ies_len;
2426
2427                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2428                 if (ie_ptr == NULL) {
2429                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2430                         return -EINVAL;
2431                 }
2432                 memcpy(ie_ptr, beacon->beacon_ies, ie_len);
2433                 printkd("begin send beacon extra ies\n");
2434
2435                 ret =
2436                     wlan_cmd_set_p2p_ie(vif_id, P2P_BEACON_IE, ie_ptr, ie_len);
2437                 if (ret) {
2438                         printkd
2439                             ("wlan_cmd_set_p2p_ie beacon_ies failed with ret %d\n",
2440                              ret);
2441                 } else {
2442                         printkd("send beacon extra ies successfully\n");
2443                 }
2444
2445                 kfree(ie_ptr);
2446         }
2447
2448         /* send probe response ies */
2449
2450         if (beacon->proberesp_ies != NULL) {
2451                 printkd("%s line:%d\n", __func__, __LINE__);
2452                 ie_len = beacon->proberesp_ies_len;
2453
2454                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2455                 if (ie_ptr == NULL) {
2456                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2457                         return -EINVAL;
2458                 }
2459                 memcpy(ie_ptr, beacon->proberesp_ies, ie_len);
2460                 printkd("begin send probe response extra ies\n");
2461
2462                 ret =
2463                     wlan_cmd_set_p2p_ie(vif_id, P2P_PROBERESP_IE, ie_ptr,
2464                                         ie_len);
2465                 if (ret) {
2466                         printkd
2467                             ("wlan_cmd_set_p2p_ie proberesp_ies failed with ret %d\n",
2468                              ret);
2469                 } else {
2470                         printkd("send probe response ies successfully\n");
2471                 }
2472
2473                 kfree(ie_ptr);
2474         }
2475
2476         /* send associate response ies */
2477
2478         if (beacon->assocresp_ies != NULL) {
2479                 printkd("%s line:%d\n", __func__, __LINE__);
2480                 ie_len = beacon->assocresp_ies_len;
2481
2482                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2483                 if (ie_ptr == NULL) {
2484                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2485                         return -EINVAL;
2486                 }
2487                 memcpy(ie_ptr, beacon->assocresp_ies, ie_len);
2488                 printkd("begin send associate response extra ies\n");
2489
2490                 ret =
2491                     wlan_cmd_set_p2p_ie(vif_id, P2P_ASSOCRESP_IE, ie_ptr,
2492                                         ie_len);
2493                 if (ret) {
2494                         printkd
2495                             ("wlan_cmd_set_p2p_ie assocresp_ies failed with ret %d\n",
2496                              ret);
2497                 } else {
2498                         printkd("send associate response ies successfully\n");
2499                 }
2500
2501                 kfree(ie_ptr);
2502         }
2503 #endif /*WIFI_DIRECT_SUPPORT */
2504         return ret;
2505 }
2506
2507 static int wlan_cfg80211_set_mac_acl(struct wiphy *wiphy,
2508                                      struct net_device *ndev,
2509                                      const struct cfg80211_acl_data *acl)
2510 {
2511         int index, ret, macnum;
2512         int macmode = MACLIST_MODE_DISABLED;
2513         unsigned char *cmdData  = NULL;
2514         char mac[ETH_ALEN] = {0};
2515
2516         wlan_vif_t  *vif = ndev_to_vif(ndev);
2517         unsigned char  vif_id = vif->id;
2518
2519         if (!acl || acl->n_acl_entries == 0 || !acl->mac_addrs) {
2520                 printkd("no acl data or no mac address\n");
2521                 return  0;
2522         }
2523
2524         /* get the MAC filter mode */
2525         if (acl && acl->acl_policy == NL80211_ACL_POLICY_DENY_UNLESS_LISTED) {
2526                 macmode = MACLIST_MODE_WHITELIST;
2527         } else if (acl && acl->acl_policy ==
2528                    NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED) {
2529                 macmode = MACLIST_MODE_BLACKLIST;
2530         } else {
2531                 printkd("Invalid acl policy\n");
2532                 return -EINVAL;
2533         }
2534
2535         macnum = acl->n_acl_entries;
2536         printkd("the num for mac : %d\n", macnum);
2537         if (macnum < 0 || macnum > MAX_NUM_MAC_FILT)
2538                 return -EINVAL;
2539
2540         if (macmode == MACLIST_MODE_WHITELIST) {
2541                 cmdData = kzalloc(macnum * ETH_ALEN + 1, GFP_KERNEL);
2542                 if (IS_ERR(cmdData))
2543                         return  -ENOMEM;
2544                 cmdData[0] = macnum;
2545                 for (index = 0; index < macnum; index++) {
2546                         printkd("the mac is : %pM\n", &acl->mac_addrs[index]);
2547                         memcpy(cmdData + index * ETH_ALEN + 1,
2548                                &acl->mac_addrs[index], ETH_ALEN);
2549                 }
2550                 ret = wlan_cmd_enable_whitelist(vif->id, cmdData);
2551         }
2552
2553         if (macmode == MACLIST_MODE_BLACKLIST) {
2554                 for (index = 0; index < macnum; index++) {
2555                         memcpy(mac, &acl->mac_addrs[index], ETH_ALEN);
2556                         printkd("add blacklist mac is : %pM\n", mac);
2557                         ret = wlan_cmd_add_blacklist(vif->id, mac);
2558                 }
2559         }
2560         return ret;
2561 }
2562
2563 static int itm_wlan_start_ap(wlan_vif_t *vif,
2564                              struct cfg80211_beacon_data *beacon)
2565 {
2566 #define SSID_LEN_OFFSET                (37)
2567         struct ieee80211_mgmt *mgmt;
2568         u16 mgmt_len, index = 0;
2569         int ret;
2570         unsigned char vif_id = vif->id;
2571         u8 *data = NULL;
2572         struct wlan_cmd_hidden_ssid *hssid = &(vif->hssid);
2573         printkd("%s enter\n", __func__);
2574         wlan_change_beacon(vif, beacon);
2575         if (beacon->head == NULL) {
2576                 printke("%s line:%d err\n", __func__, __LINE__);
2577                 return -EINVAL;
2578         }
2579         mgmt_len = beacon->head_len;
2580
2581         /*add 1 byte for hidden ssid flag */
2582         mgmt_len += 1;
2583
2584         if (beacon->tail)
2585                 mgmt_len += beacon->tail_len;
2586
2587         mgmt = kmalloc(mgmt_len, GFP_KERNEL);
2588         if (mgmt == NULL) {
2589                 printkd("[%s][%d][%d]\n", __func__, __LINE__, mgmt);
2590                 return -EINVAL;
2591         }
2592         data = (u8 *) mgmt;
2593
2594         memcpy(data, beacon->head, SSID_LEN_OFFSET);
2595         index += SSID_LEN_OFFSET;
2596
2597         /*hostapd config ssid by ioctl */
2598         if (hssid->ssid_len == (unsigned char)*(beacon->head + index)) {
2599                 /*modify ssid_len */
2600                 *(data + index) = (unsigned char)(hssid->ssid_len + 1);
2601                 index += 1;
2602                 /*copy ssid */
2603                 memcpy(data + index, hssid->ssid, hssid->ssid_len);
2604                 index += hssid->ssid_len;
2605                 /*set hidden ssid flag */
2606                 *(data + index) = (unsigned char)(hssid->ignore_broadcast_ssid);
2607                 index += 1;
2608         } else {                /*hostapd not config ssid */
2609                 unsigned char org_len = (unsigned char)*(beacon->head + index);
2610                 /*modify ssid_len */
2611                 *(data + index) = org_len + 1;
2612                 index += 1;
2613                 /*copy ssid */
2614                 memcpy(data + index, beacon->head + index, org_len);
2615                 index += org_len;
2616                 /*set no hidden ssid flag */
2617                 *(data + index) = 0;
2618                 index += 1;
2619         }
2620         /*cope left info */
2621         memcpy(data + index, beacon->head + index - 1,
2622                beacon->head_len + 1 - index);
2623
2624         if (beacon->tail)
2625                 memcpy(data + beacon->head_len + 1,
2626                        beacon->tail, beacon->tail_len);
2627
2628         ret = wlan_cmd_start_ap(vif_id, (unsigned char *)mgmt, mgmt_len);
2629         kfree(mgmt);
2630         if (!netif_carrier_ok(vif->ndev)) {
2631                 printkd("%s(), netif_carrier_on, ssid:%s\n", __func__,
2632                         vif->cfg80211.ssid);
2633                 netif_carrier_on(vif->ndev);
2634                 netif_wake_queue(vif->ndev);
2635         }
2636         if (ret != 0) {
2637                 printke("%s line:%d err\n", __func__, __LINE__);
2638         }
2639         return ret;
2640 }
2641
2642 static int wlan_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
2643                                   struct cfg80211_ap_settings *info)
2644 {
2645         wlan_vif_t *vif;
2646         unsigned char vif_id;
2647         int ret;
2648         vif = ndev_to_vif(ndev);
2649         vif_id = vif->id;
2650         if (ITM_NONE_MODE == vif->mode)
2651                 return -EAGAIN;
2652         printkd("[%s][%d] enter\n", __func__, vif_id);
2653         if (info->ssid == NULL) {
2654                 printkd("%s line:%d\n", __func__, __LINE__);
2655                 return -EINVAL;
2656         }
2657         printkd("[cfg80211] \t ==>>>%s\n", __func__);
2658         memcpy(vif->cfg80211.ssid, info->ssid, info->ssid_len);
2659         vif->cfg80211.ssid_len = info->ssid_len;
2660         if (info->acl) {
2661                 ret = wlan_cfg80211_set_mac_acl(wiphy, ndev, info->acl);
2662                 if (ret) {
2663                         printkd("set acl failed when start ap\n");
2664                         return ret;
2665                 }
2666         }
2667         return itm_wlan_start_ap(vif, &info->beacon);
2668 }
2669
2670 static int wlan_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
2671 {
2672         int ret = 0;
2673         wlan_vif_t *vif;
2674         unsigned char vif_id;
2675         vif = ndev_to_vif(ndev);
2676         vif_id = vif->id;
2677         if (ITM_NONE_MODE == vif->mode)
2678                 return -EAGAIN;
2679         printkd("[%s][%d] enter\n", __func__, vif_id);
2680         ret = wlan_cmd_mac_close(vif_id, vif->mode);
2681         return ret;
2682 }
2683
2684 static int wlan_cfg80211_change_beacon(struct wiphy *wiphy,
2685                                        struct net_device *ndev,
2686                                        struct cfg80211_beacon_data *beacon)
2687 {
2688         wlan_vif_t *vif;
2689         unsigned char vif_id;
2690         vif = ndev_to_vif(ndev);
2691         vif_id = vif->id;
2692         if (ITM_NONE_MODE == vif->mode)
2693                 return -EAGAIN;
2694         printkd("[%s][%d] enter\n", __func__, vif_id);
2695 #ifdef WIFI_DIRECT_SUPPORT
2696         return wlan_change_beacon(vif, beacon);
2697 #else
2698         return itm_wlan_start_ap(vif, beacon);
2699 #endif
2700
2701 }
2702
2703 static int itm_wlan_change_mode(wlan_vif_t *vif, enum nl80211_iftype type)
2704 {
2705         int mode = 0;
2706         int ret;
2707         unsigned char vif_id = vif->id;
2708         switch (type) {
2709         case NL80211_IFTYPE_STATION:
2710                 if (NETIF_0_ID == vif->id)
2711                         mode = ITM_STATION_MODE;
2712                 else
2713                         mode = ITM_P2P_CLIENT_MODE;
2714                 break;
2715         case NL80211_IFTYPE_AP:
2716                 if (NETIF_0_ID == vif->id)
2717                         mode = ITM_AP_MODE;
2718                 else
2719                         mode = ITM_P2P_GO_MODE;
2720                 break;
2721         case NL80211_IFTYPE_P2P_CLIENT:
2722                 mode = ITM_P2P_CLIENT_MODE;
2723                 break;
2724         case NL80211_IFTYPE_P2P_GO:
2725                 mode = ITM_P2P_GO_MODE;
2726                 break;
2727         default:
2728                 printkd("invalid interface type %u\n", type);
2729                 return -EOPNOTSUPP;
2730         }
2731         vif->wdev.iftype = type;
2732         if (mode == vif->mode) {
2733                 printkd("not need change mode\n");
2734                 return 0;
2735         }
2736         vif->wdev.iftype = type;
2737         vif->mode = mode;
2738         printkd("[%s][%d][%d]\n", __func__, vif_id, mode);
2739         ret = wlan_cmd_mac_open(vif_id, mode, vif->ndev->dev_addr);
2740         if (OK != ret)
2741                 return -EIO;
2742         vif->wdev.iftype = type;
2743         vif->mode = mode;
2744 #ifdef CONFIG_MACH_SAMSUNG
2745         wlan_cmd_set_psm_cap();
2746 #endif
2747         return OK;
2748 }
2749
2750 static int wlan_cfg80211_change_iface(struct wiphy *wiphy,
2751                                       struct net_device *ndev,
2752                                       enum nl80211_iftype type,
2753                                       unsigned int *flags,
2754                                       struct vif_params *params)
2755 {
2756         wlan_vif_t *vif;
2757         unsigned char vif_id;
2758         vif = ndev_to_vif(ndev);
2759         vif_id = vif->id;
2760 #ifdef WIFI_DIRECT_SUPPORT
2761         if (NETIF_1_ID == vif_id) {
2762                 vif->cfg80211.p2p_mode = itm_get_p2p_mode_from_file();
2763                 printkd("[%s][%d][%d]\n", __func__, vif_id,
2764                         (vif->cfg80211.p2p_mode ? 1 : 0));
2765         }
2766 #endif /* WIFI_DIRECT_SUPPORT */
2767         return itm_wlan_change_mode(vif, type);
2768 }
2769
2770 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2771 static int wlan_cfg80211_set_channel(struct wiphy *wiphy,
2772                                      struct net_device *ndev,
2773                                      struct ieee80211_channel *channel)
2774 #else
2775 static int wlan_cfg80211_set_channel(struct wiphy *wiphy,
2776                                      struct net_device *ndev,
2777                                      struct ieee80211_channel *channel,
2778                                      enum nl80211_channel_type channel_type)
2779 #endif
2780 {
2781         int ret = -ENOTSUPP;
2782         wlan_vif_t *vif;
2783         unsigned char vif_id;
2784         vif = ndev_to_vif(ndev);
2785         vif_id = vif->id;
2786         if (ITM_NONE_MODE == vif->mode)
2787                 return -EAGAIN;
2788         printkd("[%s][%d] enter\n", __func__, vif_id);
2789         /*
2790          * FIXME: To be handled properly when monitor mode is supported.
2791          */
2792         ret =
2793             wlan_cmd_set_channel(vif_id,
2794                                  ieee80211_frequency_to_channel
2795                                  (channel->center_freq));
2796         if (ret < 0) {
2797                 printkd("wlan_cmd_set_channel failed with ret %d\n", ret);
2798                 return ret;
2799         }
2800
2801         return 0;
2802 }
2803
2804 int wlan_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *ndev,
2805                                 struct cfg80211_update_ft_ies_params *ftie)
2806 {
2807         wlan_vif_t *vif;
2808         unsigned char vif_id;
2809         vif = ndev_to_vif(ndev);
2810         vif_id = vif->id;
2811         printkd("%s enter\n", __func__);
2812         return wlan_cmd_update_ft_ies(vif_id, ftie);
2813 }
2814
2815 static void wlan_cfg80211_reg_notify(struct wiphy *wiphy,
2816                                      struct regulatory_request *request)
2817 {
2818         struct ieee80211_supported_band *sband;
2819         struct ieee80211_channel *chan;
2820         const struct ieee80211_freq_range *freq_range;
2821         const struct ieee80211_reg_rule *reg_rule;
2822         wlan_ieee80211_regdomain *rd = NULL;
2823         u32 band, channel, i;
2824         u32 last_start_freq;
2825         u32 n_rules = 0, rd_size;
2826         static int num;
2827
2828         wiphy_info(wiphy, "%s %c%c initiator %d hint_type %d\n", __func__,
2829                    request->alpha2[0], request->alpha2[1], request->initiator,
2830                    request->user_reg_hint_type);
2831
2832         if ((num != 1) && (num != 2)) {
2833                 num++;
2834                 return;
2835         }
2836
2837         /* Figure out the actual rule number */
2838         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2839                 sband = wiphy->bands[band];
2840                 if (!sband)
2841                         continue;
2842
2843                 last_start_freq = 0;
2844                 for (channel = 0; channel < sband->n_channels; channel++) {
2845                         chan = &sband->channels[channel];
2846
2847                         reg_rule =
2848                             freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
2849                         if (IS_ERR(reg_rule))
2850                                 continue;
2851
2852                         freq_range = &reg_rule->freq_range;
2853                         if (last_start_freq != freq_range->start_freq_khz) {
2854                                 last_start_freq = freq_range->start_freq_khz;
2855                                 n_rules++;
2856                         }
2857                 }
2858         }
2859         rd_size = sizeof(wlan_ieee80211_regdomain) +
2860             n_rules * sizeof(struct ieee80211_reg_rule);
2861
2862         rd = kzalloc(rd_size, GFP_KERNEL);
2863         if (!rd) {
2864                 wiphy_err(wiphy,
2865                           "Failed to allocate itm_ieee80211_regdomain\n");
2866                 return;
2867         }
2868
2869         /* Fill regulatory domain */
2870         rd->n_reg_rules = n_rules;
2871         memcpy(rd->alpha2, request->alpha2, ARRAY_SIZE(rd->alpha2));
2872         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2873                 sband = wiphy->bands[band];
2874                 if (!sband)
2875                         continue;
2876
2877                 last_start_freq = 0;
2878                 for (channel = i = 0; channel < sband->n_channels; channel++) {
2879                         chan = &sband->channels[channel];
2880
2881                         if (chan->flags & IEEE80211_CHAN_DISABLED)
2882                                 continue;
2883
2884                         reg_rule =
2885                             freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
2886                         if (IS_ERR(reg_rule))
2887                                 continue;
2888
2889                         freq_range = &reg_rule->freq_range;
2890                         if (last_start_freq != freq_range->start_freq_khz
2891                             && i < n_rules) {
2892                                 last_start_freq = freq_range->start_freq_khz;
2893                                 memcpy(&rd->reg_rules[i], reg_rule,
2894                                        sizeof(struct ieee80211_reg_rule));
2895                                 i++;
2896                                 wiphy_dbg(wiphy,
2897                                           "%s %d KHz - %d KHz @ %d KHz flags %#x\n",
2898                                           __func__, freq_range->start_freq_khz,
2899                                           freq_range->end_freq_khz,
2900                                           freq_range->max_bandwidth_khz,
2901                                           reg_rule->flags);
2902                         }
2903                 }
2904         }
2905         if (wlan_cmd_set_regdom(0, (u8 *) rd, rd_size))
2906                 wiphy_err(wiphy, "%s failed to set regdomain!\n", __func__);
2907         kfree(rd);
2908         num++;
2909 }
2910
2911 int lte_concur_proc_open(struct inode *inode, struct file *filp)
2912 {
2913         return 0;
2914 }
2915
2916 int lte_concur_proc_release(struct inode *inode, struct file *filp)
2917 {
2918         return 0;
2919 }
2920
2921 ssize_t lte_concur_proc_ioctl(struct file *filp, unsigned int cmd,
2922                               unsigned long arg)
2923 {
2924         int ret = 0;
2925         lte_concur_data_t *val;
2926         unsigned char buff[100];
2927         int len;
2928         switch (cmd) {
2929         case LTE_CONCUR_REQ:
2930                 if (copy_from_user
2931                     (buff, (unsigned char *)arg,
2932                      ((lte_concur_data_t *) arg)->size +
2933                      sizeof(lte_concur_data_t))) {
2934                         return -EFAULT;
2935                 }
2936
2937                 val = (lte_concur_data_t *) buff;
2938                 len = val->size;
2939                 ret =
2940                     wlan_cmd_req_lte_concur(0,
2941                                             (unsigned char *)val +
2942                                             sizeof(lte_concur_data_t), len);
2943                 if (ret < 0) {
2944                         printkd("wlan_cmd_req_lte_concur failed with ret %d\n",
2945                                 ret);
2946                         return ret;
2947                 }
2948                 break;
2949         default:
2950                 break;
2951         }
2952         return 0;
2953 }
2954
2955 /*
2956  * CFG802.11 operation handler for connection quality monitoring.
2957  *
2958  * This function subscribes/unsubscribes HIGH_RSSI and LOW_RSSI
2959  * events to FW.
2960  */
2961 int wlan_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
2962                                       struct net_device *ndev,
2963                                       s32 rssi_thold, u32 rssi_hyst)
2964 {
2965         int ret = -ENOTSUPP;
2966         wlan_vif_t *vif = ndev_to_vif(ndev);
2967         unsigned char vif_id = vif->id;
2968         if (ITM_NONE_MODE == vif->mode)
2969                 return -EAGAIN;
2970         wiphy_info(wiphy, "[%s][%d] rssi_thold %d rssi_hyst %d",
2971                    __func__, vif_id, rssi_thold, rssi_hyst);
2972         if (rssi_thold && rssi_hyst)
2973                 ret = wlan_cmd_cmq_rssi(vif_id, rssi_thold, rssi_hyst,
2974                                         WIFI_CMD_SET_CQM_RSSI);
2975         return ret;
2976 }
2977
2978 static struct cfg80211_ops wlan_cfg80211_ops = {
2979         .scan = wlan_cfg80211_scan,
2980         .connect = wlan_cfg80211_connect,
2981         .disconnect = wlan_cfg80211_disconnect,
2982         .add_key = wlan_cfg80211_add_key,
2983         .del_key = wlan_cfg80211_del_key,
2984         .set_default_key = wlan_cfg80211_set_default_key,
2985         .set_wiphy_params = wlan_cfg80211_set_wiphy_params,
2986         .get_station = wlan_cfg80211_get_station,
2987         .set_pmksa = wlan_cfg80211_set_pmksa,
2988         .del_pmksa = wlan_cfg80211_del_pmksa,
2989         .flush_pmksa = wlan_cfg80211_flush_pmksa,
2990         .start_ap = wlan_cfg80211_start_ap,
2991         .change_beacon = wlan_cfg80211_change_beacon,
2992         .stop_ap = wlan_cfg80211_stop_ap,
2993         .mgmt_tx = wlan_cfg80211_mgmt_tx,
2994         .mgmt_frame_register = wlan_cfg80211_mgmt_frame_register,
2995         .change_virtual_intf = wlan_cfg80211_change_iface,
2996         .update_ft_ies = wlan_cfg80211_update_ft_ies,
2997         .set_cqm_rssi_config = wlan_cfg80211_set_cqm_rssi_config,
2998         .set_mac_acl = wlan_cfg80211_set_mac_acl,
2999 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
3000         .libertas_set_mesh_channel = wlan_cfg80211_set_channel,
3001 #else
3002         .set_channel = wlan_cfg80211_set_channel,
3003 #endif
3004
3005 #ifdef WIFI_DIRECT_SUPPORT
3006         .remain_on_channel = wlan_cfg80211_remain_on_channel,
3007         .cancel_remain_on_channel = wlan_cfg80211_cancel_remain_on_channel,
3008         .del_station = wlan_cfg80211_del_station,
3009 #endif
3010 };
3011
3012 /*Init wiphy parameters*/
3013 static void init_wiphy_parameters(struct wiphy *wiphy)
3014 {
3015         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3016         wiphy->mgmt_stypes = itm_mgmt_stypes;
3017
3018         wiphy->max_scan_ssids = MAX_SITES_FOR_SCAN;
3019         wiphy->max_scan_ie_len = SCAN_IE_LEN_MAX;
3020         wiphy->max_num_pmkids = MAX_NUM_PMKIDS;
3021
3022         wiphy->interface_modes =
3023             BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_STATION) |
3024             BIT(NL80211_IFTYPE_AP);
3025
3026         wiphy->interface_modes |=
3027             BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) |
3028             BIT(NL80211_IFTYPE_P2P_DEVICE);
3029         wiphy->max_remain_on_channel_duration = 2000;
3030         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
3031         /* set AP SME flag, also needed by STA mode? */
3032         wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
3033         wiphy->ap_sme_capa = 1;
3034         wiphy->max_acl_mac_addrs = MAX_NUM_MAC_FILT;
3035
3036         wiphy->software_iftypes =
3037             BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_STATION) |
3038             BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) |
3039             BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_DEVICE);
3040         /*Attach cipher suites */
3041         wiphy->cipher_suites = itm_cipher_suites;
3042         wiphy->n_cipher_suites = ARRAY_SIZE(itm_cipher_suites);
3043         /*Attach bands */
3044         wiphy->bands[IEEE80211_BAND_2GHZ] = &itm_band_2ghz;
3045         /*wiphy->bands[IEEE80211_BAND_5GHZ] = &itm_band_5ghz; */
3046
3047         /*Default not in powersave state */
3048         wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3049         wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3050 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
3051         /*Set WoWLAN flags */
3052         wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT;
3053 #endif
3054         wiphy->reg_notifier = wlan_cfg80211_reg_notify;
3055 }
3056
3057 int wlan_wiphy_new(wlan_info_t *wlan)
3058 {
3059         int ret;
3060         printke("%s enter\n", __func__);
3061         wlan->wiphy = wiphy_new(&wlan_cfg80211_ops, 0);
3062         if (wlan->wiphy == NULL) {
3063                 ASSERT();
3064                 return ERROR;
3065         }
3066         *(struct wlan_info_t **)wiphy_priv(wlan->wiphy) = wlan;
3067         set_wiphy_dev(wlan->wiphy, wlan->dev);
3068         init_wiphy_parameters(wlan->wiphy);
3069         ret = wiphy_register(wlan->wiphy);
3070         if (ret < 0) {
3071                 printke("%s err:%d\n", __func__, ret);
3072                 ASSERT();
3073                 goto out_free_wiphy;
3074         }
3075         return OK;
3076 out_free_wiphy:
3077         wiphy_free(wlan->wiphy);
3078         return ERROR;
3079 }
3080
3081 int wlan_wiphy_free(wlan_info_t *wlan)
3082 {
3083         int i;
3084         wlan_vif_t *vif;
3085         if (NULL == wlan)
3086                 return ERROR;
3087         for (i = 0; i < 2; i++) {
3088                 vif = &(g_wlan.netif[i]);
3089                 if (vif->cfg80211.scan_request
3090                     && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) ==
3091                         1)) {
3092                         if (vif->cfg80211.scan_request->wiphy !=
3093                             vif->wdev.wiphy) {
3094                                 printkd
3095                                     ("Scan request is from a wrong wiphy device\n");
3096                         } else {
3097                                 /*If there's a pending scan request,abort it */
3098                                 cfg80211_scan_done(vif->cfg80211.scan_request,
3099                                                    1);
3100                         }
3101                         vif->cfg80211.scan_request = NULL;
3102 #ifdef CONFIG_HAS_WAKELOCK
3103                         if (vif->cfg80211.scan_done_lock.link.next !=
3104                             LIST_POISON1
3105                             && vif->cfg80211.scan_done_lock.link.prev !=
3106                             LIST_POISON2)
3107                                 wake_unlock(&vif->cfg80211.scan_done_lock);
3108 #endif
3109                         atomic_dec(&vif->cfg80211.scan_status);
3110                 }
3111 #ifdef CONFIG_HAS_WAKELOCK
3112                 wake_lock_destroy(&vif->cfg80211.scan_done_lock);
3113 #endif
3114                 del_timer_sync(&(vif->cfg80211.scan_timeout));
3115                 vfree(vif->cfg80211.scan_frame_array);
3116                 vif->cfg80211.scan_frame_array = NULL;
3117         }
3118         wiphy_unregister(wlan->wiphy);
3119         wiphy_free(wlan->wiphy);
3120         wlan->wiphy = NULL;
3121         return OK;
3122 }
3123
3124 int mac_addr_cfg(wlan_vif_t *vif, unsigned char vif_id)
3125 {
3126         struct file *fp = 0;
3127         mm_segment_t fs;
3128         loff_t *pos;
3129         bool no_file = false;
3130         unsigned char file_data[64] = { 0 };
3131         unsigned char mac_addr[18] = { 0 };
3132         unsigned char *tmp_p = NULL;
3133         fs = get_fs();
3134         set_fs(KERNEL_DS);
3135
3136         fp = filp_open(ENG_MAC_ADDR_PATH, O_RDONLY, 0);
3137         if (IS_ERR(fp)) {
3138                 random_ether_addr(vif->ndev->dev_addr);
3139 #ifdef CONFIG_MACH_SAMSUNG
3140                 vif->ndev->dev_addr[0] = 0x00;
3141                 vif->ndev->dev_addr[1] = 0x12;
3142                 vif->ndev->dev_addr[2] = 0x36;
3143 #endif /* CONFIG_MACH_SAMSUNG */
3144                 fp = filp_open(ENG_MAC_ADDR_PATH, O_CREAT | O_RDWR, 0666);
3145                 if (IS_ERR(fp)) {
3146                         printke("%s %d err\n", __func__, __LINE__);
3147                         goto EXIT;
3148                 }
3149                 no_file = true;
3150         }
3151         pos = &(fp->f_pos);
3152         if (false == no_file) {
3153                 tmp_p = file_data;
3154                 vfs_read(fp, file_data, sizeof(file_data), pos);
3155                 memcpy(mac_addr, tmp_p, 18);
3156                 sscanf(mac_addr, "%02X:%02X:%02X:%02X:%02X:%02X",
3157                        (unsigned int *)&(vif->ndev->dev_addr[0]),
3158                        (unsigned int *)&(vif->ndev->dev_addr[1]),
3159                        (unsigned int *)&(vif->ndev->dev_addr[2]),
3160                        (unsigned int *)&(vif->ndev->dev_addr[3]),
3161                        (unsigned int *)&(vif->ndev->dev_addr[4]),
3162                        (unsigned int *)&(vif->ndev->dev_addr[5]));
3163                 mac_addr[17] = '\n';
3164         } else {
3165                 sprintf(mac_addr, "%02X:%02X:%02X:%02X:%02X:%02X\n",
3166                         vif->ndev->dev_addr[0],
3167                         vif->ndev->dev_addr[1],
3168                         vif->ndev->dev_addr[2],
3169                         vif->ndev->dev_addr[3],
3170                         vif->ndev->dev_addr[4],
3171                         vif->ndev->dev_addr[5]);
3172                 vfs_write(fp, mac_addr, 18, pos);
3173                 printke("[%s write addr:%s]\n", __func__, mac_addr);
3174         }
3175
3176         if (vif_id)
3177                 vif->ndev->dev_addr[0] = vif->ndev->dev_addr[0] ^ 0x02;
3178         else {
3179                 if (!(IS_ERR(fp))) {
3180                         filp_close(fp, NULL);
3181                 }
3182
3183                 fp = filp_open(ENG_MAC_ADDR_INFO_PATH, O_CREAT | O_RDWR, 0666);
3184                 if (IS_ERR(fp))
3185                         printke("[%s %s: File create err]\n", __func__, ENG_MAC_ADDR_INFO_PATH);
3186                 else {
3187                         pos = &(fp->f_pos);
3188                         vfs_write(fp, mac_addr, 18, pos);
3189                         printke("[%s write addr:%s to %s]\n", __func__, mac_addr, ENG_MAC_ADDR_INFO_PATH);
3190                 }
3191         }
3192
3193 EXIT:
3194         if (!(IS_ERR(fp))) {
3195                 filp_close(fp, NULL);
3196         }
3197         set_fs(fs);
3198         return OK;
3199 }
3200
3201 int wlan_vif_init(wlan_vif_t *vif, int type, const char *name, void *ops)
3202 {
3203         int ret;
3204         struct net_device *ndev;
3205         unsigned char str[64] = { 0 };
3206         ndev = alloc_netdev(4, name, ether_setup);
3207         if (!ndev) {
3208                 ASSERT();
3209                 return ERROR;
3210         }
3211         vif->ndev = ndev;
3212         vif->beacon_loss = 0;
3213         memcpy((unsigned char *)(netdev_priv(ndev)), (unsigned char *)(&vif),
3214                4);
3215         ndev->netdev_ops = ops;
3216         ndev->watchdog_timeo = 1 * HZ;
3217         ndev->ieee80211_ptr = &(vif->wdev);
3218         vif->wdev.iftype = type;
3219         init_register_frame_param(vif);
3220         init_send_deauth_work(vif);
3221         vif->wdev.wiphy = g_wlan.wiphy;
3222         SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3223         vif->wdev.netdev = ndev;
3224         init_timer(&(vif->cfg80211.scan_timeout));
3225         vif->cfg80211.scan_timeout.data = (unsigned long)vif;
3226         vif->cfg80211.scan_timeout.function = wlan_scan_timeout;
3227         vif->cfg80211.scan_request = NULL;
3228         vif->cfg80211.scan_frame_array =
3229             vmalloc(MAX_SCAN_FRAME_BUF_NUM * sizeof(buf_scan_frame_t));
3230         memset(vif->cfg80211.scan_frame_array, 0,
3231                MAX_SCAN_FRAME_BUF_NUM * sizeof(buf_scan_frame_t));
3232         atomic_set(&vif->cfg80211.scan_status, 0);
3233         vif->cfg80211.connect_status = ITM_DISCONNECTED;
3234         memset(vif->cfg80211.bssid, 0, sizeof(vif->cfg80211.bssid));
3235         vif->mode = ITM_NONE_MODE;
3236 #ifdef CONFIG_HAS_WAKELOCK
3237         wake_lock_init(&(vif->cfg80211.scan_done_lock), WAKE_LOCK_SUSPEND,
3238                        "scan_lock");
3239 #endif
3240         mac_addr_cfg(vif, vif->id);
3241         ret = register_netdev(vif->ndev);
3242         if (ret < 0) {
3243                 printkd("[%s][register_netdev err:%d]\n", __func__, ret);
3244                 return ERROR;
3245         }
3246         sprintf(str, "[%s][%d][%s][0x%p][addr]:", __func__, vif->id,
3247                 vif->ndev->name, vif->ndev);
3248         hex_dump(str, strlen(str), (unsigned char *)(&(vif->ndev->dev_addr[0])),
3249                  6);
3250         return OK;
3251 }
3252
3253 int wlan_vif_free(wlan_vif_t *vif)
3254 {
3255         if (NULL == vif->ndev)
3256                 return ERROR;
3257         printkd("[unregister_netdev][%s][0x%p]\n", __func__, vif->ndev->name);
3258         cancel_work_sync(&vif->cfg80211.register_frame.work);
3259         cancel_work_sync(&vif->deauth_info.work);
3260         unregister_netdev(vif->ndev);
3261         printkd("[free_netdev][%s][0x%p]\n", __func__, vif->ndev->name);
3262         free_netdev(vif->ndev);
3263         printkd("%s(), ok\n", __func__);
3264         return OK;
3265 }
3266
3267 wlan_vif_t *id_to_vif(unsigned char id)
3268 {
3269         if ((NETIF_0_ID != id) && (NETIF_1_ID != id))
3270                 return NULL;
3271         return &(g_wlan.netif[id]);
3272 }
3273
3274 wlan_vif_t *ndev_to_vif(struct net_device * ndev)
3275 {
3276         wlan_vif_t *vif;
3277         memcpy((unsigned char *)(&vif), (unsigned char *)(netdev_priv(ndev)),
3278                4);
3279         return vif;
3280 }