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