WiFi: add rtl8189es/etv support, Optimization wifi configuration.
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8189es / os_dep / linux / sdio_intf.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _HCI_INTF_C_
21
22 #include <drv_types.h>
23 #include <platform_ops.h>
24
25 #ifndef CONFIG_SDIO_HCI
26 #error "CONFIG_SDIO_HCI shall be on!\n"
27 #endif
28
29 #ifndef dev_to_sdio_func
30 #define dev_to_sdio_func(d)     container_of(d, struct sdio_func, dev)
31 #endif
32
33 #ifdef CONFIG_WOWLAN
34 static struct mmc_host *mmc_host = NULL;
35 #endif
36
37 static const struct sdio_device_id sdio_ids[] =
38 {
39 #ifdef CONFIG_RTL8723A
40         { SDIO_DEVICE(0x024c, 0x8723),.driver_data = RTL8723A},
41 #endif //CONFIG_RTL8723A
42 #ifdef CONFIG_RTL8723B
43         { SDIO_DEVICE(0x024c, 0xB723),.driver_data = RTL8723B},
44 #endif
45 #ifdef CONFIG_RTL8188E
46         { SDIO_DEVICE(0x024c, 0x8179),.driver_data = RTL8188E},
47 #endif //CONFIG_RTL8188E
48 #ifdef CONFIG_RTL8821A
49         { SDIO_DEVICE(0x024c, 0x8821),.driver_data = RTL8821},
50 #endif //CONFIG_RTL8188E
51
52 #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) /* temporarily add this to accept all sdio wlan id */
53         { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) },
54 #endif
55 //      { /* end: all zeroes */                         },
56 };
57
58 static int rtw_drv_init(struct sdio_func *func, const struct sdio_device_id *id);
59 static void rtw_dev_remove(struct sdio_func *func);
60 static int rtw_sdio_resume(struct device *dev);
61 static int rtw_sdio_suspend(struct device *dev);
62
63 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) 
64 static const struct dev_pm_ops rtw_sdio_pm_ops = {
65         .suspend        = rtw_sdio_suspend,
66         .resume = rtw_sdio_resume,
67 };
68 #endif
69         
70 struct sdio_drv_priv {
71         struct sdio_driver r871xs_drv;
72         int drv_registered;
73 };
74
75 static struct sdio_drv_priv sdio_drvpriv = {
76         .r871xs_drv.probe = rtw_drv_init,
77         .r871xs_drv.remove = rtw_dev_remove,
78         .r871xs_drv.name = (char*)DRV_NAME,
79         .r871xs_drv.id_table = sdio_ids,
80         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) 
81         .r871xs_drv.drv = {
82                 .pm = &rtw_sdio_pm_ops,
83         }
84         #endif
85 };
86
87 static void sd_sync_int_hdl(struct sdio_func *func)
88 {
89         struct dvobj_priv *psdpriv;
90
91
92         psdpriv = sdio_get_drvdata(func);
93
94         if (!psdpriv->if1) {
95                 DBG_871X("%s if1 == NULL\n", __func__);
96                 return;
97         }
98
99         rtw_sdio_set_irq_thd(psdpriv, current);
100         sd_int_hdl(psdpriv->if1);
101         rtw_sdio_set_irq_thd(psdpriv, NULL);
102 }
103
104 int sdio_alloc_irq(struct dvobj_priv *dvobj)
105 {
106         PSDIO_DATA psdio_data;
107         struct sdio_func *func;
108         int err;
109
110         psdio_data = &dvobj->intf_data;
111         func = psdio_data->func;
112
113         sdio_claim_host(func);
114
115         err = sdio_claim_irq(func, &sd_sync_int_hdl);
116         if (err)
117         {
118                 dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++;
119                 printk(KERN_CRIT "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err);
120         }
121         else
122         {
123                 dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++;
124                 dvobj->irq_alloc = 1;
125         }
126
127         sdio_release_host(func);
128
129         return err?_FAIL:_SUCCESS;
130 }
131
132 void sdio_free_irq(struct dvobj_priv *dvobj)
133 {
134     PSDIO_DATA psdio_data;
135     struct sdio_func *func;
136     int err;
137
138     if (dvobj->irq_alloc) {
139         psdio_data = &dvobj->intf_data;
140         func = psdio_data->func;
141
142         if (func) {
143             sdio_claim_host(func);
144             err = sdio_release_irq(func);
145             if (err)
146             {
147                                 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
148                                 DBG_871X_LEVEL(_drv_err_,"%s: sdio_release_irq FAIL(%d)!\n", __func__, err);
149             }
150             else
151                 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
152             sdio_release_host(func);
153         }
154         dvobj->irq_alloc = 0;
155     }
156 }
157
158 #ifdef CONFIG_GPIO_WAKEUP
159 extern unsigned int oob_irq;
160 static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data)
161 {
162         PADAPTER padapter = (PADAPTER)data;
163         DBG_871X_LEVEL(_drv_always_, "gpio_hostwakeup_irq_thread\n");
164         /* Disable interrupt before calling handler */
165         //disable_irq_nosync(oob_irq);
166         rtw_lock_suspend_timeout(HZ/2);
167 #ifdef CONFIG_PLATFORM_ARM_SUN6I
168         return 0;
169 #else
170         return IRQ_HANDLED;
171 #endif
172 }
173
174 static u8 gpio_hostwakeup_alloc_irq(PADAPTER padapter)
175 {
176         int err;
177         if (oob_irq == 0)
178                 return _FAIL;
179         /* dont set it IRQF_TRIGGER_LOW, or wowlan */
180         /* power is high after suspend */
181         /* and failing can prevent can not sleep issue if */
182         /* wifi gpio12 pin is not linked with CPU */
183         err = request_threaded_irq(oob_irq, gpio_hostwakeup_irq_thread, NULL,
184                 //IRQF_TRIGGER_LOW | IRQF_ONESHOT,
185                 IRQF_TRIGGER_FALLING,
186                 "rtw_wifi_gpio_wakeup", padapter);
187         if (err < 0) {
188                 DBG_871X("Oops: can't allocate gpio irq %d err:%d\n", oob_irq, err);
189                 return _FALSE;
190         } else {
191                 DBG_871X("allocate gpio irq %d ok\n", oob_irq);
192         }
193         
194 #ifndef CONFIG_PLATFORM_ARM_SUN8I       
195         enable_irq_wake(oob_irq);
196 #endif
197         return _SUCCESS;
198 }
199
200 static void gpio_hostwakeup_free_irq(PADAPTER padapter)
201 {
202         if (oob_irq == 0)
203                 return;
204                 
205 #ifndef CONFIG_PLATFORM_ARM_SUN8I
206         disable_irq_wake(oob_irq);
207 #endif
208         free_irq(oob_irq, padapter);
209 }
210 #endif
211
212 static u32 sdio_init(struct dvobj_priv *dvobj)
213 {
214         PSDIO_DATA psdio_data;
215         struct sdio_func *func;
216         int err;
217
218 _func_enter_;
219
220         psdio_data = &dvobj->intf_data;
221         func = psdio_data->func;
222
223         //3 1. init SDIO bus
224         sdio_claim_host(func);
225
226         err = sdio_enable_func(func);
227         if (err) {
228                 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
229                 DBG_8192C(KERN_CRIT "%s: sdio_enable_func FAIL(%d)!\n", __func__, err);
230                 goto release;
231         }
232
233         err = sdio_set_block_size(func, 512);
234         if (err) {
235                 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
236                 DBG_8192C(KERN_CRIT "%s: sdio_set_block_size FAIL(%d)!\n", __func__, err);
237                 goto release;
238         }
239         psdio_data->block_transfer_len = 512;
240         psdio_data->tx_block_mode = 1;
241         psdio_data->rx_block_mode = 1;
242
243 release:
244         sdio_release_host(func);
245
246 exit:
247 _func_exit_;
248
249         if (err) return _FAIL;
250         return _SUCCESS;
251 }
252
253 static void sdio_deinit(struct dvobj_priv *dvobj)
254 {
255         struct sdio_func *func;
256         int err;
257
258
259         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+sdio_deinit\n"));
260
261         func = dvobj->intf_data.func;
262
263         if (func) {
264                 sdio_claim_host(func);
265                 err = sdio_disable_func(func);
266                 if (err)
267                 {
268                         dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++;
269                         DBG_8192C(KERN_ERR "%s: sdio_disable_func(%d)\n", __func__, err);
270                 }
271
272                 if (dvobj->irq_alloc) {
273                         err = sdio_release_irq(func);
274                         if (err)
275                         {
276                                 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
277                                 DBG_8192C(KERN_ERR "%s: sdio_release_irq(%d)\n", __func__, err);
278                         }
279                         else
280                                 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
281                 }
282
283                 sdio_release_host(func);
284         }
285 }
286 static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func)
287 {
288         int status = _FAIL;
289         struct dvobj_priv *dvobj = NULL;
290         PSDIO_DATA psdio;
291 _func_enter_;
292
293         if((dvobj = devobj_init()) == NULL) {
294                 goto exit;
295         }
296
297         sdio_set_drvdata(func, dvobj);
298
299         psdio = &dvobj->intf_data;
300         psdio->func = func;
301
302         if (sdio_init(dvobj) != _SUCCESS) {
303                 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!\n", __FUNCTION__));
304                 goto free_dvobj;
305         }
306         rtw_reset_continual_io_error(dvobj);
307         status = _SUCCESS;
308
309 free_dvobj:
310         if (status != _SUCCESS && dvobj) {
311                 sdio_set_drvdata(func, NULL);
312                 
313                 devobj_deinit(dvobj);
314                 
315                 dvobj = NULL;
316         }
317 exit:
318 _func_exit_;
319         return dvobj;
320 }
321
322 static void sdio_dvobj_deinit(struct sdio_func *func)
323 {
324         struct dvobj_priv *dvobj = sdio_get_drvdata(func);
325 _func_enter_;
326
327         sdio_set_drvdata(func, NULL);
328         if (dvobj) {
329                 sdio_deinit(dvobj);
330                 devobj_deinit(dvobj);
331         }
332
333 _func_exit_;
334         return;
335 }
336 static void rtw_decide_chip_type_by_device_id(PADAPTER padapter, const struct sdio_device_id  *pdid)
337 {
338         padapter->chip_type = pdid->driver_data;
339
340 #if defined(CONFIG_RTL8723A)
341         if( padapter->chip_type == RTL8723A){
342                 padapter->HardwareType = HARDWARE_TYPE_RTL8723AS;
343                 DBG_871X("CHIP TYPE: RTL8723A\n");
344         }
345 #endif
346
347 #if defined(CONFIG_RTL8188E)
348         if(padapter->chip_type == RTL8188E){
349                 padapter->HardwareType = HARDWARE_TYPE_RTL8188ES;
350                 DBG_871X("CHIP TYPE: RTL8188E\n");
351         }
352 #endif
353
354 #if defined(CONFIG_RTL8723B)
355         padapter->chip_type = RTL8723B;
356         padapter->HardwareType = HARDWARE_TYPE_RTL8723BS;
357 #endif
358
359 #if defined(CONFIG_RTL8821A)
360         if (padapter->chip_type == RTL8821) {
361                 padapter->HardwareType = HARDWARE_TYPE_RTL8821S;
362                 DBG_871X("CHIP TYPE: RTL8821A\n");
363         }
364 #endif
365 }
366
367 void rtw_set_hal_ops(PADAPTER padapter)
368 {
369 #if defined(CONFIG_RTL8723A)
370         if( padapter->chip_type == RTL8723A){
371                 rtl8723as_set_hal_ops(padapter);
372         }
373 #endif
374 #if defined(CONFIG_RTL8188E)
375         if(padapter->chip_type == RTL8188E){
376                 rtl8188es_set_hal_ops(padapter);
377         }
378 #endif
379 #if defined(CONFIG_RTL8723B)
380         if(padapter->chip_type == RTL8723B){
381                 rtl8723bs_set_hal_ops(padapter);
382         }
383 #endif
384 #if defined(CONFIG_RTL8821A)
385         if(padapter->chip_type == RTL8821){
386                 rtl8821as_set_hal_ops(padapter);
387         }
388 #endif
389 }
390
391 static void sd_intf_start(PADAPTER padapter)
392 {
393         if (padapter == NULL) {
394                 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
395                 return;
396         }
397
398         // hal dep
399         rtw_hal_enable_interrupt(padapter);
400 }
401
402 static void sd_intf_stop(PADAPTER padapter)
403 {
404         if (padapter == NULL) {
405                 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
406                 return;
407         }
408
409         // hal dep
410         rtw_hal_disable_interrupt(padapter);
411 }
412
413
414 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
415 PADAPTER g_test_adapter = NULL;
416 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
417
418 _adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct sdio_device_id  *pdid)
419 {
420         int status = _FAIL;
421         struct net_device *pnetdev;
422         PADAPTER padapter = NULL;
423         
424         if ((padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter))) == NULL) {
425                 goto exit;
426         }
427
428 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
429         g_test_adapter = padapter;
430 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
431         padapter->dvobj = dvobj;
432         dvobj->if1 = padapter;
433
434         padapter->bDriverStopped=_TRUE;
435
436         dvobj->padapters[dvobj->iface_nums++] = padapter;
437         padapter->iface_id = IFACE_ID0;
438
439 #if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_DUALMAC_CONCURRENT)
440         //set adapter_type/iface type for primary padapter
441         padapter->isprimary = _TRUE;
442         padapter->adapter_type = PRIMARY_ADAPTER;       
443         #ifndef CONFIG_HWPORT_SWAP
444         padapter->iface_type = IFACE_PORT0;
445         #else
446         padapter->iface_type = IFACE_PORT1;
447         #endif
448 #endif
449
450         padapter->interface_type = RTW_SDIO;
451         rtw_decide_chip_type_by_device_id(padapter, pdid);
452         
453         //3 1. init network device data
454         pnetdev = rtw_init_netdev(padapter);
455         if (!pnetdev)
456                 goto free_adapter;
457         
458         SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
459
460         padapter = rtw_netdev_priv(pnetdev);
461
462 #ifdef CONFIG_IOCTL_CFG80211
463         rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj));
464 #endif
465
466         //3 3. init driver special setting, interface, OS and hardware relative
467
468         //4 3.1 set hardware operation functions
469         rtw_set_hal_ops(padapter);
470
471
472         //3 5. initialize Chip version
473         padapter->intf_start = &sd_intf_start;
474         padapter->intf_stop = &sd_intf_stop;
475
476         padapter->intf_init = &sdio_init;
477         padapter->intf_deinit = &sdio_deinit;
478         padapter->intf_alloc_irq = &sdio_alloc_irq;
479         padapter->intf_free_irq = &sdio_free_irq;
480
481         if (rtw_init_io_priv(padapter, sdio_set_intf_ops) == _FAIL)
482         {
483                 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
484                         ("rtw_drv_init: Can't init io_priv\n"));
485                 goto free_hal_data;
486         }
487
488         rtw_hal_read_chip_version(padapter);
489
490         rtw_hal_chip_configure(padapter);
491
492 #ifdef CONFIG_BT_COEXIST
493         rtw_btcoex_Initialize(padapter);
494 #endif // CONFIG_BT_COEXIST
495
496         //3 6. read efuse/eeprom data
497         rtw_hal_read_chip_info(padapter);
498
499         //3 7. init driver common data
500         if (rtw_init_drv_sw(padapter) == _FAIL) {
501                 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
502                          ("rtw_drv_init: Initialize driver software resource Failed!\n"));
503                 goto free_hal_data;
504         }
505
506         //3 8. get WLan MAC address
507         // set mac addr
508         rtw_macaddr_cfg(padapter->eeprompriv.mac_addr);
509         rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr, padapter->eeprompriv.mac_addr);
510
511         rtw_hal_disable_interrupt(padapter);
512
513         DBG_871X("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n"
514                 ,padapter->bDriverStopped
515                 ,padapter->bSurpriseRemoved
516                 ,padapter->bup
517                 ,padapter->hw_init_completed
518         );
519         
520         status = _SUCCESS;
521         
522 free_hal_data:
523         if(status != _SUCCESS && padapter->HalData)
524                 rtw_mfree(padapter->HalData, sizeof(*(padapter->HalData)));
525
526 free_wdev:
527         if(status != _SUCCESS) {
528                 #ifdef CONFIG_IOCTL_CFG80211
529                 rtw_wdev_unregister(padapter->rtw_wdev);
530                 rtw_wdev_free(padapter->rtw_wdev);
531                 #endif
532         }
533
534 free_adapter:
535         if (status != _SUCCESS) {
536                 if (pnetdev)
537                         rtw_free_netdev(pnetdev);
538                 else
539                         rtw_vmfree((u8*)padapter, sizeof(*padapter));
540                 padapter = NULL;
541         }
542 exit:
543         return padapter;
544 }
545
546 static void rtw_sdio_if1_deinit(_adapter *if1)
547 {
548         struct net_device *pnetdev = if1->pnetdev;
549         struct mlme_priv *pmlmepriv= &if1->mlmepriv;
550
551         if(check_fwstate(pmlmepriv, _FW_LINKED))
552                 rtw_disassoc_cmd(if1, 0, _FALSE);
553
554 #ifdef CONFIG_AP_MODE
555         free_mlme_ap_info(if1);
556         #ifdef CONFIG_HOSTAPD_MLME
557         hostapd_mode_unload(if1);
558         #endif
559 #endif
560
561 #ifdef CONFIG_GPIO_WAKEUP
562 #ifdef CONFIG_PLATFORM_ARM_SUN6I 
563         sw_gpio_eint_set_enable(gpio_eint_wlan, 0);
564         sw_gpio_irq_free(eint_wlan_handle);
565 #else  
566         gpio_hostwakeup_free_irq(if1);
567 #endif
568 #endif
569
570         rtw_cancel_all_timer(if1);
571
572 #ifdef CONFIG_WOWLAN
573         adapter_to_pwrctl(if1)->wowlan_mode=_FALSE;
574         DBG_871X_LEVEL(_drv_always_, "%s wowlan_mode:%d\n", __func__, adapter_to_pwrctl(if1)->wowlan_mode);
575 #endif //CONFIG_WOWLAN
576
577         rtw_dev_unload(if1);
578         DBG_871X("+r871xu_dev_remove, hw_init_completed=%d\n", if1->hw_init_completed);
579         
580         rtw_handle_dualmac(if1, 0);
581
582 #ifdef CONFIG_IOCTL_CFG80211
583         if (if1->rtw_wdev) {
584                 rtw_wdev_free(if1->rtw_wdev);
585         }
586 #endif
587
588         rtw_free_drv_sw(if1);
589
590         if(pnetdev)
591                 rtw_free_netdev(pnetdev);
592
593 #ifdef CONFIG_PLATFORM_RTD2880B
594         DBG_871X("wlan link down\n");
595         rtd2885_wlan_netlink_sendMsg("linkdown", "8712");
596 #endif
597
598 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
599         g_test_adapter = NULL;
600 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
601 }
602
603 /*
604  * drv_init() - a device potentially for us
605  *
606  * notes: drv_init() is called when the bus driver has located a card for us to support.
607  *        We accept the new device by returning 0.
608  */
609 static int rtw_drv_init(
610         struct sdio_func *func,
611         const struct sdio_device_id *id)
612 {
613         int status = _FAIL;
614         struct net_device *pnetdev;
615         PADAPTER if1 = NULL, if2 = NULL;
616         struct dvobj_priv *dvobj;
617
618         RT_TRACE(_module_hci_intfs_c_, _drv_info_,
619                 ("+rtw_drv_init: vendor=0x%04x device=0x%04x class=0x%02x\n",
620                 func->vendor, func->device, func->class));
621
622         if ((dvobj = sdio_dvobj_init(func)) == NULL) {
623                 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n"));
624                 goto exit;
625         }
626
627         if ((if1 = rtw_sdio_if1_init(dvobj, id)) == NULL) {
628                 DBG_871X("rtw_init_primary_adapter Failed!\n");
629                 goto free_dvobj;
630         }
631
632 #ifdef CONFIG_CONCURRENT_MODE
633         if ((if2 = rtw_drv_if2_init(if1, sdio_set_intf_ops)) == NULL) {
634                 goto free_if1;
635         }
636 #endif
637
638         //dev_alloc_name && register_netdev
639         if((status = rtw_drv_register_netdev(if1)) != _SUCCESS) {
640                 goto free_if2;
641         }
642
643 #ifdef CONFIG_HOSTAPD_MLME
644         hostapd_mode_init(if1);
645 #endif
646
647 #ifdef CONFIG_PLATFORM_RTD2880B
648         DBG_871X("wlan link up\n");
649         rtd2885_wlan_netlink_sendMsg("linkup", "8712");
650 #endif
651
652         if (sdio_alloc_irq(dvobj) != _SUCCESS)
653                 goto free_if2;
654
655 #ifdef  CONFIG_GPIO_WAKEUP
656 #ifdef CONFIG_PLATFORM_ARM_SUN6I
657         eint_wlan_handle = sw_gpio_irq_request(gpio_eint_wlan, TRIG_EDGE_NEGATIVE,(peint_handle)gpio_hostwakeup_irq_thread, NULL);
658         if (!eint_wlan_handle) {
659                DBG_871X( "%s: request irq failed\n",__func__);
660                return -1;
661   }
662 #else
663         gpio_hostwakeup_alloc_irq(if1);
664 #endif
665 #endif
666
667 #ifdef CONFIG_GLOBAL_UI_PID
668         if(ui_pid[1]!=0) {
669                 DBG_871X("ui_pid[1]:%d\n",ui_pid[1]);
670                 rtw_signal_process(ui_pid[1], SIGUSR2);
671         }
672 #endif
673
674         RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-871x_drv - drv_init, success!\n"));
675
676         status = _SUCCESS;
677
678 free_if2:
679         if(status != _SUCCESS && if2) {
680                 #ifdef CONFIG_CONCURRENT_MODE
681                 rtw_drv_if2_stop(if2);
682                 rtw_drv_if2_free(if2);
683                 #endif
684         }
685 free_if1:
686         if (status != _SUCCESS && if1) {
687                 rtw_sdio_if1_deinit(if1);
688         }
689 free_dvobj:
690         if (status != _SUCCESS)
691                 sdio_dvobj_deinit(func);
692 exit:
693         return status == _SUCCESS?0:-ENODEV;
694 }
695
696 static void rtw_dev_remove(struct sdio_func *func)
697 {
698         struct dvobj_priv *dvobj = sdio_get_drvdata(func);
699         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
700         PADAPTER padapter = dvobj->if1;
701
702 _func_enter_;
703
704         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+rtw_dev_remove\n"));
705
706         dvobj->processing_dev_remove = _TRUE;
707
708         rtw_unregister_netdevs(dvobj);
709
710         if (padapter->bSurpriseRemoved == _FALSE) {
711                 int err;
712
713                 /* test surprise remove */
714                 sdio_claim_host(func);
715                 sdio_readb(func, 0, &err);
716                 sdio_release_host(func);
717                 if (err == -ENOMEDIUM) {
718                         padapter->bSurpriseRemoved = _TRUE;
719                         DBG_871X(KERN_NOTICE "%s: device had been removed!\n", __func__);
720                 }
721         }
722
723 #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
724         rtw_unregister_early_suspend(pwrctl);
725 #endif
726
727         rtw_ps_deny(padapter, PS_DENY_DRV_REMOVE);
728
729         rtw_pm_set_ips(padapter, IPS_NONE);
730         rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
731
732         LeaveAllPowerSaveMode(padapter);
733
734 #ifdef CONFIG_CONCURRENT_MODE
735         rtw_drv_if2_stop(dvobj->if2);
736 #endif
737
738 #ifdef CONFIG_BT_COEXIST
739         rtw_btcoex_HaltNotify(padapter);
740 #endif
741
742         rtw_sdio_if1_deinit(padapter);
743
744 #ifdef CONFIG_CONCURRENT_MODE
745         rtw_drv_if2_free(dvobj->if2);
746 #endif
747
748         sdio_dvobj_deinit(func);
749
750         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-rtw_dev_remove\n"));
751
752 _func_exit_;
753 }
754 extern int pm_netdev_open(struct net_device *pnetdev,u8 bnormal);
755 extern int pm_netdev_close(struct net_device *pnetdev,u8 bnormal);
756
757
758 #ifdef CONFIG_SUSPEND_REFINE    
759 static int rtw_sdio_suspend(struct device *dev)
760 {
761         struct sdio_func *func =dev_to_sdio_func(dev);
762         struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
763         struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv);
764         _adapter *padapter = psdpriv->if1;
765         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
766         int ret = 0;
767         u8 ch, bw, offset;
768
769         if(padapter->bDriverStopped == _TRUE)
770         {
771                 DBG_871X("%s bDriverStopped = %d\n", __FUNCTION__, padapter->bDriverStopped);
772                 goto exit;
773         }
774
775         if (pwrpriv->bInSuspend == _TRUE)
776         {
777                 DBG_871X("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend);
778                 pdbgpriv->dbg_suspend_error_cnt++;
779                 goto exit;
780         }
781
782         ret = rtw_suspend_common(padapter);             
783
784 exit:
785 #ifdef CONFIG_RTW_SDIO_PM_KEEP_POWER 
786         //Android 4.0 don't support WIFI close power
787         //or power down or clock will close after wifi resume,
788         //this is sprd's bug in Android 4.0, but sprd don't
789         //want to fix it.
790         //we have test power under 8723as, power consumption is ok
791         if (func) {
792                 mmc_pm_flag_t pm_flag = 0;
793                 pm_flag = sdio_get_host_pm_caps(func);
794                 DBG_871X("cmd: %s: suspend: PM flag = 0x%x\n", sdio_func_id(func), pm_flag);
795                 if (!(pm_flag & MMC_PM_KEEP_POWER)) {
796                         DBG_871X("%s: cannot remain alive while host is suspended\n", sdio_func_id(func));
797                         pdbgpriv->dbg_suspend_error_cnt++;
798                         return -ENOSYS;
799                 } else {
800                         DBG_871X("cmd: suspend with MMC_PM_KEEP_POWER\n");
801                         sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
802                 }
803         }
804 #endif
805         return ret;
806 }
807 int rtw_resume_process(_adapter *padapter)
808 {
809         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
810         struct dvobj_priv *psdpriv = padapter->dvobj;
811         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
812
813         if (pwrpriv->bInSuspend == _FALSE)
814         {
815                 pdbgpriv->dbg_resume_error_cnt++;
816                 DBG_871X("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend);
817                 return -1;
818         }
819         
820         return rtw_resume_common(padapter);
821 }
822
823
824 #else //CONFIG_SUSPEND_REFINE
825 static int rtw_sdio_suspend(struct device *dev)
826 {
827         struct sdio_func *func =dev_to_sdio_func(dev);
828         struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
829         struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv);
830         _adapter *padapter = psdpriv->if1;
831         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
832         struct net_device *pnetdev = padapter->pnetdev;
833         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
834                 
835         int ret = 0;
836 #ifdef CONFIG_PLATFORM_SPRD
837         u32 value;
838 #endif // CONFIG_PLATFORM_SPRD
839
840 #ifdef CONFIG_WOWLAN
841         struct wowlan_ioctl_param poidparam;
842         u8 ch, bw, offset;
843         u8 ps_mode;
844 #endif //CONFIG_WOWLAN
845
846         u32 start_time = rtw_get_current_time();
847
848         _func_enter_;
849
850         DBG_871X_LEVEL(_drv_always_, "sdio suspend start\n");
851         DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
852         pdbgpriv->dbg_suspend_cnt++;
853         
854         if (pwrpriv->bInSuspend == _TRUE)
855         {
856                 DBG_871X("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend);
857                 pdbgpriv->dbg_suspend_error_cnt++;
858                 goto exit;
859         }
860         
861         pwrpriv->bInSuspend = _TRUE;
862 #ifdef CONFIG_PNO_SUPPORT
863         pwrpriv->pno_in_resume = _FALSE;
864 #endif
865
866 #ifdef CONFIG_WOWLAN
867         if (check_fwstate(pmlmepriv, _FW_LINKED))
868                 pwrpriv->wowlan_mode = _TRUE;
869         else
870                 pwrpriv->wowlan_mode = _FALSE;
871 #endif
872
873 #ifdef CONFIG_PNO_SUPPORT
874         pwrpriv->wowlan_mode |= pwrpriv->wowlan_pno_enable;
875 #endif
876
877         while (pwrpriv->bips_processing == _TRUE)
878                 rtw_msleep_os(1);
879
880 #ifdef CONFIG_IOL_READ_EFUSE_MAP
881         if(!padapter->bup){
882                 u8 bMacPwrCtrlOn = _FALSE;
883                 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
884                 if(bMacPwrCtrlOn)
885                         rtw_hal_power_off(padapter);
886         }
887 #endif
888
889         if((!padapter->bup) || (padapter->bDriverStopped)||(padapter->bSurpriseRemoved))
890         {
891                 DBG_871X("%s bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", __FUNCTION__
892                         ,padapter->bup, padapter->bDriverStopped,padapter->bSurpriseRemoved);
893                 pdbgpriv->dbg_suspend_error_cnt++;
894                 goto exit;
895         }
896
897         rtw_ps_deny(padapter, PS_DENY_SUSPEND);
898
899         if(pnetdev) {
900 #ifdef CONFIG_WOWLAN
901                 if(pwrpriv->wowlan_mode == _TRUE) {
902                         rtw_netif_stop_queue(pnetdev);
903                 }
904                 else
905 #endif
906                 {
907                         netif_carrier_off(pnetdev);
908                         rtw_netif_stop_queue(pnetdev);
909                 }
910         }
911
912         rtw_cancel_all_timer(padapter);
913
914 #ifdef CONFIG_CONCURRENT_MODE
915         if (padapter->pbuddy_adapter)
916         {
917                 rtw_cancel_all_timer(padapter->pbuddy_adapter);
918         }
919 #endif // CONFIG_CONCURRENT_MODE
920
921         LeaveAllPowerSaveModeDirect(padapter);
922
923         rtw_stop_cmd_thread(padapter);
924         
925 #ifdef CONFIG_WOWLAN
926         if (pwrpriv->wowlan_mode == _TRUE)
927         {
928                 // 1. stop thread
929                 padapter->bDriverStopped = _TRUE;       //for stop thread
930                 rtw_stop_drv_threads(padapter);
931                 padapter->bDriverStopped = _FALSE;      //for 32k command
932
933 #ifdef CONFIG_CONCURRENT_MODE
934                 if (padapter->pbuddy_adapter)
935                 {
936                         padapter->pbuddy_adapter->bDriverStopped = _TRUE;       //for stop thread
937                         rtw_stop_drv_threads(padapter->pbuddy_adapter);
938                         padapter->pbuddy_adapter->bDriverStopped = _FALSE;      //for 32k command
939                 }
940 #endif // CONFIG_CONCURRENT_MODE
941
942                 // 2. disable interrupt
943                 rtw_hal_disable_interrupt(padapter); // It need wait for leaving 32K.
944
945                 // 2.1 clean interupt
946                 if (padapter->HalFunc.clear_interrupt)
947                         padapter->HalFunc.clear_interrupt(padapter);
948
949                 // 2.2 free irq
950                 sdio_free_irq(adapter_to_dvobj(padapter));
951         }
952 #endif // CONFIG_WOWLAN
953
954 #ifdef CONFIG_BT_COEXIST
955         rtw_btcoex_SuspendNotify(padapter, 1);
956 #endif // CONFIG_BT_COEXIST
957
958         rtw_ps_deny_cancel(padapter, PS_DENY_SUSPEND);
959
960 #ifdef CONFIG_WOWLAN
961         DBG_871X("wowlan_mode: %d\n", pwrpriv->wowlan_mode);
962
963         if ((pwrpriv->bSupportRemoteWakeup == _TRUE) &&
964                 (pwrpriv->wowlan_mode == _TRUE))
965         {
966                 if (rtw_port_switch_chk(padapter))
967                         rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
968
969                 poidparam.subcode = WOWLAN_ENABLE;
970                 padapter->HalFunc.SetHwRegHandler(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam);
971         }
972         else
973 #endif // CONFIG_WOWLAN
974         {
975         //s2-1.  issue rtw_disassoc_cmd to fw
976                 rtw_disassoc_cmd(padapter, 0, _FALSE);
977         }
978
979         if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) {
980                 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)
981                         && check_fwstate(pmlmepriv, _FW_LINKED))
982                 {
983                         DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__,
984                                         pmlmepriv->cur_network.network.Ssid.Ssid,
985                                         MAC_ARG(pmlmepriv->cur_network.network.MacAddress),
986                                         pmlmepriv->cur_network.network.Ssid.SsidLength,
987                                         pmlmepriv->assoc_ssid.SsidLength);
988                         #ifdef CONFIG_WOWLAN
989                         if (pwrpriv->wowlan_mode != _TRUE)
990                                 rtw_set_to_roam(padapter, 1);
991                         else
992                                 rtw_set_to_roam(padapter, 0);
993                         #else // !CONFIG_WOWLAN
994                         rtw_set_to_roam(padapter, 1);
995                         #endif // !CONFIG_WOWLAN
996                 }
997         }
998
999 #ifdef CONFIG_WOWLAN
1000         if (pwrpriv->wowlan_mode == _TRUE)
1001         {
1002                 DBG_871X_LEVEL(_drv_always_, "%s: wowmode suspending\n", __func__);
1003
1004                 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
1005                 {
1006                         DBG_871X_LEVEL(_drv_always_, "%s: fw_under_survey\n", __func__);
1007                         rtw_indicate_scan_done(padapter, 1);
1008                         clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
1009                 }
1010                 
1011                 if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) {
1012                         DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
1013                                 FUNC_ADPT_ARG(padapter), ch, bw, offset);
1014                         set_channel_bwmode(padapter, ch, offset, bw);
1015                 }
1016
1017 #ifdef CONFIG_POWER_SAVING
1018 #ifdef CONFIG_PNO_SUPPORT
1019                 if(pwrpriv->wowlan_pno_enable)
1020                         DBG_871X_LEVEL(_drv_always_, "%s: pno: %d\n", __func__, pwrpriv->wowlan_pno_enable);
1021                 else
1022 #endif //CONFIG_PNO_SUPPORT
1023                         rtw_set_ps_mode(padapter, PS_MODE_SELF_DEFINED, 0, 0);
1024 #endif
1025         }
1026         else
1027 #endif // CONFIG_WOWLAN
1028         {
1029                 //s2-2.  indicate disconnect to os
1030                 rtw_indicate_disconnect(padapter);
1031                 //s2-3.
1032                 rtw_free_assoc_resources(padapter, 1);
1033                 //s2-4.
1034                 rtw_free_network_queue(padapter, _TRUE);
1035                 //s2-5 dev unload and stop thread
1036                 rtw_dev_unload(padapter);
1037
1038                 if ((rtw_hal_check_ips_status(padapter) == _TRUE)
1039                         || (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off))
1040                 {
1041                         DBG_871X_LEVEL(_drv_always_, "%s: driver in IPS\n", __FUNCTION__);
1042                         LeaveAllPowerSaveMode(padapter);
1043                         DBG_871X_LEVEL(_drv_always_, "%s: driver not in IPS\n", __FUNCTION__);
1044                 }
1045
1046                 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
1047                 {
1048                         DBG_871X_LEVEL(_drv_always_, "%s: fw_under_survey\n", __FUNCTION__);
1049                         rtw_indicate_scan_done(padapter, 1);
1050                 }
1051
1052                 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
1053                 {
1054                         DBG_871X_LEVEL(_drv_always_, "%s: fw_under_linking\n", __FUNCTION__);
1055                         rtw_indicate_disconnect(padapter);
1056                 }
1057
1058                 // interface deinit
1059                 sdio_deinit(adapter_to_dvobj(padapter));
1060         }
1061
1062         DBG_871X_LEVEL(_drv_always_, "sdio suspend success in %d ms\n",
1063                         rtw_get_passing_time_ms(start_time));
1064
1065 exit:
1066
1067 #ifdef CONFIG_RTW_SDIO_PM_KEEP_POWER  
1068         //Android 4.0 don't support WIFI close power
1069         //or power down or clock will close after wifi resume,
1070         //this is sprd's bug in Android 4.0, but sprd don't
1071         //want to fix it.
1072         //we have test power under 8723as, power consumption is ok
1073         if (func) {
1074                 mmc_pm_flag_t pm_flag = 0;
1075                 pm_flag = sdio_get_host_pm_caps(func);
1076                 DBG_871X("cmd: %s: suspend: PM flag = 0x%x\n", sdio_func_id(func), pm_flag);
1077                 if (!(pm_flag & MMC_PM_KEEP_POWER)) {
1078                         DBG_871X("%s: cannot remain alive while host is suspended\n", sdio_func_id(func));
1079                         pdbgpriv->dbg_suspend_error_cnt++;
1080                         return -ENOSYS;
1081                 } else {
1082                         DBG_871X("cmd: suspend with MMC_PM_KEEP_POWER\n");
1083                         sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
1084                 }
1085         }
1086 #endif
1087
1088         DBG_871X("<===  %s return %d.............. in %dms\n", __FUNCTION__
1089                 , ret, rtw_get_passing_time_ms(start_time));
1090
1091         _func_exit_;
1092         return ret;
1093 }
1094
1095
1096
1097 int rtw_resume_process(_adapter *padapter)
1098 {
1099         struct net_device *pnetdev;
1100         struct pwrctrl_priv *pwrpriv = NULL;
1101         u8 is_pwrlock_hold_by_caller;
1102         u8 is_directly_called_by_auto_resume;
1103         int ret = 0;
1104         u32 start_time = rtw_get_current_time();
1105         struct dvobj_priv *psdpriv = padapter->dvobj;
1106         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1107 #ifdef CONFIG_WOWLAN
1108         u32 value = 0;
1109         struct wowlan_ioctl_param poidparam;
1110         struct sta_info *psta = NULL;
1111 #endif // CONFIG_WOWLAN
1112
1113         _func_enter_;
1114
1115         DBG_871X_LEVEL(_drv_always_, "sdio resume start\n");
1116         DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
1117
1118         if (padapter) {
1119                 pnetdev = padapter->pnetdev;
1120                 pwrpriv = adapter_to_pwrctl(padapter);
1121         } else {
1122                 pdbgpriv->dbg_resume_error_cnt++;
1123                 ret = -1;
1124                 goto exit;
1125         }
1126         
1127         if (pwrpriv->bInSuspend == _FALSE)
1128         {
1129                 ret = -1;
1130                 pdbgpriv->dbg_resume_error_cnt++;
1131                 DBG_871X("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend);
1132                 goto exit;
1133         }
1134
1135 #ifdef CONFIG_PNO_SUPPORT
1136         pwrpriv->pno_in_resume = _TRUE;
1137 #endif
1138
1139 #ifdef CONFIG_WOWLAN
1140         if (pwrpriv->wowlan_mode == _FALSE){
1141
1142         // interface init
1143         if (sdio_init(adapter_to_dvobj(padapter)) != _SUCCESS)
1144         {
1145                 ret = -1;
1146                 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!!\n", __FUNCTION__));
1147                 goto exit;
1148         }
1149
1150         rtw_hal_disable_interrupt(padapter);
1151
1152                 if (padapter->HalFunc.clear_interrupt)
1153                         padapter->HalFunc.clear_interrupt(padapter);
1154
1155         if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)
1156         {
1157                 ret = -1;
1158                 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __FUNCTION__));
1159                 goto exit;
1160         }
1161
1162         rtw_reset_drv_sw(padapter);
1163         pwrpriv->bkeepfwalive = _FALSE;
1164
1165         DBG_871X("bkeepfwalive(%x)\n",pwrpriv->bkeepfwalive);
1166
1167         if(pm_netdev_open(pnetdev,_TRUE) != 0) {
1168                 ret = -1;
1169                 pdbgpriv->dbg_resume_error_cnt++;
1170                 goto exit;
1171         }
1172
1173         netif_device_attach(pnetdev);   
1174         netif_carrier_on(pnetdev);
1175         } else {
1176
1177 #ifdef CONFIG_POWER_SAVING
1178 #ifdef CONFIG_LPS
1179                 rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "WOWLAN");
1180 #endif //CONFIG_LPS
1181 #endif
1182
1183                 pwrpriv->bFwCurrentInPSMode = _FALSE;
1184
1185                 rtw_hal_disable_interrupt(padapter);
1186
1187                 if (padapter->HalFunc.clear_interrupt)
1188                         padapter->HalFunc.clear_interrupt(padapter);
1189
1190                 if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) {
1191                         ret = -1;
1192                         RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __FUNCTION__));
1193                         goto exit;
1194                 }
1195
1196                 //Disable WOW, set H2C command
1197                 poidparam.subcode=WOWLAN_DISABLE;
1198                 padapter->HalFunc.SetHwRegHandler(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam);
1199
1200                 psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
1201                 if (psta) {
1202                         set_sta_rate(padapter, psta);
1203                 }
1204
1205                 padapter->bDriverStopped = _FALSE;
1206                 DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped);
1207                 rtw_start_drv_threads(padapter);
1208
1209 #ifdef CONFIG_CONCURRENT_MODE
1210                 if (padapter->pbuddy_adapter)
1211                 {
1212                         padapter->pbuddy_adapter->bDriverStopped = _FALSE;
1213                         DBG_871X("%s: wowmode resuming, pbuddy_adapter->DriverStopped:%d\n",
1214                                 __FUNCTION__, padapter->pbuddy_adapter->bDriverStopped);
1215                         rtw_start_drv_threads(padapter->pbuddy_adapter);
1216                 }
1217 #endif // CONFIG_CONCURRENT_MODE
1218
1219                 rtw_hal_enable_interrupt(padapter);
1220
1221                 // start netif queue
1222                 if (pnetdev) {
1223                         if(!rtw_netif_queue_stopped(pnetdev))
1224                                 rtw_netif_start_queue(pnetdev);
1225                         else 
1226                                 rtw_netif_wake_queue(pnetdev);
1227                 }
1228         }
1229 #else //!CONFIG_WOWLAN
1230
1231                 // interface init
1232                 if (sdio_init(adapter_to_dvobj(padapter)) != _SUCCESS)
1233                 {
1234                         ret = -1;
1235                         RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!!\n", __FUNCTION__));
1236                         goto exit;
1237                 }
1238                 rtw_hal_disable_interrupt(padapter);
1239                 if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)
1240                 {
1241                         ret = -1;
1242                         RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __FUNCTION__));
1243                         goto exit;
1244                 }
1245
1246                 rtw_reset_drv_sw(padapter);
1247                 pwrpriv->bkeepfwalive = _FALSE;
1248
1249                 DBG_871X("bkeepfwalive(%x)\n",pwrpriv->bkeepfwalive);
1250                 if(pm_netdev_open(pnetdev,_TRUE) != 0) {
1251                         ret = -1;
1252                         pdbgpriv->dbg_resume_error_cnt++;
1253                         goto exit;
1254                 }
1255
1256                 netif_device_attach(pnetdev);
1257                 netif_carrier_on(pnetdev);
1258 #endif
1259         if( padapter->pid[1]!=0) {
1260                 DBG_871X("pid[1]:%d\n",padapter->pid[1]);
1261                 rtw_signal_process(padapter->pid[1], SIGUSR2);
1262         }       
1263
1264         if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) {
1265 #ifdef CONFIG_WOWLAN
1266                 if (pwrpriv->wowlan_wake_reason == FWDecisionDisconnect ||
1267                         pwrpriv->wowlan_wake_reason == Rx_DisAssoc ||
1268                         pwrpriv->wowlan_wake_reason == Rx_DeAuth) {
1269
1270                         DBG_871X("%s: disconnect reason: %02x\n", __func__,
1271                                                 pwrpriv->wowlan_wake_reason);
1272                         rtw_indicate_disconnect(padapter);
1273                         rtw_sta_media_status_rpt(padapter, rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)), 0);
1274                         rtw_free_assoc_resources(padapter, 1);
1275                 } else {
1276                         DBG_871X("%s: do roaming\n", __func__);
1277                         rtw_roaming(padapter, NULL);
1278                 }
1279 #else
1280                 rtw_roaming(padapter, NULL);
1281 #endif //CONFOG_WOWLAN
1282         }
1283
1284         #ifdef CONFIG_RESUME_IN_WORKQUEUE
1285         rtw_unlock_suspend();
1286         #endif //CONFIG_RESUME_IN_WORKQUEUE
1287
1288 #ifdef CONFIG_WOWLAN
1289         if (pwrpriv->wowlan_wake_reason == Rx_GTK ||
1290                 pwrpriv->wowlan_wake_reason == Rx_DisAssoc ||
1291                 pwrpriv->wowlan_wake_reason == Rx_DeAuth ||
1292                 pwrpriv->wowlan_wake_reason == RX_PNOWakeUp) {
1293                 rtw_lock_ext_suspend_timeout(8000);
1294         }
1295
1296         if (pwrpriv->wowlan_mode == _TRUE) {
1297                 pwrpriv->bips_processing = _FALSE;
1298                 _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000);
1299 #ifndef CONFIG_IPS_CHECK_IN_WD
1300                 rtw_set_pwr_state_check_timer(pwrpriv);
1301 #endif
1302         } else {
1303                 DBG_871X_LEVEL(_drv_always_, "do not reset timer\n");
1304         }
1305
1306         pwrpriv->wowlan_mode =_FALSE;
1307
1308         //clean driver side wake up reason.
1309         pwrpriv->wowlan_wake_reason = 0;
1310 #endif //CONFIG_WOWLAN
1311
1312 #ifdef CONFIG_BT_COEXIST
1313         rtw_btcoex_SuspendNotify(padapter, 0);
1314 #endif // CONFIG_BT_COEXIST
1315
1316 exit:
1317         if (pwrpriv) {
1318                 pwrpriv->bInSuspend = _FALSE;
1319 #ifdef CONFIG_PNO_SUPPORT
1320                 pwrpriv->pno_in_resume = _FALSE;
1321 #endif
1322         }
1323         DBG_871X_LEVEL(_drv_always_, "sdio resume ret:%d in %d ms\n", ret,
1324                 rtw_get_passing_time_ms(start_time));
1325
1326         _func_exit_;
1327         
1328         return ret;
1329 }
1330
1331
1332 #endif
1333 static int rtw_sdio_resume(struct device *dev)
1334 {
1335         struct sdio_func *func =dev_to_sdio_func(dev);
1336         struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
1337         struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv);
1338         _adapter *padapter = psdpriv->if1;
1339         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1340         int ret = 0;
1341         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1342
1343         DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
1344         pdbgpriv->dbg_resume_cnt++;
1345
1346         if(pwrpriv->bInternalAutoSuspend)
1347         {
1348                 ret = rtw_resume_process(padapter);
1349         }
1350         else
1351         {
1352                 if(pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode)
1353                 {
1354                         rtw_resume_lock_suspend();
1355                         ret = rtw_resume_process(padapter);
1356                         rtw_resume_unlock_suspend();
1357                 }
1358                 else
1359                 {
1360 #ifdef CONFIG_RESUME_IN_WORKQUEUE
1361                         rtw_resume_in_workqueue(pwrpriv);
1362 #else
1363                         if (rtw_is_earlysuspend_registered(pwrpriv))
1364                         {
1365                                 /* jeff: bypass resume here, do in late_resume */
1366                                 rtw_set_do_late_resume(pwrpriv, _TRUE);
1367                         }
1368                         else
1369                         {
1370                                 rtw_resume_lock_suspend();
1371                                 ret = rtw_resume_process(padapter);
1372                                 rtw_resume_unlock_suspend();
1373                         }
1374 #endif
1375                 }
1376         }
1377
1378         pmlmeext->last_scan_time = rtw_get_current_time();
1379         DBG_871X("<========  %s return %d\n", __FUNCTION__, ret);
1380         return ret;
1381
1382 }
1383
1384 static int rtw_drv_entry(void)
1385 {
1386         int ret = 0;
1387
1388
1389         DBG_871X_LEVEL(_drv_always_, "module init start\n");
1390         dump_drv_version(RTW_DBGDUMP);
1391 #ifdef BTCOEXVERSION
1392         DBG_871X_LEVEL(_drv_always_, DRV_NAME" BT-Coex version = %s\n", BTCOEXVERSION);
1393 #endif // BTCOEXVERSION
1394
1395         ret = platform_wifi_power_on();
1396         if (ret)
1397         {
1398                 DBG_871X("%s: power on failed!!(%d)\n", __FUNCTION__, ret);
1399                 ret = -1;
1400                 goto exit;
1401         }
1402
1403         sdio_drvpriv.drv_registered = _TRUE;
1404         rtw_suspend_lock_init();
1405         rtw_drv_proc_init();
1406         rtw_ndev_notifier_register();
1407
1408         ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv);
1409         if (ret != 0)
1410         {
1411                 sdio_drvpriv.drv_registered = _FALSE;
1412                 rtw_suspend_lock_uninit();
1413                 rtw_drv_proc_deinit();
1414                 rtw_ndev_notifier_unregister();
1415                 DBG_871X("%s: register driver failed!!(%d)\n", __FUNCTION__, ret);
1416                 goto poweroff;
1417         }
1418
1419         rtw_android_wifictrl_func_add();
1420
1421         goto exit;
1422
1423 poweroff:
1424         platform_wifi_power_off();
1425
1426 exit:
1427         DBG_871X_LEVEL(_drv_always_, "module init ret=%d\n", ret);
1428         return ret;
1429 }
1430
1431 static void rtw_drv_halt(void)
1432 {
1433         DBG_871X_LEVEL(_drv_always_, "module exit start\n");
1434
1435         sdio_drvpriv.drv_registered = _FALSE;
1436
1437         sdio_unregister_driver(&sdio_drvpriv.r871xs_drv);
1438
1439         rtw_android_wifictrl_func_del();
1440
1441         platform_wifi_power_off();
1442
1443         rtw_suspend_lock_uninit();
1444         rtw_drv_proc_deinit();
1445         rtw_ndev_notifier_unregister();
1446
1447         DBG_871X_LEVEL(_drv_always_, "module exit success\n");
1448
1449         rtw_mstat_dump(RTW_DBGDUMP);
1450 }
1451
1452 #include "wifi_version.h"
1453 #include <linux/rfkill-wlan.h>
1454
1455 int rockchip_wifi_init_module_rtkwifi(void)
1456 {
1457     printk("\n");
1458     printk("=======================================================\n");
1459     printk("==== Launching Wi-Fi driver! (Powered by Rockchip) ====\n");
1460     printk("=======================================================\n");
1461     printk("Realtek 8189ES/ETV SDIO WiFi driver (Powered by Rockchip,Ver %s) init.\n", RTL8192_DRV_VERSION);
1462     rockchip_wifi_power(1);
1463     rockchip_wifi_set_carddetect(1);
1464
1465     return rtw_drv_entry();
1466 }
1467
1468 void rockchip_wifi_exit_module_rtkwifi(void)
1469 {
1470     printk("\n");
1471     printk("=======================================================\n");
1472     printk("==== Dislaunching Wi-Fi driver! (Powered by Rockchip) ====\n");
1473     printk("=======================================================\n");
1474     printk("Realtek 8189ES/ETV SDIO WiFi driver (Powered by Rockchip,Ver %s) init.\n", RTL8192_DRV_VERSION);
1475     rtw_drv_halt();
1476     rockchip_wifi_set_carddetect(0);
1477     rockchip_wifi_power(0);
1478 }
1479
1480 EXPORT_SYMBOL(rockchip_wifi_init_module_rtkwifi);
1481 EXPORT_SYMBOL(rockchip_wifi_exit_module_rtkwifi);
1482 //module_init(rtw_drv_entry);
1483 //module_exit(rtw_drv_halt);
1484