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