net: wireless: rockchip_wlan: add rtl8723bs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bs / 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 <hal_data.h>
24 #include <platform_ops.h>
25
26 #ifndef CONFIG_SDIO_HCI
27 #error "CONFIG_SDIO_HCI shall be on!\n"
28 #endif
29
30 #ifdef CONFIG_PLATFORM_INTEL_BYT
31 #ifdef CONFIG_ACPI
32 #include <linux/acpi.h>
33 #include <linux/acpi_gpio.h>
34 #include "rtw_android.h"
35 #endif
36 static int wlan_en_gpio = -1;
37 #endif //CONFIG_PLATFORM_INTEL_BYT
38
39 #ifndef dev_to_sdio_func
40 #define dev_to_sdio_func(d)     container_of(d, struct sdio_func, dev)
41 #endif
42
43 #ifdef CONFIG_WOWLAN
44 static struct mmc_host *mmc_host = NULL;
45 #endif
46
47 static const struct sdio_device_id sdio_ids[] =
48 {
49 #ifdef CONFIG_RTL8723B
50         { SDIO_DEVICE(0x024c, 0xB723),.driver_data = RTL8723B},
51 #endif
52 #ifdef CONFIG_RTL8188E
53         { SDIO_DEVICE(0x024c, 0x8179),.driver_data = RTL8188E},
54 #endif //CONFIG_RTL8188E
55
56 #ifdef CONFIG_RTL8821A
57         { SDIO_DEVICE(0x024c, 0x8821),.driver_data = RTL8821},
58 #endif //CONFIG_RTL8821A
59
60 #ifdef CONFIG_RTL8192E
61         { SDIO_DEVICE(0x024c, 0x818B),.driver_data = RTL8192E},
62 #endif //CONFIG_RTL8192E
63
64 #ifdef CONFIG_RTL8703B
65         { SDIO_DEVICE(0x024c, 0xB703), .driver_data = RTL8703B},
66 #endif
67
68 #ifdef CONFIG_RTL8188F
69         {SDIO_DEVICE(0x024c, 0xF179), .driver_data = RTL8188F},
70 #endif
71
72 #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) /* temporarily add this to accept all sdio wlan id */
73         { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) },
74 #endif
75         { /* end: all zeroes */                         },
76 };
77
78 MODULE_DEVICE_TABLE(sdio, sdio_ids);
79
80 static int rtw_drv_init(struct sdio_func *func, const struct sdio_device_id *id);
81 static void rtw_dev_remove(struct sdio_func *func);
82 static int rtw_sdio_resume(struct device *dev);
83 static int rtw_sdio_suspend(struct device *dev);
84 extern void rtw_dev_unload(PADAPTER padapter);
85
86 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) 
87 static const struct dev_pm_ops rtw_sdio_pm_ops = {
88         .suspend        = rtw_sdio_suspend,
89         .resume = rtw_sdio_resume,
90 };
91 #endif
92         
93 struct sdio_drv_priv {
94         struct sdio_driver r871xs_drv;
95         int drv_registered;
96 };
97
98 static struct sdio_drv_priv sdio_drvpriv = {
99         .r871xs_drv.probe = rtw_drv_init,
100         .r871xs_drv.remove = rtw_dev_remove,
101         .r871xs_drv.name = (char*)DRV_NAME,
102         .r871xs_drv.id_table = sdio_ids,
103         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) 
104         .r871xs_drv.drv = {
105                 .pm = &rtw_sdio_pm_ops,
106         }
107         #endif
108 };
109
110 static void sd_sync_int_hdl(struct sdio_func *func)
111 {
112         struct dvobj_priv *psdpriv;
113
114         psdpriv = sdio_get_drvdata(func);
115
116         if (!psdpriv->padapters[IFACE_ID0]) {
117                 DBG_871X("%s if1 == NULL\n", __func__);
118                 return;
119         }
120
121         rtw_sdio_set_irq_thd(psdpriv, current);
122         sd_int_hdl(psdpriv->padapters[IFACE_ID0]);
123         rtw_sdio_set_irq_thd(psdpriv, NULL);
124 }
125
126 int sdio_alloc_irq(struct dvobj_priv *dvobj)
127 {
128         PSDIO_DATA psdio_data;
129         struct sdio_func *func;
130         int err;
131
132         psdio_data = &dvobj->intf_data;
133         func = psdio_data->func;
134
135         sdio_claim_host(func);
136
137         err = sdio_claim_irq(func, &sd_sync_int_hdl);
138         if (err)
139         {
140                 dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++;
141                 printk(KERN_CRIT "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err);
142         }
143         else
144         {
145                 dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++;
146                 dvobj->irq_alloc = 1;
147         }
148
149         sdio_release_host(func);
150
151         return err?_FAIL:_SUCCESS;
152 }
153
154 void sdio_free_irq(struct dvobj_priv *dvobj)
155 {
156     PSDIO_DATA psdio_data;
157     struct sdio_func *func;
158     int err;
159
160     if (dvobj->irq_alloc) {
161         psdio_data = &dvobj->intf_data;
162         func = psdio_data->func;
163
164         if (func) {
165             sdio_claim_host(func);
166             err = sdio_release_irq(func);
167             if (err)
168             {
169                                 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
170                                 DBG_871X_LEVEL(_drv_err_,"%s: sdio_release_irq FAIL(%d)!\n", __func__, err);
171             }
172             else
173                 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
174             sdio_release_host(func);
175         }
176         dvobj->irq_alloc = 0;
177     }
178 }
179
180 #ifdef CONFIG_GPIO_WAKEUP
181 extern unsigned int oob_irq;
182 extern unsigned int oob_gpio;
183 static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data)
184 {
185         PADAPTER padapter = (PADAPTER)data;
186         DBG_871X_LEVEL(_drv_always_, "gpio_hostwakeup_irq_thread\n");
187         /* Disable interrupt before calling handler */
188         //disable_irq_nosync(oob_irq);
189         rtw_lock_suspend_timeout(HZ/2);
190 #ifdef CONFIG_PLATFORM_ARM_SUN6I
191         return 0;
192 #else
193         return IRQ_HANDLED;
194 #endif
195 }
196
197 static u8 gpio_hostwakeup_alloc_irq(PADAPTER padapter)
198 {
199         int err;
200         u32 status = 0;
201
202         if (oob_irq == 0) {
203                 DBG_871X("oob_irq ZERO!\n");
204                 return _FAIL;
205         }
206
207         DBG_871X("%s : oob_irq = %d\n", __func__, oob_irq);
208
209 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
210         status = IRQF_NO_SUSPEND;
211 #endif
212
213         if (HIGH_ACTIVE)
214                 status |= IRQF_TRIGGER_RISING;
215         else
216                 status |= IRQF_TRIGGER_FALLING;
217
218         err = request_threaded_irq(oob_irq, gpio_hostwakeup_irq_thread, NULL,
219                 status, "rtw_wifi_gpio_wakeup", padapter);
220
221         if (err < 0) {
222                 DBG_871X("Oops: can't allocate gpio irq %d err:%d\n", oob_irq, err);
223                 return _FALSE;
224         } else {
225                 DBG_871X("allocate gpio irq %d ok\n", oob_irq);
226         }
227         
228 #ifndef CONFIG_PLATFORM_ARM_SUN8I       
229         enable_irq_wake(oob_irq);
230 #endif
231         return _SUCCESS;
232 }
233
234 static void gpio_hostwakeup_free_irq(PADAPTER padapter)
235 {
236         wifi_free_gpio(oob_gpio);
237
238         if (oob_irq == 0)
239                 return;
240                 
241 #ifndef CONFIG_PLATFORM_ARM_SUN8I
242         disable_irq_wake(oob_irq);
243 #endif
244         free_irq(oob_irq, padapter);
245 }
246 #endif
247
248 static u32 sdio_init(struct dvobj_priv *dvobj)
249 {
250         PSDIO_DATA psdio_data;
251         struct sdio_func *func;
252         int err;
253
254 _func_enter_;
255
256         psdio_data = &dvobj->intf_data;
257         func = psdio_data->func;
258
259         //3 1. init SDIO bus
260         sdio_claim_host(func);
261
262         err = sdio_enable_func(func);
263         if (err) {
264                 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
265                 DBG_8192C(KERN_CRIT "%s: sdio_enable_func FAIL(%d)!\n", __func__, err);
266                 goto release;
267         }
268
269         err = sdio_set_block_size(func, 512);
270         if (err) {
271                 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
272                 DBG_8192C(KERN_CRIT "%s: sdio_set_block_size FAIL(%d)!\n", __func__, err);
273                 goto release;
274         }
275         psdio_data->block_transfer_len = 512;
276         psdio_data->tx_block_mode = 1;
277         psdio_data->rx_block_mode = 1;
278
279 release:
280         sdio_release_host(func);
281
282 exit:
283 _func_exit_;
284
285         if (err) return _FAIL;
286         return _SUCCESS;
287 }
288
289 static void sdio_deinit(struct dvobj_priv *dvobj)
290 {
291         struct sdio_func *func;
292         int err;
293
294
295         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+sdio_deinit\n"));
296
297         func = dvobj->intf_data.func;
298
299         if (func) {
300                 sdio_claim_host(func);
301                 err = sdio_disable_func(func);
302                 if (err)
303                 {
304                         dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++;
305                         DBG_8192C(KERN_ERR "%s: sdio_disable_func(%d)\n", __func__, err);
306                 }
307
308                 if (dvobj->irq_alloc) {
309                         err = sdio_release_irq(func);
310                         if (err)
311                         {
312                                 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
313                                 DBG_8192C(KERN_ERR "%s: sdio_release_irq(%d)\n", __func__, err);
314                         }
315                         else
316                                 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
317                 }
318
319                 sdio_release_host(func);
320         }
321 }
322
323 static void rtw_decide_chip_type_by_device_id(struct dvobj_priv *dvobj, const struct sdio_device_id  *pdid)
324 {
325         dvobj->chip_type = pdid->driver_data;
326
327 #if defined(CONFIG_RTL8188E)
328         if (dvobj->chip_type == RTL8188E) {
329                 dvobj->HardwareType = HARDWARE_TYPE_RTL8188ES;
330                 DBG_871X("CHIP TYPE: RTL8188E\n");
331         }
332 #endif
333
334 #if defined(CONFIG_RTL8723B)
335         dvobj->chip_type = RTL8723B;
336         dvobj->HardwareType = HARDWARE_TYPE_RTL8723BS;
337 #endif
338
339 #if defined(CONFIG_RTL8821A)
340         if (dvobj->chip_type == RTL8821) {
341                 dvobj->HardwareType = HARDWARE_TYPE_RTL8821S;
342                 DBG_871X("CHIP TYPE: RTL8821A\n");
343         }
344 #endif
345
346 #if defined(CONFIG_RTL8192E)
347         if (dvobj->chip_type == RTL8192E) {
348                 dvobj->HardwareType = HARDWARE_TYPE_RTL8192ES;
349                 DBG_871X("CHIP TYPE: RTL8192E\n");
350         }
351 #endif
352
353 #if defined(CONFIG_RTL8703B)
354         if (dvobj->chip_type == RTL8703B) {
355                 dvobj->HardwareType = HARDWARE_TYPE_RTL8703BS;
356                 DBG_871X("CHIP TYPE: RTL8703B\n");
357         }
358 #endif
359
360 #if defined(CONFIG_RTL8188F)
361         if (dvobj->chip_type == RTL8188F) {
362                 dvobj->HardwareType = HARDWARE_TYPE_RTL8188FS;
363                 DBG_871X("CHIP TYPE: RTL8188F\n");
364         }
365 #endif
366 }
367
368 static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func, const struct sdio_device_id  *pdid)
369 {
370         int status = _FAIL;
371         struct dvobj_priv *dvobj = NULL;
372         PSDIO_DATA psdio;
373 _func_enter_;
374
375         if((dvobj = devobj_init()) == NULL) {
376                 goto exit;
377         }
378
379         sdio_set_drvdata(func, dvobj);
380
381         psdio = &dvobj->intf_data;
382         psdio->func = func;
383
384         if (sdio_init(dvobj) != _SUCCESS) {
385                 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!\n", __FUNCTION__));
386                 goto free_dvobj;
387         }
388
389         dvobj->interface_type = RTW_SDIO;
390         rtw_decide_chip_type_by_device_id(dvobj, pdid);
391
392         rtw_reset_continual_io_error(dvobj);
393         status = _SUCCESS;
394
395 free_dvobj:
396         if (status != _SUCCESS && dvobj) {
397                 sdio_set_drvdata(func, NULL);
398                 
399                 devobj_deinit(dvobj);
400                 
401                 dvobj = NULL;
402         }
403 exit:
404 _func_exit_;
405         return dvobj;
406 }
407
408 static void sdio_dvobj_deinit(struct sdio_func *func)
409 {
410         struct dvobj_priv *dvobj = sdio_get_drvdata(func);
411 _func_enter_;
412
413         sdio_set_drvdata(func, NULL);
414         if (dvobj) {
415                 sdio_deinit(dvobj);
416                 devobj_deinit(dvobj);
417         }
418
419 _func_exit_;
420         return;
421 }
422
423 u8 rtw_set_hal_ops(PADAPTER padapter)
424 {
425         //alloc memory for HAL DATA
426         if(rtw_hal_data_init(padapter) == _FAIL)
427                 return _FAIL;
428
429 #if defined(CONFIG_RTL8188E)
430         if (rtw_get_chip_type(padapter) == RTL8188E)
431                 rtl8188es_set_hal_ops(padapter);
432 #endif
433
434 #if defined(CONFIG_RTL8723B)
435         if (rtw_get_chip_type(padapter) == RTL8723B)
436                 rtl8723bs_set_hal_ops(padapter);
437 #endif
438
439 #if defined(CONFIG_RTL8821A)
440         if (rtw_get_chip_type(padapter) == RTL8821)
441                 rtl8821as_set_hal_ops(padapter);
442 #endif
443
444 #if defined(CONFIG_RTL8192E)
445         if (rtw_get_chip_type(padapter) == RTL8192E)
446                 rtl8192es_set_hal_ops(padapter);
447 #endif
448
449 #if defined(CONFIG_RTL8703B)
450         if (rtw_get_chip_type(padapter) == RTL8703B)
451                 rtl8703bs_set_hal_ops(padapter);
452 #endif
453
454 #if defined(CONFIG_RTL8188F)
455         if (rtw_get_chip_type(padapter) == RTL8188F)
456                 rtl8188fs_set_hal_ops(padapter);
457 #endif
458
459         if( rtw_hal_ops_check(padapter) == _FAIL)
460                 return _FAIL;
461
462         if (hal_spec_init(padapter) == _FAIL)
463                 return _FAIL;
464
465         return _SUCCESS;
466 }
467
468 static void sd_intf_start(PADAPTER padapter)
469 {
470         if (padapter == NULL) {
471                 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
472                 return;
473         }
474
475         // hal dep
476         rtw_hal_enable_interrupt(padapter);
477 }
478
479 static void sd_intf_stop(PADAPTER padapter)
480 {
481         if (padapter == NULL) {
482                 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
483                 return;
484         }
485
486         // hal dep
487         rtw_hal_disable_interrupt(padapter);
488 }
489
490
491 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
492 PADAPTER g_test_adapter = NULL;
493 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
494
495 _adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj)
496 {
497         int status = _FAIL;
498         PADAPTER padapter = NULL;
499
500         padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter));
501         if (padapter == NULL)
502                 goto exit;
503
504         if (loadparam(padapter) != _SUCCESS)
505                 goto free_adapter;
506
507 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
508         g_test_adapter = padapter;
509 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
510         padapter->dvobj = dvobj;
511
512         rtw_set_drv_stopped(padapter);/*init*/
513
514         dvobj->padapters[dvobj->iface_nums++] = padapter;
515         padapter->iface_id = IFACE_ID0;
516
517 #if defined(CONFIG_CONCURRENT_MODE)
518         //set adapter_type/iface type for primary padapter
519         padapter->isprimary = _TRUE;
520         padapter->adapter_type = PRIMARY_ADAPTER;       
521         #ifndef CONFIG_HWPORT_SWAP
522         padapter->iface_type = IFACE_PORT0;
523         #else
524         padapter->iface_type = IFACE_PORT1;
525         #endif
526 #endif
527
528         //3 3. init driver special setting, interface, OS and hardware relative
529
530         //4 3.1 set hardware operation functions
531         if (rtw_set_hal_ops(padapter)== _FAIL)
532                 goto free_hal_data;
533
534         //3 5. initialize Chip version
535         padapter->intf_start = &sd_intf_start;
536         padapter->intf_stop = &sd_intf_stop;
537
538         padapter->intf_init = &sdio_init;
539         padapter->intf_deinit = &sdio_deinit;
540         padapter->intf_alloc_irq = &sdio_alloc_irq;
541         padapter->intf_free_irq = &sdio_free_irq;
542
543         if (rtw_init_io_priv(padapter, sdio_set_intf_ops) == _FAIL)
544         {
545                 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
546                         ("rtw_drv_init: Can't init io_priv\n"));
547                 goto free_hal_data;
548         }
549
550         rtw_hal_read_chip_version(padapter);
551
552         rtw_hal_chip_configure(padapter);
553
554 #ifdef CONFIG_BT_COEXIST
555         rtw_btcoex_Initialize(padapter);
556 #endif // CONFIG_BT_COEXIST
557
558         //3 6. read efuse/eeprom data
559         rtw_hal_read_chip_info(padapter);
560
561         //3 7. init driver common data
562         if (rtw_init_drv_sw(padapter) == _FAIL) {
563                 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
564                          ("rtw_drv_init: Initialize driver software resource Failed!\n"));
565                 goto free_hal_data;
566         }
567
568         //3 8. get WLan MAC address
569         // set mac addr
570         rtw_macaddr_cfg(adapter_mac_addr(padapter),  get_hal_mac_addr(padapter));
571 #ifdef CONFIG_P2P
572         rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));
573 #endif /* CONFIG_P2P */
574
575         rtw_hal_disable_interrupt(padapter);
576
577         DBG_871X("bDriverStopped:%s, bSurpriseRemoved:%s, bup:%d, hw_init_completed:%d\n"
578                 , rtw_is_drv_stopped(padapter)?"True":"False"
579                 , rtw_is_surprise_removed(padapter)?"True":"False"
580                 , padapter->bup
581                 , rtw_get_hw_init_completed(padapter)
582         );
583         
584         status = _SUCCESS;
585         
586 free_hal_data:
587         if (status != _SUCCESS && padapter->HalData)
588                 rtw_hal_free_data(padapter);
589
590 free_adapter:
591         if (status != _SUCCESS && padapter) {
592                 rtw_vmfree((u8 *)padapter, sizeof(*padapter));
593                 padapter = NULL;
594         }
595 exit:
596         return padapter;
597 }
598
599 static void rtw_sdio_if1_deinit(_adapter *if1)
600 {
601         struct mlme_priv *pmlmepriv= &if1->mlmepriv;
602
603         if(check_fwstate(pmlmepriv, _FW_LINKED))
604                 rtw_disassoc_cmd(if1, 0, _FALSE);
605
606 #ifdef CONFIG_AP_MODE
607         free_mlme_ap_info(if1);
608         #ifdef CONFIG_HOSTAPD_MLME
609         hostapd_mode_unload(if1);
610         #endif
611 #endif
612
613 #ifdef CONFIG_GPIO_WAKEUP
614 #ifdef CONFIG_PLATFORM_ARM_SUN6I 
615         sw_gpio_eint_set_enable(gpio_eint_wlan, 0);
616         sw_gpio_irq_free(eint_wlan_handle);
617 #else  
618         gpio_hostwakeup_free_irq(if1);
619 #endif
620 #endif
621
622
623 #ifdef CONFIG_WOWLAN
624         adapter_to_pwrctl(if1)->wowlan_mode=_FALSE;
625         DBG_871X_LEVEL(_drv_always_, "%s wowlan_mode:%d\n", __func__, adapter_to_pwrctl(if1)->wowlan_mode);
626 #endif //CONFIG_WOWLAN
627
628         rtw_dev_unload(if1);
629         DBG_871X("+r871xu_dev_remove, hw_init_completed=%d\n", rtw_get_hw_init_completed(if1));
630
631         rtw_free_drv_sw(if1);
632
633         /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
634         rtw_os_ndev_free(if1);
635
636         rtw_vmfree((u8 *)if1, sizeof(_adapter));
637
638 #ifdef CONFIG_PLATFORM_RTD2880B
639         DBG_871X("wlan link down\n");
640         rtd2885_wlan_netlink_sendMsg("linkdown", "8712");
641 #endif
642
643 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
644         g_test_adapter = NULL;
645 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
646 }
647
648 /*
649  * drv_init() - a device potentially for us
650  *
651  * notes: drv_init() is called when the bus driver has located a card for us to support.
652  *        We accept the new device by returning 0.
653  */
654 static int rtw_drv_init(
655         struct sdio_func *func,
656         const struct sdio_device_id *id)
657 {
658         int status = _FAIL;
659         struct net_device *pnetdev;
660         PADAPTER if1 = NULL, if2 = NULL;
661         struct dvobj_priv *dvobj;
662
663 #ifdef CONFIG_PLATFORM_INTEL_BYT
664
665 #ifdef CONFIG_ACPI
666         acpi_handle handle;
667         struct acpi_device *adev;
668 #endif
669
670 #if defined(CONFIG_ACPI) && defined(CONFIG_GPIO_WAKEUP)
671         handle = ACPI_HANDLE(&func->dev);
672
673         if (handle) {
674                 /* Dont try to do acpi pm for the wifi module */
675                 if (!handle || acpi_bus_get_device(handle, &adev))
676                         DBG_871X("Could not get acpi pointer!\n");
677                 else {
678                         adev->flags.power_manageable = 0;
679                         DBG_871X("Disabling ACPI power management support!\n");
680                 }
681                 oob_gpio = acpi_get_gpio_by_index(&func->dev, 0, NULL);
682                 DBG_871X("rtw_drv_init: ACPI_HANDLE found oob_gpio %d!\n", oob_gpio);
683                 wifi_configure_gpio();
684         }
685         else
686                 DBG_871X("rtw_drv_init: ACPI_HANDLE NOT found!\n");
687 #endif
688
689 #if defined(CONFIG_ACPI)
690         if (&func->dev && ACPI_HANDLE(&func->dev)) {
691                 wlan_en_gpio = acpi_get_gpio_by_index(&func->dev, 1, NULL);
692                 DBG_871X("rtw_drv_init: ACPI_HANDLE found wlan_en %d!\n", wlan_en_gpio);
693         }
694         else
695                 DBG_871X("rtw_drv_init: ACPI_HANDLE NOT found!\n");
696 #endif
697 #endif //CONFIG_PLATFORM_INTEL_BYT
698
699
700         RT_TRACE(_module_hci_intfs_c_, _drv_info_,
701                 ("+rtw_drv_init: vendor=0x%04x device=0x%04x class=0x%02x\n",
702                 func->vendor, func->device, func->class));
703
704         if ((dvobj = sdio_dvobj_init(func, id)) == NULL) {
705                 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n"));
706                 goto exit;
707         }
708
709         if ((if1 = rtw_sdio_if1_init(dvobj)) == NULL) {
710                 DBG_871X("rtw_init_primary_adapter Failed!\n");
711                 goto free_dvobj;
712         }
713
714 #ifdef CONFIG_CONCURRENT_MODE
715         if ((if2 = rtw_drv_if2_init(if1, sdio_set_intf_ops)) == NULL) {
716                 goto free_if1;
717         }
718 #endif
719
720         //dev_alloc_name && register_netdev
721         if (rtw_os_ndevs_init(dvobj) != _SUCCESS)
722                 goto free_if2;
723
724 #ifdef CONFIG_HOSTAPD_MLME
725         hostapd_mode_init(if1);
726 #endif
727
728 #ifdef CONFIG_PLATFORM_RTD2880B
729         DBG_871X("wlan link up\n");
730         rtd2885_wlan_netlink_sendMsg("linkup", "8712");
731 #endif
732
733         if (sdio_alloc_irq(dvobj) != _SUCCESS)
734                 goto os_ndevs_deinit;
735
736 #ifdef  CONFIG_GPIO_WAKEUP
737 #ifdef CONFIG_PLATFORM_ARM_SUN6I
738         eint_wlan_handle = sw_gpio_irq_request(gpio_eint_wlan, TRIG_EDGE_NEGATIVE,(peint_handle)gpio_hostwakeup_irq_thread, NULL);
739         if (!eint_wlan_handle) {
740                DBG_871X( "%s: request irq failed\n",__func__);
741                return -1;
742   }
743 #else
744         gpio_hostwakeup_alloc_irq(if1);
745 #endif
746 #endif
747
748 #ifdef CONFIG_GLOBAL_UI_PID
749         if(ui_pid[1]!=0) {
750                 DBG_871X("ui_pid[1]:%d\n",ui_pid[1]);
751                 rtw_signal_process(ui_pid[1], SIGUSR2);
752         }
753 #endif
754
755         RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-871x_drv - drv_init, success!\n"));
756
757         status = _SUCCESS;
758
759 os_ndevs_deinit:
760         if (status != _SUCCESS)
761                 rtw_os_ndevs_deinit(dvobj);
762 free_if2:
763         if(status != _SUCCESS && if2) {
764                 #ifdef CONFIG_CONCURRENT_MODE
765                 rtw_drv_if2_stop(if2);
766                 rtw_drv_if2_free(if2);
767                 #endif
768         }
769 free_if1:
770         if (status != _SUCCESS && if1) {
771                 rtw_sdio_if1_deinit(if1);
772         }
773 free_dvobj:
774         if (status != _SUCCESS)
775                 sdio_dvobj_deinit(func);
776 exit:
777         return status == _SUCCESS?0:-ENODEV;
778 }
779
780 static void rtw_dev_remove(struct sdio_func *func)
781 {
782         struct dvobj_priv *dvobj = sdio_get_drvdata(func);
783         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
784         PADAPTER padapter = dvobj->padapters[IFACE_ID0];
785
786 _func_enter_;
787
788         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+rtw_dev_remove\n"));
789
790         dvobj->processing_dev_remove = _TRUE;
791
792         /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
793         rtw_os_ndevs_unregister(dvobj);
794
795         if (!rtw_is_surprise_removed(padapter)) {
796                 int err;
797
798                 /* test surprise remove */
799                 sdio_claim_host(func);
800                 sdio_readb(func, 0, &err);
801                 sdio_release_host(func);
802                 if (err == -ENOMEDIUM) {
803                         rtw_set_surprise_removed(padapter);
804                         DBG_871X(KERN_NOTICE "%s: device had been removed!\n", __func__);
805                 }
806         }
807
808 #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
809         rtw_unregister_early_suspend(pwrctl);
810 #endif
811
812         if (padapter->bFWReady == _TRUE) {
813                 rtw_ps_deny(padapter, PS_DENY_DRV_REMOVE);
814                 rtw_pm_set_ips(padapter, IPS_NONE);
815                 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
816                 LeaveAllPowerSaveMode(padapter);
817         }
818         rtw_set_drv_stopped(padapter);  /*for stop thread*/
819
820         /* stop cmd thread */
821         rtw_stop_cmd_thread(padapter);
822 #ifdef CONFIG_CONCURRENT_MODE
823         rtw_drv_if2_stop(dvobj->padapters[IFACE_ID1]);
824 #endif
825
826 #ifdef CONFIG_BT_COEXIST
827         #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
828         if (GET_HAL_DATA(padapter)->EEPROMBluetoothCoexist)
829                 rtw_btcoex_close_socket(padapter);
830         #endif
831         rtw_btcoex_HaltNotify(padapter);
832 #endif
833
834         rtw_sdio_if1_deinit(padapter);
835
836 #ifdef CONFIG_CONCURRENT_MODE
837         rtw_drv_if2_free(dvobj->padapters[IFACE_ID1]);
838 #endif
839
840         sdio_dvobj_deinit(func);
841
842         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-rtw_dev_remove\n"));
843
844 _func_exit_;
845 }
846 extern int pm_netdev_open(struct net_device *pnetdev,u8 bnormal);
847 extern int pm_netdev_close(struct net_device *pnetdev,u8 bnormal);
848
849 static int rtw_sdio_suspend(struct device *dev)
850 {
851         struct sdio_func *func =dev_to_sdio_func(dev);
852         struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
853         struct pwrctrl_priv *pwrpriv = NULL;
854         _adapter *padapter = NULL;
855         struct debug_priv *pdbgpriv = NULL;
856         int ret = 0;
857         u8 ch, bw, offset;
858
859         if (psdpriv == NULL)
860                 goto exit;
861
862         pwrpriv = dvobj_to_pwrctl(psdpriv);
863         padapter = psdpriv->padapters[IFACE_ID0];
864         pdbgpriv = &psdpriv->drv_dbg;
865         if (rtw_is_drv_stopped(padapter)) {
866                 DBG_871X("%s bDriverStopped == _TRUE\n", __func__);
867                 goto exit;
868         }
869
870         if (pwrpriv->bInSuspend == _TRUE)
871         {
872                 DBG_871X("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend);
873                 pdbgpriv->dbg_suspend_error_cnt++;
874                 goto exit;
875         }
876
877         ret = rtw_suspend_common(padapter);             
878
879 exit:
880 #ifdef CONFIG_RTW_SDIO_PM_KEEP_POWER 
881 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
882         //Android 4.0 don't support WIFI close power
883         //or power down or clock will close after wifi resume,
884         //this is sprd's bug in Android 4.0, but sprd don't
885         //want to fix it.
886         //we have test power under 8723as, power consumption is ok
887         if (func) {
888                 mmc_pm_flag_t pm_flag = 0;
889                 pm_flag = sdio_get_host_pm_caps(func);
890                 DBG_871X("cmd: %s: suspend: PM flag = 0x%x\n", sdio_func_id(func), pm_flag);
891                 if (!(pm_flag & MMC_PM_KEEP_POWER)) {
892                         DBG_871X("%s: cannot remain alive while host is suspended\n", sdio_func_id(func));
893                         if (pdbgpriv)
894                                 pdbgpriv->dbg_suspend_error_cnt++;
895                         return -ENOSYS;
896                 } else {
897                         DBG_871X("cmd: suspend with MMC_PM_KEEP_POWER\n");
898                         sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
899                 }
900         }
901 #endif  
902 #endif
903         return ret;
904 }
905 int rtw_resume_process(_adapter *padapter)
906 {
907         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
908         struct dvobj_priv *psdpriv = padapter->dvobj;
909         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
910                 
911         if (pwrpriv->bInSuspend == _FALSE)
912         {
913                 pdbgpriv->dbg_resume_error_cnt++;
914                 DBG_871X("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend);
915                 return -1;
916         }
917         
918         return rtw_resume_common(padapter);
919 }
920
921 static int rtw_sdio_resume(struct device *dev)
922 {
923         struct sdio_func *func =dev_to_sdio_func(dev);
924         struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
925         struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv);
926         _adapter *padapter = psdpriv->padapters[IFACE_ID0];
927         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
928         int ret = 0;
929         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
930
931         DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
932
933         pdbgpriv->dbg_resume_cnt++;
934
935         if(pwrpriv->bInternalAutoSuspend)
936         {
937                 ret = rtw_resume_process(padapter);
938         }
939         else
940         {
941 #ifdef CONFIG_PLATFORM_INTEL_BYT
942                 if(0)
943 #else
944                 if(pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode)
945 #endif
946                 {
947                         rtw_resume_lock_suspend();                      
948                         ret = rtw_resume_process(padapter);
949                         rtw_resume_unlock_suspend();
950                 }
951                 else
952                 {
953 #ifdef CONFIG_RESUME_IN_WORKQUEUE
954                         rtw_resume_in_workqueue(pwrpriv);
955 #else                   
956                         if (rtw_is_earlysuspend_registered(pwrpriv))
957                         {
958                                 /* jeff: bypass resume here, do in late_resume */
959                                 rtw_set_do_late_resume(pwrpriv, _TRUE);
960                         }       
961                         else
962                         {
963                                 rtw_resume_lock_suspend();                      
964                                 ret = rtw_resume_process(padapter);
965                                 rtw_resume_unlock_suspend();
966                         }
967 #endif
968                 }
969         }
970         pmlmeext->last_scan_time = rtw_get_current_time();
971         DBG_871X("<========  %s return %d\n", __FUNCTION__, ret);
972         return ret;
973
974 }
975
976 static int rtw_drv_entry(void)
977 {
978         int ret = 0;
979
980         DBG_871X_LEVEL(_drv_always_, "module init start\n");
981         dump_drv_version(RTW_DBGDUMP);
982 #ifdef BTCOEXVERSION
983         DBG_871X_LEVEL(_drv_always_, DRV_NAME" BT-Coex version = %s\n", BTCOEXVERSION);
984 #endif // BTCOEXVERSION
985
986         ret = platform_wifi_power_on();
987         if (ret)
988         {
989                 DBG_871X("%s: power on failed!!(%d)\n", __FUNCTION__, ret);
990                 ret = -1;
991                 goto exit;
992         }
993
994         sdio_drvpriv.drv_registered = _TRUE;
995         rtw_suspend_lock_init();
996         rtw_drv_proc_init();
997         rtw_ndev_notifier_register();
998
999         ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv);
1000         if (ret != 0)
1001         {
1002                 sdio_drvpriv.drv_registered = _FALSE;
1003                 rtw_suspend_lock_uninit();
1004                 rtw_drv_proc_deinit();
1005                 rtw_ndev_notifier_unregister();
1006                 DBG_871X("%s: register driver failed!!(%d)\n", __FUNCTION__, ret);
1007                 goto poweroff;
1008         }
1009
1010 #ifndef CONFIG_PLATFORM_INTEL_BYT
1011         rtw_android_wifictrl_func_add();
1012 #endif //!CONFIG_PLATFORM_INTEL_BYT
1013         goto exit;
1014
1015 poweroff:
1016         platform_wifi_power_off();
1017
1018 exit:
1019         DBG_871X_LEVEL(_drv_always_, "module init ret=%d\n", ret);
1020         return ret;
1021 }
1022
1023 static void rtw_drv_halt(void)
1024 {
1025         DBG_871X_LEVEL(_drv_always_, "module exit start\n");
1026
1027         sdio_drvpriv.drv_registered = _FALSE;
1028
1029         sdio_unregister_driver(&sdio_drvpriv.r871xs_drv);
1030
1031         rtw_android_wifictrl_func_del();
1032
1033         platform_wifi_power_off();
1034
1035         rtw_suspend_lock_uninit();
1036         rtw_drv_proc_deinit();
1037         rtw_ndev_notifier_unregister();
1038
1039         DBG_871X_LEVEL(_drv_always_, "module exit success\n");
1040
1041         rtw_mstat_dump(RTW_DBGDUMP);
1042 }
1043
1044 #ifdef CONFIG_PLATFORM_INTEL_BYT
1045 int rtw_sdio_set_power(int on)
1046 {
1047
1048         if(wlan_en_gpio >= 0){
1049                 if(on)
1050                         gpio_set_value(wlan_en_gpio,1);
1051                 else
1052                         gpio_set_value(wlan_en_gpio,0);
1053         }
1054
1055         return 0;
1056 }
1057 #endif //CONFIG_PLATFORM_INTEL_BYT
1058
1059 #include <linux/rfkill-wlan.h>
1060 extern int get_wifi_chip_type(void);
1061 extern int rockchip_wifi_power(int on);
1062 extern int rockchip_wifi_set_carddetect(int val);
1063
1064 int rockchip_wifi_init_module_rtkwifi(void)
1065 {
1066 #ifdef CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
1067     int type = get_wifi_chip_type();
1068     if (type < WIFI_AP6XXX_SERIES || type == WIFI_ESP8089) return 0;
1069 #endif
1070     printk("\n");
1071     printk("=======================================================\n");
1072     printk("==== Launching Wi-Fi driver! (Powered by Rockchip) ====\n");
1073     printk("=======================================================\n");
1074     printk("Realtek 8723BS SDIO WiFi driver (Powered by Rockchip,Ver %s) init.\n", DRIVERVERSION);
1075
1076     rockchip_wifi_power(1);
1077     rockchip_wifi_set_carddetect(1);
1078
1079     return rtw_drv_entry();
1080 }
1081
1082 void rockchip_wifi_exit_module_rtkwifi(void)
1083 {
1084 #ifdef CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
1085     int type = get_wifi_chip_type();
1086     if (type < WIFI_AP6XXX_SERIES || type == WIFI_ESP8089) return;
1087 #endif
1088     printk("\n");
1089     printk("=======================================================\n");
1090     printk("==== Dislaunching Wi-Fi driver! (Powered by Rockchip) ====\n");
1091     printk("=======================================================\n");
1092     printk("Realtek 8723BS SDIO WiFi driver (Powered by Rockchip,Ver %s) init.\n", DRIVERVERSION);
1093
1094     rtw_drv_halt();
1095
1096     rockchip_wifi_set_carddetect(0);
1097     rockchip_wifi_power(0);
1098 }
1099
1100 #ifdef CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
1101 late_initcall(rockchip_wifi_init_module_rtkwifi);
1102 module_exit(rockchip_wifi_exit_module_rtkwifi);
1103 #else
1104 EXPORT_SYMBOL(rockchip_wifi_init_module_rtkwifi);
1105 EXPORT_SYMBOL(rockchip_wifi_exit_module_rtkwifi);
1106 #endif
1107 //module_init(rtw_drv_entry);
1108 //module_exit(rtw_drv_halt);
1109