tizen 2.4 release
[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         n = min(request->n_ssids, 9);
829         if (n) {
830                 data = kzalloc(512, GFP_KERNEL);
831                 if (!data) {
832                         printkd("%s failed to alloc for combo ssid\n",
833                                 __func__);
834                         return -2;
835                 }
836                 scan_ssids = (struct wlan_cmd_scan_ssid *)data;
837                 for (i = 0; i < n; i++) {
838                         if (!ssids[i].ssid_len)
839                                 continue;
840                         scan_ssids->len = ssids[i].ssid_len;
841                         memcpy(scan_ssids->ssid, ssids[i].ssid,
842                                ssids[i].ssid_len);
843                         scan_ssids_len += (ssids[i].ssid_len
844                                            + sizeof(scan_ssids->len));
845                         scan_ssids = (struct wlan_cmd_scan_ssid *)
846                             (data + scan_ssids_len);
847                 }
848         }
849
850         n = min(request->n_channels, 14);
851         if (n > 15)
852                 n = 15;
853         for (i = 0, j = 0; i < n; i++) {
854                 int ch = request->channels[i]->hw_value;
855                 if (ch == 0) {
856                         printkd("Scan requested for unknown frequency %dMhz\n",
857                                 request->channels[i]->center_freq);
858                         continue;
859                 }
860                 channels[j + 1] = ch;
861                 j++;
862         }
863         channels[0] = j;
864
865         /* Arm scan timeout timer */
866         mod_timer(&vif->cfg80211.scan_timeout,
867                   jiffies + ITM_SCAN_TIMER_INTERVAL_MS * HZ / 1000);
868         vif->cfg80211.scan_request = request;
869
870         ret = wlan_cmd_scan(vif_id, data, channels, scan_ssids_len);
871         if (ret) {
872                 printkd("wlan_cmd_scan failed with ret %d\n", ret);
873                 kfree(data);
874                 return ret;
875         }
876
877 #ifdef CONFIG_HAS_WAKELOCK
878         if (vif->cfg80211.scan_done_lock.link.next == LIST_POISON1 ||
879             vif->cfg80211.scan_done_lock.link.prev == LIST_POISON2)
880                 wake_lock(&vif->cfg80211.scan_done_lock);
881 #endif
882         kfree(data);
883         printkd("%s(), ok!\n", __func__);
884         return 0;
885 }
886
887 static int wlan_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
888                                  struct cfg80211_connect_params *sme)
889 {
890         wlan_vif_t *vif;
891         unsigned char vif_id;
892         struct wireless_dev *wdev;
893         int ret;
894         unsigned int cipher = 0;
895         unsigned char key_mgmt = 0;
896         int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40)
897             || (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104);
898         bool is_wapi = false;
899         int auth_type = 0;
900         unsigned char *buf = NULL;
901         size_t wps_len = 0;
902         unsigned short p2p_len = 0;
903         size_t ftie_len = 0;
904         vif = ndev_to_vif(ndev);
905         vif_id = vif->id;
906         wdev = &(vif->wdev);
907         if (ITM_NONE_MODE == vif->mode)
908                 return -EAGAIN;
909         printkd("[%s][%d] enter\n", __func__, vif_id);
910         printkd("%s(), Begin connect: %s\n", __func__, sme->ssid);
911
912         /* To avoid confused wapi frame */
913         vif->cfg80211.cipher_type = NONE;
914         /* Get request status, type, bss, ie and so on */
915         /* Set appending ie */
916         /* Set wps ie */
917         if (sme->ie_len > 0) {
918                 if (sme->ie_len > 255) {
919                         printkd("%s invalid sme->len(%d)\n", __func__,
920                                 sme->ie_len);
921                         return -EOPNOTSUPP;
922                 }
923                 buf = kmalloc(sme->ie_len, GFP_KERNEL);
924                 if (NULL == buf) {
925                         printkd("%s(), end\n", __func__);
926                         return -ENOMEM;
927                 }
928                 if (itm_find_wpsie(sme->ie, sme->ie_len, buf, &wps_len) == true) {
929                         ret =
930                             wlan_cmd_set_wps_ie(vif_id, WPS_ASSOC_IE, buf,
931                                                 wps_len);
932                         if (ret) {
933                                 printkd
934                                     ("wlan_cmd_set_wps_ie failed with ret %d\n",
935                                      ret);
936                                 return ret;
937                         }
938                 }
939         }
940 #ifdef WIFI_DIRECT_SUPPORT
941         if (itm_find_p2p_ie(sme->ie, sme->ie_len, buf, &p2p_len) == true) {
942                 ret = wlan_cmd_set_p2p_ie(vif_id, P2P_ASSOC_IE, buf, p2p_len);
943                 if (ret) {
944                         printkd("wlan_cmd_set_p2p_ie failed with ret %d\n",
945                                 ret);
946                         return ret;
947                 }
948         }
949 #endif /*WIFI_DIRECT_SUPPORT */
950 #ifdef WLAN_11R_SUPPORT
951         if (itm_find_ft_ie(sme->ie, sme->ie_len, buf, &ftie_len)) {
952                 ret = wlan_cmd_set_ft_ie(vif_id, buf, ftie_len);
953                 if (ret) {
954                         printkd("wlan_cmd_set_ft_ie failed with ret %d\n", ret);
955                 }
956         }
957 #endif
958         /* Set WPA version */
959         printkd("Set wpa_versions %#x\n", sme->crypto.wpa_versions);
960         ret = wlan_cmd_set_wpa_version(vif_id, sme->crypto.wpa_versions);
961         if (ret < 0) {
962                 printkd("wlan_cmd_set_wpa_version failed with ret %d\n", ret);
963                 printkd("%s(), end\n", __func__);
964                 return ret;
965         }
966
967         /* Set Auth type */
968         printkd("Set auth_type %#x\n", sme->auth_type);
969         /* Set the authorisation */
970         if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
971             ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
972                 auth_type = ITM_AUTH_OPEN;
973         else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
974                  ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
975                 auth_type = ITM_AUTH_SHARED;
976         ret = wlan_cmd_set_auth_type(vif_id, auth_type);
977         if (ret < 0) {
978                 printkd("wlan_cmd_set_auth_type failed with ret %d\n", ret);
979                 return ret;
980         }
981         /* Set cipher - pairewise and group */
982         printkd("n_ciphers_pairwise %d\n", sme->crypto.n_ciphers_pairwise);
983         if (sme->crypto.n_ciphers_pairwise) {
984                 switch (sme->crypto.ciphers_pairwise[0]) {
985                 case WLAN_CIPHER_SUITE_WEP40:
986                         cipher = WEP40;
987                         break;
988                 case WLAN_CIPHER_SUITE_WEP104:
989                         cipher = WEP104;
990                         break;
991                 case WLAN_CIPHER_SUITE_TKIP:
992                         cipher = TKIP;
993                         break;
994                 case WLAN_CIPHER_SUITE_CCMP:
995                         cipher = CCMP;
996                         break;
997                         /* WAPI cipher is not processed by CP2 */
998                 case WLAN_CIPHER_SUITE_SMS4:
999                         cipher = WAPI;
1000                         is_wapi = true;
1001                         break;
1002                 default:
1003                         printkd("Unicast cipher suite 0x%x is not supported\n",
1004                                 sme->crypto.ciphers_pairwise[0]);
1005                         printkd("%s(), end\n", __func__);
1006                         kfree(buf);
1007                         return -ENOTSUPP;
1008                 }
1009
1010                 if (is_wapi != true) {
1011                         ret =
1012                             wlan_cmd_set_cipher(vif_id, cipher,
1013                                                 WIFI_CMD_SET_PAIRWISE_CIPHER);
1014                         if (ret < 0) {
1015                                 printkd
1016                                     ("set_cipher_cmd pairwise failed with ret %d\n",
1017                                      ret);
1018                                 printkd("%s(), end\n", __func__);
1019                                 return ret;
1020                         }
1021                 }
1022         } else {
1023                 /*No pairewise cipher */
1024                 printkd("No pairewise cipher\n");
1025         }
1026
1027         /* Set group cipher */
1028         switch (sme->crypto.cipher_group) {
1029         case NONE:
1030                 cipher = NONE;
1031                 break;
1032         case WLAN_CIPHER_SUITE_WEP40:
1033                 cipher = WEP40;
1034                 break;
1035         case WLAN_CIPHER_SUITE_WEP104:
1036                 cipher = WEP104;
1037                 break;
1038         case WLAN_CIPHER_SUITE_TKIP:
1039                 cipher = TKIP;
1040                 break;
1041         case WLAN_CIPHER_SUITE_CCMP:
1042                 cipher = CCMP;
1043                 break;
1044         default:
1045                 printkd("Group cipher suite 0x%x is not supported\n",
1046                         sme->crypto.cipher_group);
1047                 printkd("%s(), end\n", __func__);
1048                 kfree(buf);
1049                 return -ENOTSUPP;
1050         }
1051
1052         if (is_wapi != true) {
1053                 ret =
1054                     wlan_cmd_set_cipher(vif_id, cipher,
1055                                         WIFI_CMD_SET_GROUP_CIPHER);
1056                 if (ret < 0) {
1057                         printkd("set_cipher_cmd group failed with ret %d\n",
1058                                 ret);
1059                         printkd("%s(), end\n", __func__);
1060                         return ret;
1061                 }
1062         }
1063
1064         /* FIXME */
1065         /* Set Auth type again because of CP2 process's differece */
1066         printkd("Set auth_type %#x\n", sme->auth_type);
1067         /* Set the authorisation */
1068         if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
1069             ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
1070                 auth_type = ITM_AUTH_OPEN;
1071         else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
1072                  ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
1073                 auth_type = ITM_AUTH_SHARED;
1074         ret = wlan_cmd_set_auth_type(vif_id, auth_type);
1075         if (ret < 0) {
1076                 printkd("wlan_cmd_set_auth_type failed with ret %d\n", ret);
1077                 printkd("%s(), end\n", __func__);
1078                 return ret;
1079         }
1080
1081         /* Set auth key management (akm) */
1082         printkd("akm_suites %#x\n", sme->crypto.n_akm_suites);
1083         if (sme->crypto.n_akm_suites) {
1084                 if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_PSK)
1085                         key_mgmt = AKM_SUITE_PSK;
1086                 else if (WLAN_AKM_SUITE_FT_PSK == sme->crypto.akm_suites[0])
1087                         key_mgmt = AKM_SUITE_FT_PSK;
1088                 else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
1089                         key_mgmt = AKM_SUITE_8021X;
1090                 /* WAPI akm is not processed by CP2 */
1091                 else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_CERT)
1092                         key_mgmt = AKM_SUITE_WAPI_CERT;
1093                 else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_PSK)
1094                         key_mgmt = AKM_SUITE_WAPI_PSK;
1095                 else if (WLAN_AKM_SUITE_FT_8021X == sme->crypto.akm_suites[0])
1096                         key_mgmt = AKM_SUITE_FT_8021X;
1097                 else {
1098                 }
1099                 ret = wlan_cmd_set_key_management(vif_id, key_mgmt);
1100                 if (ret < 0) {
1101                         printkd("wlan_cmd_set_key_management failed %d\n", ret);
1102                         printkd("%s(), end\n", __func__);
1103                         return ret;
1104                 }
1105         }
1106
1107         /* Set PSK */
1108         if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40 ||
1109             sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104 ||
1110             sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP40 ||
1111             sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP104) {
1112                 printkd("Don't need to set PSK since driver is using WEP\n");
1113                 vif->cfg80211.key_index[GROUP] = sme->key_idx;
1114                 vif->cfg80211.key_len[GROUP][sme->key_idx] = sme->key_len;
1115                 memcpy(vif->cfg80211.key[GROUP][sme->key_idx], sme->key,
1116                        sme->key_len);
1117                 ret =
1118                     itm_wlan_add_cipher_key(vif, 0, sme->key_idx,
1119                                             sme->crypto.ciphers_pairwise[0],
1120                                             NULL, NULL);
1121                 if (ret < 0) {
1122                         printkd("itm_wlan_add_key failed %d\n", ret);
1123                         printkd("%s(), end\n", __func__);
1124                         kfree(buf);
1125                         return ret;
1126                 }
1127         } else {
1128                 unsigned char psk[32];
1129                 int key_len = 0;
1130                 if (wdev->iftype == NL80211_IFTYPE_AP) {
1131                         ret = hostap_conf_load(HOSTAP_CONF_FILE_NAME, psk);
1132                         if (ret) {
1133                                 printkd("load hostap failed with ret %d\n",
1134                                         ret);
1135                                 printkd("%s(), end\n", __func__);
1136                                 return ret;
1137                         }
1138                         key_len = sizeof(psk);
1139                 } else {
1140                         if (sme->key_len > 32) {
1141                                 printkd("Invalid key len (%d)\n", sme->key_len);
1142                                 printkd("%s(), end\n", __func__);
1143                                 kfree(buf);
1144                                 return -EINVAL;
1145                         }
1146                         memcpy(psk, sme->key, sme->key_len);
1147                         key_len = sme->key_len;
1148                 }
1149                 ret = wlan_cmd_set_psk(vif_id, psk, key_len);
1150                 if (ret < 0) {
1151                         printkd("set_psk_cmd failed with ret %d\n", ret);
1152                         printkd("%s(), end\n", __func__);
1153                         return ret;
1154                 }
1155         }
1156
1157         /* Auth RX unencrypted EAPOL is not implemented, do nothing */
1158         /* Set channel */
1159         if (sme->channel != NULL) {
1160                 printkd("Settting channel to %d\n",
1161                         ieee80211_frequency_to_channel(sme->
1162                                                        channel->center_freq));
1163                 ret =
1164                     wlan_cmd_set_channel(vif_id,
1165                                          ieee80211_frequency_to_channel
1166                                          (sme->channel->center_freq));
1167                 if (ret < 0) {
1168                         printkd("wlan_cmd_set_channel failed with ret %d\n",
1169                                 ret);
1170                         printkd("%s(), end\n", __func__);
1171                         return ret;
1172                 }
1173         } else {
1174                 printkd("Channel is not specified\n");
1175         }
1176
1177         /* Set BSSID */
1178         if (sme->bssid != NULL) {
1179                 ret = wlan_cmd_set_bssid(vif_id, sme->bssid);
1180                 if (ret < 0) {
1181                         printkd("wlan_cmd_set_bssid failed with ret %d\n", ret);
1182                         printkd("%s(), end\n", __func__);
1183                         return ret;
1184                 }
1185                 memcpy(vif->cfg80211.bssid, sme->bssid, 6);
1186         } else {
1187                 printkd("BSSID is not specified\n");
1188         }
1189
1190         /* Special process for WEP(WEP key must be set before itm_set_essid) */
1191         if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40 ||
1192             sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
1193                 printkd("Setting WEP group cipher\n");
1194                 if (sme->key_len <= 0) {
1195                         printkd("No key is specified\n");
1196                 } else {
1197                         if (sme->key_len != WLAN_KEY_LEN_WEP104 &&
1198                             sme->key_len != WLAN_KEY_LEN_WEP40) {
1199                                 printkd("Invalid key length for WEP\n");
1200                                 printkd("%s(), end\n", __func__);
1201                                 return -EINVAL;
1202                         }
1203
1204                         wlan_cmd_set_key(vif_id, sme->key_idx);
1205                 }
1206         }
1207         /* Set ESSID */
1208         if (sme->ssid != NULL) {
1209                 printkd("sme->ssid:%s\n", sme->ssid);
1210                 ret = wlan_cmd_set_essid(vif_id, sme->ssid, (int)sme->ssid_len);
1211                 if (ret < 0) {
1212                         printkd("wlan_cmd_set_essid failed with ret %d\n", ret);
1213                         printkd("%s(), end\n", __func__);
1214                         kfree(buf);
1215                         return ret;
1216                 }
1217                 memcpy(vif->cfg80211.ssid, sme->ssid, sme->ssid_len);
1218                 vif->cfg80211.ssid_len = sme->ssid_len;
1219         }
1220         vif->cfg80211.connect_status = ITM_CONNECTING;
1221         kfree(buf);
1222         printkd("%s(), ok\n", __func__);
1223         return ret;
1224 }
1225
1226 static int wlan_cfg80211_disconnect(struct wiphy *wiphy,
1227                                     struct net_device *ndev,
1228                                     unsigned short reason_code)
1229 {
1230         wlan_vif_t *vif;
1231         unsigned char vif_id;
1232         struct cfg80211_bss *bss = NULL;
1233         bool found = false;
1234         int ret;
1235         vif = ndev_to_vif(ndev);
1236         vif_id = vif->id;
1237         if (ITM_NONE_MODE == vif->mode)
1238                 return -EAGAIN;
1239         printkd("[%s][%d] enter\n", __func__, vif_id);
1240         printkd("Begin disconnect: %s\n", vif->cfg80211.ssid);
1241
1242         ret = wlan_cmd_disconnect(vif_id, reason_code);
1243         if (ret < 0) {
1244                 printkd("swifi_disconnect_cmd failed with ret %d\n", ret);
1245         }
1246         memset(vif->cfg80211.ssid, 0, sizeof(vif->cfg80211.ssid));
1247         return ret;
1248 }
1249
1250 static int wlan_cfg80211_add_key(struct wiphy *wiphy,
1251                                  struct net_device *netdev, u8 idx,
1252                                  bool pairwise, const u8 *mac_addr,
1253                                  struct key_params *params)
1254 {
1255         wlan_vif_t *vif;
1256         unsigned char vif_id;
1257         int ret;
1258         unsigned char key[32];
1259         vif = ndev_to_vif(netdev);
1260         vif_id = vif->id;
1261         if (ITM_NONE_MODE == vif->mode)
1262                 return -EAGAIN;
1263         printkd("[%s][%d] enter\n", __func__, vif_id);
1264
1265         vif->cfg80211.key_index[pairwise] = idx;
1266         vif->cfg80211.key_len[pairwise][idx] = params->key_len;
1267         memcpy(vif->cfg80211.key[pairwise][idx], params->key, params->key_len);
1268         ret =
1269             itm_wlan_add_cipher_key(vif, pairwise, idx, params->cipher,
1270                                     params->seq, mac_addr);
1271         if (ret < 0) {
1272                 printkd("%s failed to add cipher key!\n", __func__);
1273                 return ret;
1274         }
1275
1276         return 0;
1277 }
1278
1279 static int wlan_cfg80211_del_key(struct wiphy *wiphy,
1280                                  struct net_device *ndev,
1281                                  unsigned char key_index, bool pairwise,
1282                                  const unsigned char *mac_addr)
1283 {
1284         wlan_vif_t *vif;
1285         unsigned char vif_id;
1286
1287         vif = ndev_to_vif(ndev);
1288         vif_id = vif->id;
1289         if (ITM_NONE_MODE == vif->mode)
1290                 return -EAGAIN;
1291         printkd("[%s][%d] enter\n", __func__, vif_id);
1292         if (key_index > WLAN_MAX_KEY_INDEX) {
1293                 printkd("key index %d out of bounds\n", key_index);
1294                 return -ENOENT;
1295         }
1296         if (!vif->cfg80211.key_len[pairwise][key_index]) {
1297                 printkd("index %d is empty\n", key_index);
1298                 return 0;
1299         }
1300         vif->cfg80211.key_len[pairwise][key_index] = 0;
1301         vif->cfg80211.cipher_type = NONE;
1302
1303         return wlan_cmd_del_key(vif_id, key_index, mac_addr);
1304 }
1305
1306 static int wlan_cfg80211_set_default_key(struct wiphy *wiphy,
1307                                          struct net_device *ndev,
1308                                          unsigned char key_index, bool unicast,
1309                                          bool multicast)
1310 {
1311         int ret;
1312         wlan_vif_t *vif;
1313         unsigned char vif_id;
1314         vif = ndev_to_vif(ndev);
1315         vif_id = vif->id;
1316         if (ITM_NONE_MODE == vif->mode)
1317                 return -EAGAIN;
1318         printkd("[%s][%d] enter\n", __func__, vif_id);
1319         if (key_index < 0 || key_index > 3) {
1320                 printkd("Invalid key index %d\n", key_index);
1321                 return -EINVAL;
1322         }
1323         ret = wlan_cmd_set_key(vif_id, key_index);
1324         if (ret < 0) {
1325                 printkd("wlan_cmd_set_key failed\n");
1326                 return ret;
1327         }
1328
1329         return 0;
1330 }
1331
1332 static int wlan_cfg80211_set_wiphy_params(struct wiphy *wiphy,
1333                                           unsigned int changed)
1334 {
1335         int ret;
1336         wlan_vif_t *vif;
1337         unsigned char vif_id;
1338         vif_id = NETIF_0_ID;
1339         vif = id_to_vif(vif_id);
1340         if (ITM_NONE_MODE == vif->mode)
1341                 return -EAGAIN;
1342         printkd("[%s][%d] enter\n", __func__, vif_id);
1343         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1344                 ret = wlan_cmd_set_rts(vif_id, wiphy->rts_threshold);
1345                 if (ret != 0) {
1346                         printkd("wlan_cmd_set_rts failed\n");
1347                         return -EIO;
1348                 }
1349         }
1350
1351         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1352                 ret = wlan_cmd_set_frag(vif_id, wiphy->frag_threshold);
1353                 if (ret != 0) {
1354                         printkd("wlan_cmd_set_frag failed\n");
1355                         return -EIO;
1356                 }
1357         }
1358         return 0;
1359 }
1360
1361 static int wlan_cfg80211_get_station(struct wiphy *wiphy,
1362                                      struct net_device *dev, unsigned char *mac,
1363                                      struct station_info *sinfo)
1364 {
1365         unsigned char signal, noise;
1366         int rate, ret, i, failed;
1367         wlan_vif_t *vif;
1368         unsigned char vif_id;
1369         static int cfg80211_get_station_time;
1370         static char cfg80211_get_station_signal;
1371         static int cfg80211_get_station_txrate;
1372         static int cfg80211_get_station_txfailed;
1373
1374         vif = ndev_to_vif(dev);
1375         vif_id = vif->id;
1376         if (ITM_NONE_MODE == vif->mode)
1377                 return -EAGAIN;
1378         if (NULL == sinfo) {
1379                 printke("[%s][sinfo null]\n", __func__);
1380                 return -EAGAIN;
1381         }
1382
1383         sinfo->filled |=
1384             STATION_INFO_TX_BYTES | STATION_INFO_TX_PACKETS |
1385             STATION_INFO_RX_BYTES | STATION_INFO_RX_PACKETS;
1386         sinfo->tx_bytes = vif->ndev->stats.tx_bytes;
1387         sinfo->tx_packets = vif->ndev->stats.tx_packets;
1388         sinfo->rx_bytes = vif->ndev->stats.rx_bytes;
1389         sinfo->rx_packets = vif->ndev->stats.rx_packets;
1390
1391         if (0 != cfg80211_get_station_time) {
1392                 sinfo->signal = cfg80211_get_station_signal;
1393                 sinfo->filled |= STATION_INFO_SIGNAL;
1394                 sinfo->txrate.legacy = cfg80211_get_station_txrate;
1395                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1396                 sinfo->tx_failed = cfg80211_get_station_txfailed;
1397                 sinfo->filled |= STATION_INFO_TX_FAILED;
1398                 if (2 == cfg80211_get_station_time) {
1399                         cfg80211_get_station_time = 0;
1400                 } else {
1401                         cfg80211_get_station_time++;
1402                 }
1403                 return 0;
1404         }
1405
1406         ret = wlan_cmd_get_rssi(vif_id, &signal, &noise);
1407         if (OK == ret) {
1408                 sinfo->signal = signal;
1409                 sinfo->filled |= STATION_INFO_SIGNAL;
1410         } else {
1411                 printkd("wlan_cmd_get_rssi error!\n");
1412                 return -EIO;
1413         }
1414
1415         ret = wlan_cmd_get_txrate_txfailed(vif_id, &rate, &failed);
1416         if (OK == ret) {
1417                 sinfo->tx_failed = failed;
1418                 sinfo->filled |=
1419                     STATION_INFO_TX_BITRATE | STATION_INFO_TX_FAILED;
1420         } else {
1421                 printkd("wlan_cmd_get_txrate_txfailed error!\n");
1422                 return -EIO;
1423         }
1424
1425         if (!(rate & 0x7f)) {
1426                 sinfo->txrate.legacy = 10;
1427         } else {
1428                 for (i = 0; i < ARRAY_SIZE(itm_rates); i++) {
1429                         if (rate == itm_rates[i].hw_value) {
1430                                 sinfo->txrate.legacy = itm_rates[i].bitrate;
1431                                 if (rate & 0x80)
1432                                         sinfo->txrate.mcs =
1433                                             itm_rates[i].hw_value;
1434                                 break;
1435                         }
1436                 }
1437                 if (i >= ARRAY_SIZE(itm_rates))
1438                         sinfo->txrate.legacy = 10;
1439         }
1440         cfg80211_get_station_signal = sinfo->signal;
1441         cfg80211_get_station_txrate = sinfo->txrate.legacy;
1442         cfg80211_get_station_txfailed = sinfo->tx_failed;
1443         cfg80211_get_station_time++;
1444
1445         return 0;
1446 }
1447
1448 static int wlan_cfg80211_set_pmksa(struct wiphy *wiphy,
1449                                    struct net_device *netdev,
1450                                    struct cfg80211_pmksa *pmksa)
1451 {
1452         int ret;
1453         wlan_vif_t *vif;
1454         unsigned char vif_id;
1455         vif = ndev_to_vif(netdev);
1456         vif_id = vif->id;
1457         if (ITM_NONE_MODE == vif->mode)
1458                 return -EAGAIN;
1459         printkd("[%s][%d] enter\n", __func__, vif_id);
1460         ret =
1461             wlan_cmd_pmksa(vif_id, pmksa->bssid, pmksa->pmkid,
1462                            WIFI_CMD_SET_PMKSA);
1463         return ret;
1464 }
1465
1466 static int wlan_cfg80211_del_pmksa(struct wiphy *wiphy,
1467                                    struct net_device *netdev,
1468                                    struct cfg80211_pmksa *pmksa)
1469 {
1470         int ret;
1471         wlan_vif_t *vif;
1472         unsigned char vif_id;
1473         vif = ndev_to_vif(netdev);
1474         vif_id = vif->id;
1475         if (ITM_NONE_MODE == vif->mode)
1476                 return -EAGAIN;
1477         printkd("[%s][%d] enter\n", __func__, vif_id);
1478         ret =
1479             wlan_cmd_pmksa(vif_id, pmksa->bssid, pmksa->pmkid,
1480                            WIFI_CMD_DEL_PMKSA);
1481         return ret;
1482 }
1483
1484 static int wlan_cfg80211_flush_pmksa(struct wiphy *wiphy,
1485                                      struct net_device *netdev)
1486 {
1487         int ret;
1488         wlan_vif_t *vif;
1489         unsigned char vif_id;
1490         vif = ndev_to_vif(netdev);
1491         vif_id = vif->id;
1492         if (ITM_NONE_MODE == vif->mode)
1493                 return -EAGAIN;
1494         printkd("[%s][%d] enter\n", __func__, vif_id);
1495         ret =
1496             wlan_cmd_pmksa(vif_id, vif->cfg80211.bssid, NULL,
1497                            WIFI_CMD_FLUSH_PMKSA);
1498         return ret;
1499 }
1500
1501 void cfg80211_report_connect_result(unsigned char vif_id, unsigned char *pData,
1502                                     int len)
1503 {
1504         unsigned char *req_ie_ptr, *resp_ie_ptr, *bssid_ptr, *pos, *value_ptr;
1505         unsigned char status_code = 0;
1506         unsigned short bssid_len;
1507         unsigned char req_ie_len;
1508         unsigned short resp_ie_len;
1509         unsigned int event_len;
1510         int left;
1511         unsigned char reassociate_rsp_flag = 0;
1512
1513         wlan_vif_t *vif = id_to_vif(vif_id);
1514         printkd("%s(), enter\n", __func__);
1515         event_len = len;
1516         /* status_len 2 + status_code 1 = 3 bytes */
1517         if (event_len < 3) {
1518                 printkd("filled event len(%d) is not a valid len\n", event_len);
1519                 goto out;
1520         }
1521         pos = kmalloc(event_len, GFP_KERNEL);
1522         if (pos == NULL) {
1523                 printkd("[%s][%d][%d]\n", __func__, __LINE__, event_len);
1524                 if (event_len > 16384)
1525                         BUG_ON(1);
1526                 goto out;
1527         }
1528         /* The first byte of event data is status and len */
1529         memcpy(pos, pData, event_len);
1530         /* msg byte format
1531          * byte [0] the length for status_code,here is 1
1532          * byte [1] reassociate_rsp_flag
1533          * byte [2] status_code
1534          * ..... other data
1535          */
1536         if (1 != *pos) {
1537                 ASSERT("msg first byte err:%d != 1", (int)*pos);
1538                 kfree(pos);
1539                 goto out;
1540         }
1541         reassociate_rsp_flag = *(pos + 1);
1542         status_code = *(pos + 2);
1543
1544         /* FIXME later the status code should be reported by CP2 */
1545         if (status_code != 0) {
1546                 printkd("%s, Connect is failled (%d)\n", __func__, status_code);
1547                 kfree(pos);
1548                 goto out;
1549         }
1550
1551         value_ptr = pos + 3;
1552         left = event_len - 3;
1553         /* BSSID is 6 + len is 2 = 8 */
1554         if (left < 8) {
1555                 printkd("%s(), Do not have a vaild bssid\n", __func__);
1556                 kfree(pos);
1557                 goto out;
1558         }
1559         memcpy(&bssid_len, value_ptr, 2);
1560         left -= 2;
1561         bssid_ptr = value_ptr + 2;
1562         left -= bssid_len;
1563
1564         if (!left) {
1565                 printkd("%s(), There is no req_ie frame!\n", __func__);
1566                 kfree(pos);
1567                 goto out;
1568         }
1569         req_ie_len = *(unsigned char *)(bssid_ptr + bssid_len);
1570         left -= 1;
1571         req_ie_ptr = bssid_ptr + bssid_len + 1;
1572         left -= req_ie_len;
1573         if (!left) {
1574                 printkd("%s(), There is no resp_ie frame!\n", __func__);
1575                 kfree(pos);
1576                 goto out;
1577         }
1578         resp_ie_len =
1579             *(unsigned char *)(req_ie_ptr + req_ie_len) +
1580             *(unsigned char *)(req_ie_ptr + req_ie_len + 1);
1581         resp_ie_ptr = req_ie_ptr + req_ie_len + 2;
1582
1583         if ((vif->cfg80211.connect_status == ITM_CONNECTING)
1584             || (1 == reassociate_rsp_flag)) {
1585                 /* inform connect result to cfg80211 */
1586                 vif->cfg80211.connect_status = ITM_CONNECTED;
1587                 if (1 == reassociate_rsp_flag) {
1588                         vif->wdev.sme_state = CFG80211_SME_CONNECTING;
1589                 }
1590                 cfg80211_connect_result(vif->ndev, bssid_ptr, req_ie_ptr,
1591                                         req_ie_len, resp_ie_ptr, resp_ie_len,
1592                                         WLAN_STATUS_SUCCESS, GFP_KERNEL);
1593                 if (!netif_carrier_ok(vif->ndev)) {
1594                         printkd("%s(), netif_carrier_on, ssid:%s\n", __func__,
1595                                 vif->cfg80211.ssid);
1596                         netif_carrier_on(vif->ndev);
1597                         netif_wake_queue(vif->ndev);
1598                 }
1599         }
1600         kfree(pos);
1601         printkd("%s(), ok\n", __func__);
1602         return;
1603 out:
1604         if (vif->cfg80211.scan_request
1605             && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1)) {
1606                 del_timer_sync(&vif->cfg80211.scan_timeout);
1607                 cfg80211_scan_done(vif->cfg80211.scan_request, true);
1608                 vif->cfg80211.scan_request = NULL;
1609 #ifdef CONFIG_HAS_WAKELOCK
1610                 if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 &&
1611                     vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1612                         wake_unlock(&vif->cfg80211.scan_done_lock);
1613 #endif
1614                 atomic_dec(&vif->cfg80211.scan_status);
1615         }
1616         if (vif->cfg80211.connect_status == ITM_CONNECTING) {
1617                 cfg80211_connect_result(vif->ndev, vif->cfg80211.bssid, NULL, 0,
1618                                         NULL, 0,
1619                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
1620                                         GFP_KERNEL);
1621         } else if (vif->cfg80211.connect_status == ITM_CONNECTED) {
1622                 cfg80211_disconnected(vif->ndev, status_code, NULL, 0,
1623                                       GFP_KERNEL);
1624         }
1625
1626         printkd("%s(), err\n", __func__);
1627         return;
1628 }
1629
1630 void cfg80211_unlink_ssid(unsigned char vif_id, unsigned char *bssid, unsigned char *ssid, int ssid_len)
1631 {
1632                 int i;
1633                 struct cfg80211_bss *bss = NULL;
1634                 struct wiphy *wiphy = NULL;
1635                 wlan_vif_t *vif;
1636                 buf_scan_frame_t *scan_buf;
1637
1638                 vif = id_to_vif(vif_id);
1639                 wiphy = vif->wdev.wiphy;
1640                 bss = cfg80211_get_bss(wiphy, NULL,bssid,ssid,ssid_len,WLAN_CAPABILITY_ESS,WLAN_CAPABILITY_ESS);
1641                 if(bss)
1642                 {
1643                         cfg80211_unlink_bss(wiphy, bss);
1644                         vif->beacon_loss = 0;
1645                         printkd("[%s][unlink][%s]\n",__func__, ssid);
1646                 }
1647                 for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++)
1648                 {
1649                         scan_buf = (buf_scan_frame_t *) (vif->
1650                                                   cfg80211.scan_frame_array +
1651                                                   i * sizeof(buf_scan_frame_t));
1652                         if (0xff != scan_buf->live)
1653                                 continue;
1654                         if (0 != memcmp(bssid, scan_buf->bssid, 6))
1655                                 continue;
1656                         if(ssid_len != strlen(scan_buf->ssid) )
1657                                 continue;
1658                         if( 0 != strncmp(ssid, scan_buf->ssid, ssid_len) )
1659                                 continue;
1660                         memset((char *)(scan_buf), 0, sizeof(buf_scan_frame_t) );
1661                         printkd("[%s][clear][%s]\n",__func__, ssid);
1662                         break;
1663                 }
1664                 return;
1665 }
1666
1667 void cfg80211_report_disconnect_done(unsigned char vif_id, unsigned char *pData,
1668                                      int len)
1669 {
1670         struct cfg80211_bss *bss = NULL;
1671         unsigned short reason_code = 0;
1672         bool found = false;
1673         wlan_vif_t *vif = id_to_vif(vif_id);
1674         printkd("%s()\n", __func__);
1675
1676         cfg80211_unlink_ssid(vif_id, vif->cfg80211.bssid, vif->cfg80211.ssid, vif->cfg80211.ssid_len );
1677
1678         /* This should filled if disconnect reason is not only one */
1679         memcpy(&reason_code, pData, 2);
1680         if (vif->cfg80211.scan_request
1681             && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1)) {
1682                 del_timer_sync(&vif->cfg80211.scan_timeout);
1683                 cfg80211_scan_done(vif->cfg80211.scan_request, true);
1684                 vif->cfg80211.scan_request = NULL;
1685 #ifdef CONFIG_HAS_WAKELOCK
1686                 if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1
1687                     && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1688                         wake_unlock(&vif->cfg80211.scan_done_lock);
1689 #endif
1690                 atomic_dec(&vif->cfg80211.scan_status);
1691         }
1692         if (vif->cfg80211.connect_status == ITM_CONNECTING) {
1693                 cfg80211_connect_result(vif->ndev,
1694                                         vif->cfg80211.bssid, NULL, 0,
1695                                         NULL, 0,
1696                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
1697                                         GFP_KERNEL);
1698         } else if (vif->cfg80211.connect_status == ITM_CONNECTED) {
1699                 if (reason_code == AP_LEAVING   /*||
1700                                                    reason_code == AP_DEAUTH */) {
1701                         do {
1702                                 bss = cfg80211_get_bss(vif->wdev.wiphy, NULL,
1703                                                        vif->cfg80211.bssid,
1704                                                        vif->cfg80211.ssid,
1705                                                        vif->cfg80211.ssid_len,
1706                                                        WLAN_CAPABILITY_ESS,
1707                                                        WLAN_CAPABILITY_ESS);
1708                                 if (bss) {
1709                                         cfg80211_unlink_bss(vif->wdev.wiphy,
1710                                                             bss);
1711                                         found = true;
1712                                 } else {
1713                                         found = false;
1714                                 }
1715                         } while (found);
1716                 }
1717                 cfg80211_disconnected(vif->ndev, reason_code,
1718                                       NULL, 0, GFP_KERNEL);
1719         }
1720
1721         vif->cfg80211.connect_status = ITM_DISCONNECTED;
1722         if (netif_carrier_ok(vif->ndev)) {
1723                 printkd("netif_carrier_off\n");
1724                 netif_carrier_off(vif->ndev);
1725                 netif_stop_queue(vif->ndev);
1726         }
1727         return;
1728 }
1729
1730 static void wlan_scan_timeout(unsigned long data)
1731 {
1732         wlan_vif_t *vif = (wlan_vif_t *) data;
1733
1734         printkd("%s()\n", __func__);
1735         if (vif->cfg80211.scan_request
1736             && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1)) {
1737                 printkd("scan timer expired!\n");
1738                 cfg80211_scan_done(vif->cfg80211.scan_request, true);
1739                 vif->cfg80211.scan_request = NULL;
1740 #ifdef CONFIG_HAS_WAKELOCK
1741                 if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1
1742                     && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1743                         wake_unlock(&vif->cfg80211.scan_done_lock);
1744 #endif
1745                 atomic_dec(&vif->cfg80211.scan_status);
1746                 printkd("%s()  end\n", __func__);
1747
1748                 return;
1749         }
1750
1751         printkd("%s()  end, wrong scan timer expired!\n", __func__);
1752         return;
1753 }
1754
1755 void cfg80211_report_scan_done(unsigned char vif_id, unsigned char *pData,
1756                                int len, bool aborted)
1757 {
1758         struct ieee80211_mgmt *mgmt;
1759         struct ieee80211_channel *channel;
1760         struct ieee80211_supported_band *band;
1761         struct wiphy *wiphy;
1762         struct cfg80211_bss *itm_bss = NULL;
1763         unsigned char ssid[33] = { 0 };
1764         unsigned char bssid[6] = { 0 };
1765         unsigned int mgmt_len = 0;
1766         unsigned short channel_num, channel_len;
1767         unsigned short rssi_len;
1768         short rssi;
1769         int signal;
1770         int freq;
1771         unsigned int left = len;
1772         wlan_vif_t *vif = id_to_vif(vif_id);
1773         const unsigned char *pos = pData;
1774
1775         wiphy = vif->wdev.wiphy;
1776         printkd("%s()\n", __func__);
1777         if (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 0) {
1778                 printkd("scan event is aborted\n");
1779                 return;
1780         }
1781
1782         if (!vif->cfg80211.scan_request) {
1783                 printkd("vif->cfg80211.scan_request is null\n");
1784                 atomic_dec(&vif->cfg80211.scan_status);
1785                 return;
1786         }
1787
1788         if (left < 10 || aborted) {
1789                 printkd("filled event len(%d) is not a valid len\n", len);
1790                 goto out;
1791         }
1792
1793         mgmt = kmalloc(left, GFP_KERNEL);
1794         if (mgmt == NULL) {
1795                 printkd("[%s][%d]\n", __func__, left);
1796                 goto out;
1797         }
1798         while (left >= 10) {
1799                 /* must use memcpy to protect unaligned */
1800                 /* The formate of frame is len(two bytes) + data */
1801                 memcpy(&channel_len, pos, 2);
1802                 pos += 2;
1803                 left -= 2;
1804                 if (channel_len > 2) {
1805                         ASSERT("channel_len %u > 2\n", channel_len);
1806                         kfree(mgmt);
1807                         goto out;
1808                 }
1809                 memcpy(&channel_num, pos, channel_len);
1810                 pos += channel_len;
1811                 left -= channel_len;
1812                 /* The second two value of frame is rssi */
1813                 memcpy(&rssi_len, pos, 2);
1814                 pos += 2;
1815                 left -= 2;
1816                 memcpy(&rssi, pos, rssi_len);
1817                 pos += rssi_len;
1818                 left -= rssi_len;
1819                 /* The third two value of frame is following data len */
1820                 memcpy(&mgmt_len, pos, 2);
1821                 pos += 2;
1822                 left -= 2;
1823
1824                 if (mgmt_len > left) {
1825                         printkd("mgmt_len(0x%08x) > left(0x%08x)!\n", mgmt_len,
1826                                 left);
1827                         kfree(mgmt);
1828                         goto out;
1829                 }
1830
1831                 /* The following is real data */
1832                 memcpy(mgmt, pos, mgmt_len);
1833                 left -= mgmt_len;
1834                 pos += mgmt_len;
1835
1836                 /* FIXME Now only support 2GHZ */
1837                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
1838                 freq = ieee80211_channel_to_frequency(channel_num, band->band);
1839                 channel = ieee80211_get_channel(wiphy, freq);
1840                 if (!channel) {
1841                         printkd("freq is %d\n", freq);
1842                         continue;
1843                 }
1844                 signal = rssi;
1845                 /*printkd("[report][%s][%d][%d]\n",ssid, channel_num, signal); */
1846                 itm_bss =
1847                     cfg80211_inform_bss_frame(wiphy, channel, mgmt,
1848                                               le16_to_cpu(mgmt_len), signal,
1849                                               GFP_KERNEL);
1850
1851                 if (unlikely(!itm_bss))
1852                         printkd("cfg80211_inform_bss_frame error\n");
1853 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
1854                 cfg80211_put_bss(wiphy, itm_bss);
1855 #else
1856                 cfg80211_put_bss(itm_bss);
1857 #endif
1858         }
1859
1860         if (left) {
1861                 kfree(mgmt);
1862                 goto out;
1863         }
1864
1865         kfree(mgmt);
1866         del_timer_sync(&vif->cfg80211.scan_timeout);
1867         cfg80211_scan_done(vif->cfg80211.scan_request, aborted);
1868         vif->cfg80211.scan_request = NULL;
1869 #ifdef CONFIG_HAS_WAKELOCK
1870         if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1
1871             && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1872                 wake_unlock(&vif->cfg80211.scan_done_lock);
1873 #endif
1874         atomic_dec(&vif->cfg80211.scan_status);
1875
1876         printkd("%s(), ok!\n", __func__);
1877         return;
1878
1879 out:
1880         del_timer_sync(&vif->cfg80211.scan_timeout);
1881         cfg80211_scan_done(vif->cfg80211.scan_request, true);
1882         vif->cfg80211.scan_request = NULL;
1883 #ifdef CONFIG_HAS_WAKELOCK
1884         if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 &&
1885             vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
1886                 wake_unlock(&vif->cfg80211.scan_done_lock);
1887 #endif
1888         atomic_dec(&vif->cfg80211.scan_status);
1889
1890         printkd("%s(), err\n", __func__);
1891         return;
1892 }
1893
1894 void cfg80211_report_scan_frame(unsigned char vif_id, unsigned char *pData,
1895                                 int len)
1896 {
1897         struct cfg80211_bss *bss = NULL;
1898         int i, report_null;
1899         wlan_vif_t *vif;
1900         buf_scan_frame_t *scan_buf;
1901         wlan_event_scan_rsp_t *event;
1902         unsigned char *msa;
1903         unsigned char ssid[33] = { 0 };
1904         unsigned char bssid[6] = { 0 };
1905
1906         struct ieee80211_channel *channel = NULL;
1907         struct ieee80211_supported_band *band = NULL;
1908         struct wiphy *wiphy = NULL;
1909         struct cfg80211_bss *itm_bss = NULL;
1910         struct ieee80211_mgmt *mgmt = NULL;
1911         u8 *ie;
1912         size_t ielen;
1913         u16 capability, beacon_interval;
1914         int freq, signal;
1915         u64 tsf;
1916
1917         vif = id_to_vif(vif_id);
1918         wiphy = vif->wdev.wiphy;
1919         event = (wlan_event_scan_rsp_t *) (pData);
1920         if (((event->frame_len + sizeof(wlan_event_scan_rsp_t)) > len)
1921             || (event->ops > 2)) {
1922                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
1923                 return;
1924         }
1925         if (0 == event->ops) {
1926                 if (event->frame_len < 37) {
1927                         printkd("[%s %d][line %d err]\n", __func__, vif_id,
1928                                 __LINE__);
1929                         return;
1930                 }
1931                 msa = (unsigned char *)(event + 1);
1932                 get_ssid(msa, ssid);
1933                 get_bssid(msa, bssid);
1934                 /*if (0 == strlen(ssid)) {
1935                    printkd("[%s %d][line %d err]\n", __func__, vif_id,
1936                    __LINE__);
1937                    return;
1938                    } */
1939                 if (1024 < event->frame_len) {
1940                         printkd("[%s %d][line %d err]\n", __func__, vif_id,
1941                                 __LINE__);
1942                         return;
1943                 }
1944                 for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++) {
1945                         scan_buf =
1946                             (buf_scan_frame_t *) (vif->
1947                                                   cfg80211.scan_frame_array +
1948                                                   i * sizeof(buf_scan_frame_t));
1949                         if (0xff != scan_buf->live)
1950                                 continue;
1951                         if (0 != memcmp(bssid, scan_buf->bssid, 6))
1952                                 continue;
1953                         strcpy(scan_buf->ssid, ssid);
1954                         memcpy(scan_buf->msa, msa, event->frame_len);
1955                         scan_buf->msa_len = event->frame_len;
1956                         scan_buf->channel = event->channel;
1957                         scan_buf->signal = event->signal;
1958                         scan_buf->live = 0xff;
1959                         scan_buf->keep = 1;
1960                         return;
1961                 }
1962                 for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++) {
1963                         scan_buf =
1964                             (buf_scan_frame_t *) (vif->
1965                                                   cfg80211.scan_frame_array +
1966                                                   i * sizeof(buf_scan_frame_t));
1967                         if (0xff == scan_buf->live)
1968                                 continue;
1969                         memcpy(scan_buf->bssid, bssid, 6);
1970                         strcpy(scan_buf->ssid, ssid);
1971                         memcpy(scan_buf->msa, msa, event->frame_len);
1972                         scan_buf->msa_len = event->frame_len;
1973                         scan_buf->channel = event->channel;
1974                         scan_buf->signal = event->signal;
1975                         scan_buf->keep = 1;
1976                         scan_buf->live = 0xff;
1977                         printkd("[netif:%d find_ssid][%s][%d][%d]\n", vif_id,
1978                                 scan_buf->ssid, scan_buf->channel,
1979                                 scan_buf->signal);
1980                         return;
1981                 }
1982                 return;
1983         }
1984         if (1 != event->ops) {
1985                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
1986                 return;
1987         }
1988         if (!vif->cfg80211.scan_request) {
1989                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
1990                 atomic_dec(&vif->cfg80211.scan_status);
1991                 return;
1992         }
1993         if (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 0) {
1994                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
1995                 return;
1996         }
1997         if (!vif->cfg80211.scan_request) {
1998                 printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
1999                 atomic_dec(&vif->cfg80211.scan_status);
2000                 return;
2001         }
2002         report_null = -1;
2003         band = wiphy->bands[IEEE80211_BAND_2GHZ];
2004         for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++) {
2005                 scan_buf =
2006                     (buf_scan_frame_t *) (vif->cfg80211.scan_frame_array +
2007                                           i * sizeof(buf_scan_frame_t));
2008                 if (0xff != scan_buf->live)
2009                         continue;
2010                 if (0 == scan_buf->keep) {
2011                         printkd("[netif:%d leave_ssid][%s][%d][%d]\n", vif_id,
2012                                 scan_buf->ssid, event->channel, event->signal);
2013                         memset((char *)scan_buf, 0, sizeof(buf_scan_frame_t));
2014                         continue;
2015                 }
2016                 scan_buf->keep--;
2017                 freq =
2018                     ieee80211_channel_to_frequency(scan_buf->channel,
2019                                                    band->band);
2020                 channel = ieee80211_get_channel(wiphy, freq);
2021                 if (!channel) {
2022                         printkd("[%s %d][line %d err]\n", __func__, vif_id,
2023                                 __LINE__);
2024                         continue;
2025                 }
2026                 mgmt = (struct ieee80211_mgmt *)(&scan_buf->msa[0]);
2027                 tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
2028                 capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
2029                 beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
2030                 ie = mgmt->u.probe_resp.variable;
2031                 ielen =
2032                     le16_to_cpu(scan_buf->msa_len) -
2033                     offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
2034                 signal = scan_buf->signal;
2035                 signal = signal * 100;
2036                 wiphy_info(wiphy, "   %s, " MACSTR ", channel %2u, signal %d\n",
2037                            ieee80211_is_probe_resp(mgmt->frame_control)
2038                            ? "proberesp" : "beacon   ",
2039                            MAC2STR(mgmt->bssid), scan_buf->channel,
2040                            scan_buf->signal);
2041                 itm_bss =
2042                     cfg80211_inform_bss(wiphy, channel, mgmt->bssid, tsf,
2043                                         capability, beacon_interval, ie, ielen,
2044                                         signal, GFP_KERNEL);
2045                 if (unlikely(!itm_bss))
2046                         printkd("[%s %d][line %d err]\n", __func__, vif_id,
2047                                 __LINE__);
2048 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2049                 cfg80211_put_bss(wiphy, itm_bss);
2050 #else
2051                 cfg80211_put_bss(itm_bss);
2052 #endif
2053                 report_null = 0;
2054         }
2055
2056         if (vif->beacon_loss) {
2057                 bss = cfg80211_get_bss(wiphy, NULL,
2058                                        vif->cfg80211.bssid,
2059                                        vif->cfg80211.ssid,
2060                                        vif->cfg80211.ssid_len,
2061                                        WLAN_CAPABILITY_ESS,
2062                                        WLAN_CAPABILITY_ESS);
2063                 if (bss) {
2064                         cfg80211_unlink_bss(wiphy, bss);
2065                         wiphy_info(wiphy, "find beacon loss event " MACSTR "",
2066                                    MAC2STR(bss->bssid));
2067                         vif->beacon_loss = 0;
2068                 }
2069         }
2070
2071         if (-1 == report_null) {
2072                 printkd("[%s %d][report-ssid][NULL]\n", __func__, vif_id);
2073         }
2074         del_timer_sync(&vif->cfg80211.scan_timeout);
2075         cfg80211_scan_done(vif->cfg80211.scan_request, false);
2076         vif->cfg80211.scan_request = NULL;
2077 #ifdef CONFIG_HAS_WAKELOCK
2078         if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1
2079             && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
2080                 wake_unlock(&vif->cfg80211.scan_done_lock);
2081 #endif
2082         atomic_dec(&vif->cfg80211.scan_status);
2083         /*memset(vif->cfg80211.scan_frame_array, 0, */
2084         /*MAX_SCAN_FRAME_BUF_NUM * sizeof(buf_scan_frame_t)); */
2085         printkd("[%s %d] ok!\n", __func__, vif_id);
2086         return;
2087 }
2088
2089 void cfg80211_report_mic_failure(unsigned char vif_id,
2090                                  unsigned char *pdata, int len)
2091 {
2092         struct wlan_event_mic_failure *mic_failure;
2093         wlan_vif_t *vif;
2094
2095         mic_failure = (struct wlan_event_mic_failure *)pdata;
2096         vif = id_to_vif(vif_id);
2097         if (vif) {
2098                 /* debug info,Pls remove it in the future */
2099                 printkd
2100                     ("[%s %d] is_mcast:0x%x key_id: 0x%x bssid: %x %x %x %x %x %x\n",
2101                      __func__, vif_id, mic_failure->is_mcast,
2102                      mic_failure->key_id, vif->cfg80211.bssid[0],
2103                      vif->cfg80211.bssid[1], vif->cfg80211.bssid[2],
2104                      vif->cfg80211.bssid[3], vif->cfg80211.bssid[4],
2105                      vif->cfg80211.bssid[5]);
2106                 cfg80211_michael_mic_failure(vif->ndev, vif->cfg80211.bssid,
2107                                              (mic_failure->is_mcast ?
2108                                               NL80211_KEYTYPE_GROUP :
2109                                               NL80211_KEYTYPE_PAIRWISE),
2110                                              mic_failure->key_id, NULL,
2111                                              GFP_KERNEL);
2112         }
2113 }
2114
2115 void cfg80211_report_cqm_low(unsigned char vif_id,
2116                              unsigned char *pdata, int len)
2117 {
2118         wlan_vif_t *vif = id_to_vif(vif_id);
2119
2120         if (vif) {
2121                 struct wiphy *wiphy = vif->wdev.wiphy;
2122                 wiphy_info(wiphy, "Recv NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW");
2123                 if (sprdwl_find_ssid_count(vif) >= 2) {
2124                         cfg80211_cqm_rssi_notify(vif->ndev,
2125                                                  NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
2126                                                  GFP_KERNEL);
2127                 }
2128         }
2129 }
2130
2131 void cfg80211_report_cqm_high(unsigned char vif_id,
2132                               unsigned char *pdata, int len)
2133 {
2134         wlan_vif_t *vif = id_to_vif(vif_id);
2135
2136         if (vif) {
2137                 struct wiphy *wiphy = vif->wdev.wiphy;
2138                 wiphy_info(wiphy,
2139                            "Recv  NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH");
2140                 if (sprdwl_find_ssid_count(vif) >= 2) {
2141                         cfg80211_cqm_rssi_notify(vif->ndev,
2142                                                  NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
2143                                                  GFP_KERNEL);
2144                 }
2145         }
2146 }
2147
2148 void cfg80211_report_cqm_beacon_loss(unsigned char vif_id,
2149                                      unsigned char *pdata, int len)
2150 {
2151         wlan_vif_t *vif = id_to_vif(vif_id);
2152         cfg80211_unlink_ssid(vif_id, vif->cfg80211.bssid, vif->cfg80211.ssid, vif->cfg80211.ssid_len );
2153         if (vif) {
2154                 struct wiphy *wiphy = vif->wdev.wiphy;
2155                 wiphy_info(wiphy, "Recv NL80211_CQM_RSSI_BEACON_LOSS_EVENT");
2156                 vif->beacon_loss = 1;
2157                 /*
2158                    TODO wpa_supplicant not support the event ,
2159                    so we workaround this issue
2160                  */
2161                 cfg80211_cqm_rssi_notify(vif->ndev,
2162                                          NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
2163                                          GFP_KERNEL);
2164         }
2165 }
2166
2167 void cfg80211_report_version(unsigned char vif_id,
2168                              unsigned char *pdata, int len)
2169 {
2170         unsigned char wifi_info[100] = { 0 };
2171         struct file *fp = 0;
2172         loff_t *pos;
2173         printkd
2174             ("[wifi driver version is 0x%04x] [cp version is 0x%04x date is 0x%04x]\n",
2175              g_wlan.version, *((int *)(pdata + 4)), *((int *)pdata));
2176
2177         fp = filp_open(WIFI_VERSION_FILE, O_CREAT | O_RDWR, 0666);
2178         if (IS_ERR(fp)) {
2179                 printke("%s %d err\n", __func__, __LINE__);
2180                 goto EXIT;
2181         }
2182         pos = &(fp->f_pos);
2183         sprintf(wifi_info,
2184                 "[wifi driver version is 0x%04x] [cp version is 0x%2x date is 0x%04x]",
2185                 g_wlan.version, *((int *)(pdata + 4)), *((int *)pdata));
2186         vfs_write(fp, wifi_info, strlen(wifi_info), pos);
2187
2188 EXIT:
2189         if (!(IS_ERR(fp)))
2190                 filp_close(fp, NULL);
2191         return OK;
2192 }
2193
2194 void cfg80211_report_mlme_tx_status(unsigned char vif_id,
2195                                     unsigned char *pdata, int len)
2196 {
2197         struct wlan_report_mgmt_tx_status *tx_status = NULL;
2198         wlan_vif_t *vif;
2199
2200         vif = id_to_vif(vif_id);
2201         tx_status = (struct wlan_report_mgmt_tx_status *)pdata;
2202         printkd("[%s]: index: %lld\n", __func__, tx_status->cookie);
2203         printkd("data len is %d\n", len);
2204         hex_dump("receive is:", strlen("receive is:"), pdata, len);
2205         cfg80211_mgmt_tx_status(&vif->wdev, tx_status->cookie, tx_status->buf,
2206                                 tx_status->len, tx_status->ack, GFP_KERNEL);
2207         printkd("cfg80211_mgmt_tx_status end\n");
2208 }
2209
2210 static int wlan_cfg80211_mgmt_tx(struct wiphy *wiphy,
2211 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2212                                  struct wireless_dev *wdev,
2213 #else
2214                                  struct net_device *ndev,
2215 #endif
2216 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || \
2217         defined(COMPAT_KERNEL_RELEASE))
2218                                  struct ieee80211_channel *chan, bool offchan,
2219 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
2220                                  enum nl80211_channel_type channel_type,
2221                                  bool channel_type_valid,
2222 #endif
2223                                  unsigned int wait,
2224 #else                           /*(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) */
2225                                  struct ieee80211_channel *chan,
2226                                  enum nl80211_channel_type channel_type,
2227 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || \
2228         defined(COMPAT_KERNEL_RELEASE)
2229                                  bool channel_type_valid,
2230 #endif
2231 #endif                          /*(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) */
2232                                  const u8 *buf, size_t len,
2233 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
2234                                  bool no_cck,
2235 #endif
2236 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
2237                                  bool dont_wait_for_ack,
2238 #endif
2239                                  u64 *cookie)
2240 {
2241         int ret = -1;
2242         wlan_vif_t *vif;
2243         unsigned char vif_id;
2244         static u64 mgmt_index = 0;
2245
2246         mgmt_index++;
2247         vif = ndev_to_vif(wdev->netdev);
2248         vif_id = vif->id;
2249         if (ITM_NONE_MODE == vif->mode) {
2250                 printke("%s err\n", __func__);
2251                 return -EAGAIN;
2252         }
2253
2254         printkd("[%s][%d]enter\n", __func__, vif_id);
2255         printkd("[%s], index: %lld, cookie: %lld\n", __func__, mgmt_index,
2256                 *cookie);
2257         *cookie = mgmt_index;
2258         if (len > 0) {
2259                 ret =
2260                     wlan_cmd_set_tx_mgmt(vif_id, chan, dont_wait_for_ack, wait,
2261                                          cookie, buf, len);
2262                 if (ret) {
2263                         if (dont_wait_for_ack == false)
2264                                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len,
2265                                                         0, GFP_KERNEL);
2266                         printkd("[%s] Failed to set tx mgmt!\n", __func__);
2267                         return ret;
2268                 }
2269         }
2270         return ret;
2271 }
2272
2273 static void wlan_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
2274 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2275                                               struct wireless_dev *wdev,
2276 #else
2277                                               struct net_device *ndev,
2278 #endif
2279                                               u16 frame_type, bool reg)
2280 {
2281         wlan_vif_t *vif;
2282         unsigned char vif_id;
2283         vif = ndev_to_vif(wdev->netdev);
2284         vif_id = vif->id;
2285         if (ITM_NONE_MODE == vif->mode)
2286                 return;
2287         if (NETIF_0_ID == vif_id)
2288                 return;
2289         printkd("[%s][%d]\n", __func__, vif_id);
2290         register_frame(vif, frame_type, reg);
2291         return;
2292 }
2293
2294 static int wlan_change_beacon(wlan_vif_t *vif,
2295                               struct cfg80211_beacon_data *beacon)
2296 {
2297         u16 ie_len;
2298         u8 *ie_ptr;
2299         int ret = 0;
2300         unsigned char vif_id = vif->id;
2301
2302         printkd("%s enter\n", __func__);
2303 #ifdef WIFI_DIRECT_SUPPORT
2304         /* send beacon extra ies */
2305         if (beacon->head != NULL) {
2306                 ie_len = beacon->head_len;
2307                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2308                 if (ie_ptr == NULL) {
2309                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2310                         return -EINVAL;
2311                 }
2312                 memcpy(ie_ptr, beacon->head, ie_len);
2313                 printkd("begin send beacon head ies\n");
2314
2315                 ret =
2316                     wlan_cmd_set_p2p_ie(vif_id, P2P_BEACON_IE_HEAD, ie_ptr,
2317                                         ie_len);
2318                 if (ret) {
2319                         printkd
2320                             ("itm_wlan_set_p2p_ie beacon_ies head failed with ret %d\n",
2321                              ret);
2322                 } else {
2323                         printkd("send beacon head ies successfully\n");
2324                 }
2325
2326                 kfree(ie_ptr);
2327         }
2328
2329         /* send beacon extra ies */
2330         if (beacon->tail != NULL) {
2331                 ie_len = beacon->tail_len;
2332
2333                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2334                 if (ie_ptr == NULL) {
2335                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2336                         return -EINVAL;
2337                 }
2338                 memcpy(ie_ptr, beacon->tail, ie_len);
2339                 printkd("begin send beacon tail ies\n");
2340
2341                 ret = wlan_cmd_set_p2p_ie(vif_id,
2342                                           P2P_BEACON_IE_TAIL, ie_ptr, ie_len);
2343                 if (ret) {
2344                         printkd
2345                             ("wlan_cmd_set_p2p_ie beacon_ies tail failed with ret %d\n",
2346                              ret);
2347                 } else {
2348                         printkd("send beacon tail ies successfully\n");
2349                 }
2350
2351                 kfree(ie_ptr);
2352         }
2353
2354         /* send probe response ies */
2355
2356         /* send beacon extra ies */
2357         if (beacon->beacon_ies != NULL) {
2358                 ie_len = beacon->beacon_ies_len;
2359
2360                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2361                 if (ie_ptr == NULL) {
2362                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2363                         return -EINVAL;
2364                 }
2365                 memcpy(ie_ptr, beacon->beacon_ies, ie_len);
2366                 printkd("begin send beacon extra ies\n");
2367
2368                 ret =
2369                     wlan_cmd_set_p2p_ie(vif_id, P2P_BEACON_IE, ie_ptr, ie_len);
2370                 if (ret) {
2371                         printkd
2372                             ("wlan_cmd_set_p2p_ie beacon_ies failed with ret %d\n",
2373                              ret);
2374                 } else {
2375                         printkd("send beacon extra ies successfully\n");
2376                 }
2377
2378                 kfree(ie_ptr);
2379         }
2380
2381         /* send probe response ies */
2382
2383         if (beacon->proberesp_ies != NULL) {
2384                 printkd("%s line:%d\n", __func__, __LINE__);
2385                 ie_len = beacon->proberesp_ies_len;
2386
2387                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2388                 if (ie_ptr == NULL) {
2389                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2390                         return -EINVAL;
2391                 }
2392                 memcpy(ie_ptr, beacon->proberesp_ies, ie_len);
2393                 printkd("begin send probe response extra ies\n");
2394
2395                 ret =
2396                     wlan_cmd_set_p2p_ie(vif_id, P2P_PROBERESP_IE, ie_ptr,
2397                                         ie_len);
2398                 if (ret) {
2399                         printkd
2400                             ("wlan_cmd_set_p2p_ie proberesp_ies failed with ret %d\n",
2401                              ret);
2402                 } else {
2403                         printkd("send probe response ies successfully\n");
2404                 }
2405
2406                 kfree(ie_ptr);
2407         }
2408
2409         /* send associate response ies */
2410
2411         if (beacon->assocresp_ies != NULL) {
2412                 printkd("%s line:%d\n", __func__, __LINE__);
2413                 ie_len = beacon->assocresp_ies_len;
2414
2415                 ie_ptr = kmalloc(ie_len, GFP_KERNEL);
2416                 if (ie_ptr == NULL) {
2417                         printkd("[%s][%d][%d]\n", __func__, __LINE__, ie_ptr);
2418                         return -EINVAL;
2419                 }
2420                 memcpy(ie_ptr, beacon->assocresp_ies, ie_len);
2421                 printkd("begin send associate response extra ies\n");
2422
2423                 ret =
2424                     wlan_cmd_set_p2p_ie(vif_id, P2P_ASSOCRESP_IE, ie_ptr,
2425                                         ie_len);
2426                 if (ret) {
2427                         printkd
2428                             ("wlan_cmd_set_p2p_ie assocresp_ies failed with ret %d\n",
2429                              ret);
2430                 } else {
2431                         printkd("send associate response ies successfully\n");
2432                 }
2433
2434                 kfree(ie_ptr);
2435         }
2436 #endif /*WIFI_DIRECT_SUPPORT */
2437         return ret;
2438 }
2439
2440 static int itm_wlan_start_ap(wlan_vif_t *vif,
2441                              struct cfg80211_beacon_data *beacon)
2442 {
2443 #define SSID_LEN_OFFSET                (37)
2444         struct ieee80211_mgmt *mgmt;
2445         u16 mgmt_len, index = 0;
2446         int ret;
2447         unsigned char vif_id = vif->id;
2448         u8 *data = NULL;
2449         struct wlan_cmd_hidden_ssid *hssid = &(vif->hssid);
2450         printkd("%s enter\n", __func__);
2451         wlan_change_beacon(vif, beacon);
2452         if (beacon->head == NULL) {
2453                 printke("%s line:%d err\n", __func__, __LINE__);
2454                 return -EINVAL;
2455         }
2456         mgmt_len = beacon->head_len;
2457
2458         /*add 1 byte for hidden ssid flag */
2459         mgmt_len += 1;
2460
2461         if (beacon->tail)
2462                 mgmt_len += beacon->tail_len;
2463
2464         mgmt = kmalloc(mgmt_len, GFP_KERNEL);
2465         if (mgmt == NULL) {
2466                 printkd("[%s][%d][%d]\n", __func__, __LINE__, mgmt);
2467                 return -EINVAL;
2468         }
2469         data = (u8 *) mgmt;
2470
2471         memcpy(data, beacon->head, SSID_LEN_OFFSET);
2472         index += SSID_LEN_OFFSET;
2473
2474         /*hostapd config ssid by ioctl */
2475         if (hssid->ssid_len == (unsigned char)*(beacon->head + index)) {
2476                 /*modify ssid_len */
2477                 *(data + index) = (unsigned char)(hssid->ssid_len + 1);
2478                 index += 1;
2479                 /*copy ssid */
2480                 memcpy(data + index, hssid->ssid, hssid->ssid_len);
2481                 index += hssid->ssid_len;
2482                 /*set hidden ssid flag */
2483                 *(data + index) = (unsigned char)(hssid->ignore_broadcast_ssid);
2484                 index += 1;
2485         } else {                /*hostapd not config ssid */
2486                 unsigned char org_len = (unsigned char)*(beacon->head + index);
2487                 /*modify ssid_len */
2488                 *(data + index) = org_len + 1;
2489                 index += 1;
2490                 /*copy ssid */
2491                 memcpy(data + index, beacon->head + index, org_len);
2492                 index += org_len;
2493                 /*set no hidden ssid flag */
2494                 *(data + index) = 0;
2495                 index += 1;
2496         }
2497         /*cope left info */
2498         memcpy(data + index, beacon->head + index - 1,
2499                beacon->head_len + 1 - index);
2500
2501         if (beacon->tail)
2502                 memcpy(data + beacon->head_len + 1,
2503                        beacon->tail, beacon->tail_len);
2504
2505         ret = wlan_cmd_start_ap(vif_id, (unsigned char *)mgmt, mgmt_len);
2506         kfree(mgmt);
2507         if (!netif_carrier_ok(vif->ndev)) {
2508                 printkd("%s(), netif_carrier_on, ssid:%s\n", __func__,
2509                         vif->cfg80211.ssid);
2510                 netif_carrier_on(vif->ndev);
2511                 netif_wake_queue(vif->ndev);
2512         }
2513         if (ret != 0) {
2514                 printke("%s line:%d err\n", __func__, __LINE__);
2515         }
2516         return ret;
2517 }
2518
2519 static int wlan_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
2520                                   struct cfg80211_ap_settings *info)
2521 {
2522         wlan_vif_t *vif;
2523         unsigned char vif_id;
2524         vif = ndev_to_vif(ndev);
2525         vif_id = vif->id;
2526         if (ITM_NONE_MODE == vif->mode)
2527                 return -EAGAIN;
2528         printkd("[%s][%d] enter\n", __func__, vif_id);
2529         if (info->ssid == NULL) {
2530                 printkd("%s line:%d\n", __func__, __LINE__);
2531                 return -EINVAL;
2532         }
2533         printkd("[cfg80211] \t ==>>>%s\n", __func__);
2534         memcpy(vif->cfg80211.ssid, info->ssid, info->ssid_len);
2535         vif->cfg80211.ssid_len = info->ssid_len;
2536         return itm_wlan_start_ap(vif, &info->beacon);
2537 }
2538
2539 static int wlan_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
2540 {
2541         int ret = 0;
2542         wlan_vif_t *vif;
2543         unsigned char vif_id;
2544         vif = ndev_to_vif(ndev);
2545         vif_id = vif->id;
2546         if (ITM_NONE_MODE == vif->mode)
2547                 return -EAGAIN;
2548         printkd("[%s][%d] enter\n", __func__, vif_id);
2549         ret = wlan_cmd_mac_close(vif_id, vif->mode);
2550         return ret;
2551 }
2552
2553 static int wlan_cfg80211_change_beacon(struct wiphy *wiphy,
2554                                        struct net_device *ndev,
2555                                        struct cfg80211_beacon_data *beacon)
2556 {
2557         wlan_vif_t *vif;
2558         unsigned char vif_id;
2559         vif = ndev_to_vif(ndev);
2560         vif_id = vif->id;
2561         if (ITM_NONE_MODE == vif->mode)
2562                 return -EAGAIN;
2563         printkd("[%s][%d] enter\n", __func__, vif_id);
2564 #ifdef WIFI_DIRECT_SUPPORT
2565         return wlan_change_beacon(vif, beacon);
2566 #else
2567         return itm_wlan_start_ap(vif, beacon);
2568 #endif
2569
2570 }
2571
2572 static int itm_wlan_change_mode(wlan_vif_t *vif, enum nl80211_iftype type)
2573 {
2574         int mode = 0;
2575         int ret;
2576         unsigned char vif_id = vif->id;
2577         switch (type) {
2578         case NL80211_IFTYPE_STATION:
2579                 if (NETIF_0_ID == vif->id)
2580                         mode = ITM_STATION_MODE;
2581                 else
2582                         mode = ITM_P2P_CLIENT_MODE;
2583                 break;
2584         case NL80211_IFTYPE_AP:
2585                 if (NETIF_0_ID == vif->id)
2586                         mode = ITM_AP_MODE;
2587                 else
2588                         mode = ITM_P2P_GO_MODE;
2589                 break;
2590         case NL80211_IFTYPE_P2P_CLIENT:
2591                 mode = ITM_P2P_CLIENT_MODE;
2592                 break;
2593         case NL80211_IFTYPE_P2P_GO:
2594                 mode = ITM_P2P_GO_MODE;
2595                 break;
2596         default:
2597                 printkd("invalid interface type %u\n", type);
2598                 return -EOPNOTSUPP;
2599         }
2600         vif->wdev.iftype = type;
2601         if (mode == vif->mode) {
2602                 printkd("not need change mode\n");
2603                 return 0;
2604         }
2605         vif->wdev.iftype = type;
2606         vif->mode = mode;
2607         printkd("[%s][%d][%d]\n", __func__, vif_id, mode);
2608         ret = wlan_cmd_mac_open(vif_id, mode, vif->ndev->dev_addr);
2609         if (OK != ret)
2610                 return -EIO;
2611         vif->wdev.iftype = type;
2612         vif->mode = mode;
2613 #ifdef CONFIG_MACH_SAMSUNG
2614         wlan_cmd_set_psm_cap();
2615 #endif
2616         return OK;
2617 }
2618
2619 static int wlan_cfg80211_change_iface(struct wiphy *wiphy,
2620                                       struct net_device *ndev,
2621                                       enum nl80211_iftype type,
2622                                       unsigned int *flags,
2623                                       struct vif_params *params)
2624 {
2625         wlan_vif_t *vif;
2626         unsigned char vif_id;
2627         vif = ndev_to_vif(ndev);
2628         vif_id = vif->id;
2629 #ifdef WIFI_DIRECT_SUPPORT
2630         if (NETIF_1_ID == vif_id) {
2631                 vif->cfg80211.p2p_mode = itm_get_p2p_mode_from_file();
2632                 printkd("[%s][%d][%d]\n", __func__, vif_id,
2633                         (vif->cfg80211.p2p_mode ? 1 : 0));
2634         }
2635 #endif /* WIFI_DIRECT_SUPPORT */
2636         return itm_wlan_change_mode(vif, type);
2637 }
2638
2639 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2640 static int wlan_cfg80211_set_channel(struct wiphy *wiphy,
2641                                      struct net_device *ndev,
2642                                      struct ieee80211_channel *channel)
2643 #else
2644 static int wlan_cfg80211_set_channel(struct wiphy *wiphy,
2645                                      struct net_device *ndev,
2646                                      struct ieee80211_channel *channel,
2647                                      enum nl80211_channel_type channel_type)
2648 #endif
2649 {
2650         int ret = -ENOTSUPP;
2651         wlan_vif_t *vif;
2652         unsigned char vif_id;
2653         vif = ndev_to_vif(ndev);
2654         vif_id = vif->id;
2655         if (ITM_NONE_MODE == vif->mode)
2656                 return -EAGAIN;
2657         printkd("[%s][%d] enter\n", __func__, vif_id);
2658         /*
2659          * FIXME: To be handled properly when monitor mode is supported.
2660          */
2661         ret =
2662             wlan_cmd_set_channel(vif_id,
2663                                  ieee80211_frequency_to_channel
2664                                  (channel->center_freq));
2665         if (ret < 0) {
2666                 printkd("wlan_cmd_set_channel failed with ret %d\n", ret);
2667                 return ret;
2668         }
2669
2670         return 0;
2671 }
2672
2673 int wlan_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *ndev,
2674                                 struct cfg80211_update_ft_ies_params *ftie)
2675 {
2676         wlan_vif_t *vif;
2677         unsigned char vif_id;
2678         vif = ndev_to_vif(ndev);
2679         vif_id = vif->id;
2680         printkd("%s enter\n", __func__);
2681         return wlan_cmd_update_ft_ies(vif_id, ftie);
2682 }
2683
2684 static void wlan_cfg80211_reg_notify(struct wiphy *wiphy,
2685                                      struct regulatory_request *request)
2686 {
2687         struct ieee80211_supported_band *sband;
2688         struct ieee80211_channel *chan;
2689         const struct ieee80211_freq_range *freq_range;
2690         const struct ieee80211_reg_rule *reg_rule;
2691         wlan_ieee80211_regdomain *rd = NULL;
2692         u32 band, channel, i;
2693         u32 last_start_freq;
2694         u32 n_rules = 0, rd_size;
2695         static int num;
2696
2697         wiphy_info(wiphy, "%s %c%c initiator %d hint_type %d\n", __func__,
2698                    request->alpha2[0], request->alpha2[1], request->initiator,
2699                    request->user_reg_hint_type);
2700
2701         if ((num != 1) && (num != 2)) {
2702                 num++;
2703                 return;
2704         }
2705
2706         /* Figure out the actual rule number */
2707         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2708                 sband = wiphy->bands[band];
2709                 if (!sband)
2710                         continue;
2711
2712                 last_start_freq = 0;
2713                 for (channel = 0; channel < sband->n_channels; channel++) {
2714                         chan = &sband->channels[channel];
2715
2716                         reg_rule =
2717                             freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
2718                         if (IS_ERR(reg_rule))
2719                                 continue;
2720
2721                         freq_range = &reg_rule->freq_range;
2722                         if (last_start_freq != freq_range->start_freq_khz) {
2723                                 last_start_freq = freq_range->start_freq_khz;
2724                                 n_rules++;
2725                         }
2726                 }
2727         }
2728         rd_size = sizeof(wlan_ieee80211_regdomain) +
2729             n_rules * sizeof(struct ieee80211_reg_rule);
2730
2731         rd = kzalloc(rd_size, GFP_KERNEL);
2732         if (!rd) {
2733                 wiphy_err(wiphy,
2734                           "Failed to allocate itm_ieee80211_regdomain\n");
2735                 return;
2736         }
2737
2738         /* Fill regulatory domain */
2739         rd->n_reg_rules = n_rules;
2740         memcpy(rd->alpha2, request->alpha2, ARRAY_SIZE(rd->alpha2));
2741         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2742                 sband = wiphy->bands[band];
2743                 if (!sband)
2744                         continue;
2745
2746                 last_start_freq = 0;
2747                 for (channel = i = 0; channel < sband->n_channels; channel++) {
2748                         chan = &sband->channels[channel];
2749
2750                         if (chan->flags & IEEE80211_CHAN_DISABLED)
2751                                 continue;
2752
2753                         reg_rule =
2754                             freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
2755                         if (IS_ERR(reg_rule))
2756                                 continue;
2757
2758                         freq_range = &reg_rule->freq_range;
2759                         if (last_start_freq != freq_range->start_freq_khz
2760                             && i < n_rules) {
2761                                 last_start_freq = freq_range->start_freq_khz;
2762                                 memcpy(&rd->reg_rules[i], reg_rule,
2763                                        sizeof(struct ieee80211_reg_rule));
2764                                 i++;
2765                                 wiphy_dbg(wiphy,
2766                                           "%s %d KHz - %d KHz @ %d KHz flags %#x\n",
2767                                           __func__, freq_range->start_freq_khz,
2768                                           freq_range->end_freq_khz,
2769                                           freq_range->max_bandwidth_khz,
2770                                           reg_rule->flags);
2771                         }
2772                 }
2773         }
2774         if (wlan_cmd_set_regdom(0, (u8 *) rd, rd_size))
2775                 wiphy_err(wiphy, "%s failed to set regdomain!\n", __func__);
2776         kfree(rd);
2777         num++;
2778 }
2779
2780 int lte_concur_proc_open(struct inode *inode, struct file *filp)
2781 {
2782         return 0;
2783 }
2784
2785 int lte_concur_proc_release(struct inode *inode, struct file *filp)
2786 {
2787         return 0;
2788 }
2789
2790 ssize_t lte_concur_proc_ioctl(struct file *filp, unsigned int cmd,
2791                               unsigned long arg)
2792 {
2793         int ret = 0;
2794         lte_concur_data_t *val;
2795         unsigned char buff[100];
2796         int len;
2797         switch (cmd) {
2798         case LTE_CONCUR_REQ:
2799                 if (copy_from_user
2800                     (buff, (unsigned char *)arg,
2801                      ((lte_concur_data_t *) arg)->size +
2802                      sizeof(lte_concur_data_t))) {
2803                         return -EFAULT;
2804                 }
2805
2806                 val = (lte_concur_data_t *) buff;
2807                 len = val->size;
2808                 ret =
2809                     wlan_cmd_req_lte_concur(0,
2810                                             (unsigned char *)val +
2811                                             sizeof(lte_concur_data_t), len);
2812                 if (ret < 0) {
2813                         printkd("wlan_cmd_req_lte_concur failed with ret %d\n",
2814                                 ret);
2815                         return ret;
2816                 }
2817                 break;
2818         default:
2819                 break;
2820         }
2821         return 0;
2822 }
2823
2824 /*
2825  * CFG802.11 operation handler for connection quality monitoring.
2826  *
2827  * This function subscribes/unsubscribes HIGH_RSSI and LOW_RSSI
2828  * events to FW.
2829  */
2830 int wlan_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
2831                                       struct net_device *ndev,
2832                                       s32 rssi_thold, u32 rssi_hyst)
2833 {
2834         int ret = -ENOTSUPP;
2835         wlan_vif_t *vif = ndev_to_vif(ndev);
2836         unsigned char vif_id = vif->id;
2837         if (ITM_NONE_MODE == vif->mode)
2838                 return -EAGAIN;
2839         wiphy_info(wiphy, "[%s][%d] rssi_thold %d rssi_hyst %d",
2840                    __func__, vif_id, rssi_thold, rssi_hyst);
2841         if (rssi_thold && rssi_hyst)
2842                 ret = wlan_cmd_cmq_rssi(vif_id, rssi_thold, rssi_hyst,
2843                                         WIFI_CMD_SET_CQM_RSSI);
2844         return ret;
2845 }
2846
2847 static struct cfg80211_ops wlan_cfg80211_ops = {
2848         .scan = wlan_cfg80211_scan,
2849         .connect = wlan_cfg80211_connect,
2850         .disconnect = wlan_cfg80211_disconnect,
2851         .add_key = wlan_cfg80211_add_key,
2852         .del_key = wlan_cfg80211_del_key,
2853         .set_default_key = wlan_cfg80211_set_default_key,
2854         .set_wiphy_params = wlan_cfg80211_set_wiphy_params,
2855         .get_station = wlan_cfg80211_get_station,
2856         .set_pmksa = wlan_cfg80211_set_pmksa,
2857         .del_pmksa = wlan_cfg80211_del_pmksa,
2858         .flush_pmksa = wlan_cfg80211_flush_pmksa,
2859         .start_ap = wlan_cfg80211_start_ap,
2860         .change_beacon = wlan_cfg80211_change_beacon,
2861         .stop_ap = wlan_cfg80211_stop_ap,
2862         .mgmt_tx = wlan_cfg80211_mgmt_tx,
2863         .mgmt_frame_register = wlan_cfg80211_mgmt_frame_register,
2864         .change_virtual_intf = wlan_cfg80211_change_iface,
2865         .update_ft_ies = wlan_cfg80211_update_ft_ies,
2866         .set_cqm_rssi_config = wlan_cfg80211_set_cqm_rssi_config,
2867 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2868         .libertas_set_mesh_channel = wlan_cfg80211_set_channel,
2869 #else
2870         .set_channel = wlan_cfg80211_set_channel,
2871 #endif
2872
2873 #ifdef WIFI_DIRECT_SUPPORT
2874         .remain_on_channel = wlan_cfg80211_remain_on_channel,
2875         .cancel_remain_on_channel = wlan_cfg80211_cancel_remain_on_channel,
2876         .del_station = wlan_cfg80211_del_station,
2877 #endif
2878 };
2879
2880 /*Init wiphy parameters*/
2881 static void init_wiphy_parameters(struct wiphy *wiphy)
2882 {
2883         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2884         wiphy->mgmt_stypes = itm_mgmt_stypes;
2885
2886         wiphy->max_scan_ssids = MAX_SITES_FOR_SCAN;
2887         wiphy->max_scan_ie_len = SCAN_IE_LEN_MAX;
2888         wiphy->max_num_pmkids = MAX_NUM_PMKIDS;
2889
2890         wiphy->interface_modes =
2891             BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_STATION) |
2892             BIT(NL80211_IFTYPE_AP);
2893
2894         wiphy->interface_modes |=
2895             BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) |
2896             BIT(NL80211_IFTYPE_P2P_DEVICE);
2897         wiphy->max_remain_on_channel_duration = 2000;
2898         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2899         /* set AP SME flag, also needed by STA mode? */
2900         wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
2901         wiphy->ap_sme_capa = 1;
2902
2903         wiphy->software_iftypes =
2904             BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_STATION) |
2905             BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) |
2906             BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_DEVICE);
2907         /*Attach cipher suites */
2908         wiphy->cipher_suites = itm_cipher_suites;
2909         wiphy->n_cipher_suites = ARRAY_SIZE(itm_cipher_suites);
2910         /*Attach bands */
2911         wiphy->bands[IEEE80211_BAND_2GHZ] = &itm_band_2ghz;
2912         /*wiphy->bands[IEEE80211_BAND_5GHZ] = &itm_band_5ghz; */
2913
2914         /*Default not in powersave state */
2915         wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2916         wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
2917 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2918         /*Set WoWLAN flags */
2919         wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT;
2920 #endif
2921         wiphy->reg_notifier = wlan_cfg80211_reg_notify;
2922 }
2923
2924 int wlan_wiphy_new(wlan_info_t *wlan)
2925 {
2926         int ret;
2927         printke("%s enter\n", __func__);
2928         wlan->wiphy = wiphy_new(&wlan_cfg80211_ops, 0);
2929         if (wlan->wiphy == NULL) {
2930                 ASSERT();
2931                 return ERROR;
2932         }
2933         *(struct wlan_info_t **)wiphy_priv(wlan->wiphy) = wlan;
2934         set_wiphy_dev(wlan->wiphy, wlan->dev);
2935         init_wiphy_parameters(wlan->wiphy);
2936         ret = wiphy_register(wlan->wiphy);
2937         if (ret < 0) {
2938                 printke("%s err:%d\n", __func__, ret);
2939                 ASSERT();
2940                 goto out_free_wiphy;
2941         }
2942         return OK;
2943 out_free_wiphy:
2944         wiphy_free(wlan->wiphy);
2945         return ERROR;
2946 }
2947
2948 int wlan_wiphy_free(wlan_info_t *wlan)
2949 {
2950         int i;
2951         wlan_vif_t *vif;
2952         if (NULL == wlan)
2953                 return ERROR;
2954         for (i = 0; i < 2; i++) {
2955                 vif = &(g_wlan.netif[i]);
2956                 if (vif->cfg80211.scan_request
2957                     && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) ==
2958                         1)) {
2959                         if (vif->cfg80211.scan_request->wiphy !=
2960                             vif->wdev.wiphy) {
2961                                 printkd
2962                                     ("Scan request is from a wrong wiphy device\n");
2963                         } else {
2964                                 /*If there's a pending scan request,abort it */
2965                                 cfg80211_scan_done(vif->cfg80211.scan_request,
2966                                                    1);
2967                         }
2968                         vif->cfg80211.scan_request = NULL;
2969 #ifdef CONFIG_HAS_WAKELOCK
2970                         if (vif->cfg80211.scan_done_lock.link.next !=
2971                             LIST_POISON1
2972                             && vif->cfg80211.scan_done_lock.link.prev !=
2973                             LIST_POISON2)
2974                                 wake_unlock(&vif->cfg80211.scan_done_lock);
2975 #endif
2976                         atomic_dec(&vif->cfg80211.scan_status);
2977                 }
2978 #ifdef CONFIG_HAS_WAKELOCK
2979                 wake_lock_destroy(&vif->cfg80211.scan_done_lock);
2980 #endif
2981                 del_timer_sync(&(vif->cfg80211.scan_timeout));
2982                 vfree(vif->cfg80211.scan_frame_array);
2983                 vif->cfg80211.scan_frame_array = NULL;
2984         }
2985         wiphy_unregister(wlan->wiphy);
2986         wiphy_free(wlan->wiphy);
2987         wlan->wiphy = NULL;
2988         return OK;
2989 }
2990
2991 int mac_addr_cfg(wlan_vif_t *vif, unsigned char vif_id)
2992 {
2993         struct file *fp = 0;
2994         mm_segment_t fs;
2995         loff_t *pos;
2996         bool no_file = false;
2997         unsigned char file_data[64] = { 0 };
2998         unsigned char mac_addr[18] = { 0 };
2999         unsigned char *tmp_p = NULL;
3000         fs = get_fs();
3001         set_fs(KERNEL_DS);
3002
3003         fp = filp_open(ENG_MAC_ADDR_PATH, O_RDONLY, 0);
3004         if (IS_ERR(fp)) {
3005                 random_ether_addr(vif->ndev->dev_addr);
3006 #ifdef CONFIG_MACH_SAMSUNG
3007                 vif->ndev->dev_addr[0] = 0x00;
3008                 vif->ndev->dev_addr[1] = 0x12;
3009                 vif->ndev->dev_addr[2] = 0x36;
3010 #endif /* CONFIG_MACH_SAMSUNG */
3011                 fp = filp_open(ENG_MAC_ADDR_PATH, O_CREAT | O_RDWR, 0666);
3012                 if (IS_ERR(fp)) {
3013                         printke("%s %d err\n", __func__, __LINE__);
3014                         goto EXIT;
3015                 }
3016                 no_file = true;
3017         }
3018         pos = &(fp->f_pos);
3019         if (false == no_file) {
3020                 tmp_p = file_data;
3021                 vfs_read(fp, file_data, sizeof(file_data), pos);
3022                 memcpy(mac_addr, tmp_p, 18);
3023                 sscanf(mac_addr, "%02X:%02X:%02X:%02X:%02X:%02X",
3024                        (unsigned int *)&(vif->ndev->dev_addr[0]),
3025                        (unsigned int *)&(vif->ndev->dev_addr[1]),
3026                        (unsigned int *)&(vif->ndev->dev_addr[2]),
3027                        (unsigned int *)&(vif->ndev->dev_addr[3]),
3028                        (unsigned int *)&(vif->ndev->dev_addr[4]),
3029                        (unsigned int *)&(vif->ndev->dev_addr[5]));
3030                 mac_addr[17] = '\n';
3031         } else {
3032                 sprintf(mac_addr, "%02X:%02X:%02X:%02X:%02X:%02X\n",
3033                         vif->ndev->dev_addr[0],
3034                         vif->ndev->dev_addr[1],
3035                         vif->ndev->dev_addr[2],
3036                         vif->ndev->dev_addr[3],
3037                         vif->ndev->dev_addr[4],
3038                         vif->ndev->dev_addr[5]);
3039                 vfs_write(fp, mac_addr, 18, pos);
3040                 printke("[%s write addr:%s]\n", __func__, mac_addr);
3041         }
3042
3043         if (vif_id)
3044                 vif->ndev->dev_addr[0] = vif->ndev->dev_addr[0] ^ 0x02;
3045         else {
3046                 if (!(IS_ERR(fp))) {
3047                         filp_close(fp, NULL);
3048                 }
3049
3050                 fp = filp_open(ENG_MAC_ADDR_INFO_PATH, O_CREAT | O_RDWR, 0666);
3051                 if (IS_ERR(fp))
3052                         printke("[%s %s: File create err]\n", __func__, ENG_MAC_ADDR_INFO_PATH);
3053                 else {
3054                         pos = &(fp->f_pos);
3055                         vfs_write(fp, mac_addr, 18, pos);
3056                         printke("[%s write addr:%s to %s]\n", __func__, mac_addr, ENG_MAC_ADDR_INFO_PATH);
3057                 }
3058         }
3059
3060 EXIT:
3061         if (!(IS_ERR(fp))) {
3062                 filp_close(fp, NULL);
3063         }
3064         set_fs(fs);
3065         return OK;
3066 }
3067
3068 int wlan_vif_init(wlan_vif_t *vif, int type, const char *name, void *ops)
3069 {
3070         int ret;
3071         struct net_device *ndev;
3072         unsigned char str[64] = { 0 };
3073         ndev = alloc_netdev(4, name, ether_setup);
3074         if (!ndev) {
3075                 ASSERT();
3076                 return ERROR;
3077         }
3078         vif->ndev = ndev;
3079         vif->beacon_loss = 0;
3080         memcpy((unsigned char *)(netdev_priv(ndev)), (unsigned char *)(&vif),
3081                4);
3082         ndev->netdev_ops = ops;
3083         ndev->watchdog_timeo = 1 * HZ;
3084         ndev->ieee80211_ptr = &(vif->wdev);
3085         vif->wdev.iftype = type;
3086         init_register_frame_param(vif);
3087         init_send_deauth_work(vif);
3088         vif->wdev.wiphy = g_wlan.wiphy;
3089         SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3090         vif->wdev.netdev = ndev;
3091         init_timer(&(vif->cfg80211.scan_timeout));
3092         vif->cfg80211.scan_timeout.data = (unsigned long)vif;
3093         vif->cfg80211.scan_timeout.function = wlan_scan_timeout;
3094         vif->cfg80211.scan_request = NULL;
3095         vif->cfg80211.scan_frame_array =
3096             vmalloc(MAX_SCAN_FRAME_BUF_NUM * sizeof(buf_scan_frame_t));
3097         memset(vif->cfg80211.scan_frame_array, 0,
3098                MAX_SCAN_FRAME_BUF_NUM * sizeof(buf_scan_frame_t));
3099         atomic_set(&vif->cfg80211.scan_status, 0);
3100         vif->cfg80211.connect_status = ITM_DISCONNECTED;
3101         memset(vif->cfg80211.bssid, 0, sizeof(vif->cfg80211.bssid));
3102         vif->mode = ITM_NONE_MODE;
3103 #ifdef CONFIG_HAS_WAKELOCK
3104         wake_lock_init(&(vif->cfg80211.scan_done_lock), WAKE_LOCK_SUSPEND,
3105                        "scan_lock");
3106 #endif
3107         mac_addr_cfg(vif, vif->id);
3108         ret = register_netdev(vif->ndev);
3109         if (ret < 0) {
3110                 printkd("[%s][register_netdev err:%d]\n", __func__, ret);
3111                 return ERROR;
3112         }
3113         sprintf(str, "[%s][%d][%s][0x%p][addr]:", __func__, vif->id,
3114                 vif->ndev->name, vif->ndev);
3115         hex_dump(str, strlen(str), (unsigned char *)(&(vif->ndev->dev_addr[0])),
3116                  6);
3117         return OK;
3118 }
3119
3120 int wlan_vif_free(wlan_vif_t *vif)
3121 {
3122         if (NULL == vif->ndev)
3123                 return ERROR;
3124         printkd("[unregister_netdev][%s][0x%p]\n", __func__, vif->ndev->name);
3125         cancel_work_sync(&vif->cfg80211.register_frame.work);
3126         cancel_work_sync(&vif->deauth_info.work);
3127         unregister_netdev(vif->ndev);
3128         printkd("[free_netdev][%s][0x%p]\n", __func__, vif->ndev->name);
3129         free_netdev(vif->ndev);
3130         printkd("%s(), ok\n", __func__);
3131         return OK;
3132 }
3133
3134 wlan_vif_t *id_to_vif(unsigned char id)
3135 {
3136         if ((NETIF_0_ID != id) && (NETIF_1_ID != id))
3137                 return NULL;
3138         return &(g_wlan.netif[id]);
3139 }
3140
3141 wlan_vif_t *ndev_to_vif(struct net_device * ndev)
3142 {
3143         wlan_vif_t *vif;
3144         memcpy((unsigned char *)(&vif), (unsigned char *)(netdev_priv(ndev)),
3145                4);
3146         return vif;
3147 }