1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
22 #include <drv_types.h>
24 #include <platform_ops.h>
26 #ifndef CONFIG_SDIO_HCI
27 #error "CONFIG_SDIO_HCI shall be on!\n"
30 #ifdef CONFIG_RTL8822B
31 #include <rtl8822b_hal.h> /* rtl8822bs_set_hal_ops() */
32 #endif /* CONFIG_RTL8822B */
34 #ifdef CONFIG_PLATFORM_INTEL_BYT
36 #include <linux/acpi.h>
37 #include <linux/acpi_gpio.h>
38 #include "rtw_android.h"
40 static int wlan_en_gpio = -1;
41 #endif /* CONFIG_PLATFORM_INTEL_BYT */
43 #ifndef dev_to_sdio_func
44 #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev)
48 static struct mmc_host *mmc_host = NULL;
51 static const struct sdio_device_id sdio_ids[] = {
52 #ifdef CONFIG_RTL8723B
53 { SDIO_DEVICE(0x024c, 0xB723), .driver_data = RTL8723B},
55 #ifdef CONFIG_RTL8188E
56 { SDIO_DEVICE(0x024c, 0x8179), .driver_data = RTL8188E},
57 #endif /* CONFIG_RTL8188E */
59 #ifdef CONFIG_RTL8821A
60 { SDIO_DEVICE(0x024c, 0x8821), .driver_data = RTL8821},
61 #endif /* CONFIG_RTL8821A */
63 #ifdef CONFIG_RTL8192E
64 { SDIO_DEVICE(0x024c, 0x818B), .driver_data = RTL8192E},
65 #endif /* CONFIG_RTL8192E */
67 #ifdef CONFIG_RTL8703B
68 { SDIO_DEVICE(0x024c, 0xB703), .driver_data = RTL8703B},
71 #ifdef CONFIG_RTL8188F
72 {SDIO_DEVICE(0x024c, 0xF179), .driver_data = RTL8188F},
74 #ifdef CONFIG_RTL8822B
75 {SDIO_DEVICE(0x024c, 0xB822), .driver_data = RTL8822B},
78 #ifdef CONFIG_RTL8723D
79 { SDIO_DEVICE(0x024c, 0xD723), .driver_data = RTL8723D},
80 { SDIO_DEVICE(0x024c, 0xD724), .driver_data = RTL8723D},
83 #ifdef CONFIG_RTL8821C
84 {SDIO_DEVICE(0x024C, 0xB821), .driver_data = RTL8821C},
85 {SDIO_DEVICE(0x024C, 0xC821), .driver_data = RTL8821C},
88 #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) /* temporarily add this to accept all sdio wlan id */
89 { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) },
91 { /* end: all zeroes */ },
94 MODULE_DEVICE_TABLE(sdio, sdio_ids);
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);
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,
109 struct sdio_drv_priv {
110 struct sdio_driver r871xs_drv;
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))
121 .pm = &rtw_sdio_pm_ops,
126 static struct rtw_if_operations sdio_ops = {
127 .read = rtw_sdio_raw_read,
128 .write = rtw_sdio_raw_write,
131 static void sd_sync_int_hdl(struct sdio_func *func)
133 struct dvobj_priv *psdpriv;
135 psdpriv = sdio_get_drvdata(func);
137 if (!dvobj_get_primary_adapter(psdpriv)) {
138 RTW_INFO("%s primary adapter == NULL\n", __func__);
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);
147 int sdio_alloc_irq(struct dvobj_priv *dvobj)
149 PSDIO_DATA psdio_data;
150 struct sdio_func *func;
153 psdio_data = &dvobj->intf_data;
154 func = psdio_data->func;
156 sdio_claim_host(func);
158 err = sdio_claim_irq(func, &sd_sync_int_hdl);
160 dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++;
161 RTW_PRINT("%s: sdio_claim_irq FAIL(%d)!\n", __func__, err);
163 dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++;
164 dvobj->irq_alloc = 1;
167 sdio_release_host(func);
169 return err ? _FAIL : _SUCCESS;
172 void sdio_free_irq(struct dvobj_priv *dvobj)
174 PSDIO_DATA psdio_data;
175 struct sdio_func *func;
178 if (dvobj->irq_alloc) {
179 psdio_data = &dvobj->intf_data;
180 func = psdio_data->func;
183 sdio_claim_host(func);
184 err = sdio_release_irq(func);
186 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
187 RTW_ERR("%s: sdio_release_irq FAIL(%d)!\n", __func__, err);
189 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
190 sdio_release_host(func);
192 dvobj->irq_alloc = 0;
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)
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
213 static u8 gpio_hostwakeup_alloc_irq(PADAPTER padapter)
219 RTW_INFO("oob_irq ZERO!\n");
223 RTW_INFO("%s : oob_irq = %d\n", __func__, oob_irq);
225 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
226 status = IRQF_NO_SUSPEND;
230 status |= IRQF_TRIGGER_RISING;
232 status |= IRQF_TRIGGER_FALLING;
234 err = request_threaded_irq(oob_irq, gpio_hostwakeup_irq_thread, NULL,
235 status, "rtw_wifi_gpio_wakeup", padapter);
238 RTW_INFO("Oops: can't allocate gpio irq %d err:%d\n", oob_irq, err);
241 RTW_INFO("allocate gpio irq %d ok\n", oob_irq);
243 #ifndef CONFIG_PLATFORM_ARM_SUN8I
244 enable_irq_wake(oob_irq);
249 static void gpio_hostwakeup_free_irq(PADAPTER padapter)
251 wifi_free_gpio(oob_gpio);
256 #ifndef CONFIG_PLATFORM_ARM_SUN8I
257 disable_irq_wake(oob_irq);
259 free_irq(oob_irq, padapter);
263 #define sdio_bus_speed(sel, speed) \
264 RTW_PRINT_SEL(sel, " timing spec : %s\n", speed)
266 void dump_sdio_card_info(void *sel, struct dvobj_priv *dvobj)
268 PSDIO_DATA psdio_data = &dvobj->intf_data;
270 RTW_PRINT_SEL(sel, "== SDIO Card Info ==\n");
271 RTW_PRINT_SEL(sel, " clock: %d Hz\n", psdio_data->clock);
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");
278 case MMC_TIMING_SD_HS:
279 sdio_bus_speed(sel, "sd high-speed");
281 case MMC_TIMING_UHS_SDR12:
282 sdio_bus_speed(sel, "sd uhs SDR12");
284 case MMC_TIMING_UHS_SDR25:
285 sdio_bus_speed(sel, "sd uhs SDR25");
287 case MMC_TIMING_UHS_SDR50:
288 sdio_bus_speed(sel, "sd uhs SDR50");
290 case MMC_TIMING_UHS_SDR104:
291 sdio_bus_speed(sel, "sd uhs SDR104");
293 case MMC_TIMING_UHS_DDR50:
294 sdio_bus_speed(sel, "sd uhs DDR50");
297 case MMC_TIMING_MMC_HS:
298 sdio_bus_speed(sel, "mmc high-speed");
300 case MMC_TIMING_MMC_DDR52:
301 sdio_bus_speed(sel, "mmc DDR52");
303 case MMC_TIMING_MMC_HS200:
304 sdio_bus_speed(sel, "mmc HS200");
306 case MMC_TIMING_MMC_HS400:
307 sdio_bus_speed(sel, "mmc HS400");
311 sdio_bus_speed(sel, "invalid");
315 RTW_PRINT_SEL(sel, " sd3_bus_mode: %s\n", (psdio_data->sd3_bus_mode) ? "TRUE" : "FALSE");
316 RTW_PRINT_SEL(sel, "================\n");
319 #define SDIO_CARD_INFO_DUMP(dvobj) dump_sdio_card_info(RTW_DBGDUMP, dvobj)
321 static u32 sdio_init(struct dvobj_priv *dvobj)
323 PSDIO_DATA psdio_data;
324 struct sdio_func *func;
328 psdio_data = &dvobj->intf_data;
329 func = psdio_data->func;
331 /* 3 1. init SDIO bus */
332 sdio_claim_host(func);
334 err = sdio_enable_func(func);
336 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
337 RTW_PRINT("%s: sdio_enable_func FAIL(%d)!\n", __func__, err);
341 err = sdio_set_block_size(func, 512);
343 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
344 RTW_PRINT("%s: sdio_set_block_size FAIL(%d)!\n", __func__, err);
347 psdio_data->block_transfer_len = 512;
348 psdio_data->tx_block_mode = 1;
349 psdio_data->rx_block_mode = 1;
351 psdio_data->timing = func->card->host->ios.timing;
352 psdio_data->clock = func->card->host->ios.clock;
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;
359 SDIO_CARD_INFO_DUMP(dvobj);
363 sdio_release_host(func);
372 static void sdio_deinit(struct dvobj_priv *dvobj)
374 struct sdio_func *func;
379 func = dvobj->intf_data.func;
382 sdio_claim_host(func);
383 err = sdio_disable_func(func);
385 dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++;
386 RTW_ERR("%s: sdio_disable_func(%d)\n", __func__, err);
389 sdio_release_host(func);
393 static void rtw_decide_chip_type_by_device_id(struct dvobj_priv *dvobj, const struct sdio_device_id *pdid)
395 dvobj->chip_type = pdid->driver_data;
397 #if defined(CONFIG_RTL8188E)
398 if (dvobj->chip_type == RTL8188E) {
399 dvobj->HardwareType = HARDWARE_TYPE_RTL8188ES;
400 RTW_INFO("CHIP TYPE: RTL8188E\n");
404 #if defined(CONFIG_RTL8723B)
405 dvobj->chip_type = RTL8723B;
406 dvobj->HardwareType = HARDWARE_TYPE_RTL8723BS;
409 #if defined(CONFIG_RTL8821A)
410 if (dvobj->chip_type == RTL8821) {
411 dvobj->HardwareType = HARDWARE_TYPE_RTL8821S;
412 RTW_INFO("CHIP TYPE: RTL8821A\n");
416 #if defined(CONFIG_RTL8192E)
417 if (dvobj->chip_type == RTL8192E) {
418 dvobj->HardwareType = HARDWARE_TYPE_RTL8192ES;
419 RTW_INFO("CHIP TYPE: RTL8192E\n");
423 #if defined(CONFIG_RTL8703B)
424 if (dvobj->chip_type == RTL8703B) {
425 dvobj->HardwareType = HARDWARE_TYPE_RTL8703BS;
426 RTW_INFO("CHIP TYPE: RTL8703B\n");
430 #if defined(CONFIG_RTL8723D)
431 if (dvobj->chip_type == RTL8723D) {
432 dvobj->HardwareType = HARDWARE_TYPE_RTL8723DS;
433 RTW_INFO("CHIP TYPE: RTL8723D\n");
437 #if defined(CONFIG_RTL8188F)
438 if (dvobj->chip_type == RTL8188F) {
439 dvobj->HardwareType = HARDWARE_TYPE_RTL8188FS;
440 RTW_INFO("CHIP TYPE: RTL8188F\n");
444 #if defined(CONFIG_RTL8822B)
445 if (dvobj->chip_type == RTL8822B) {
446 dvobj->HardwareType = HARDWARE_TYPE_RTL8822BS;
447 RTW_INFO("CHIP TYPE: RTL8822B\n");
451 #if defined(CONFIG_RTL8821C)
452 if (dvobj->chip_type == RTL8821C) {
453 dvobj->HardwareType = HARDWARE_TYPE_RTL8821CS;
454 RTW_INFO("CHIP TYPE: RTL8821C\n");
459 static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func, const struct sdio_device_id *pdid)
462 struct dvobj_priv *dvobj = NULL;
465 dvobj = devobj_init();
468 dvobj->intf_ops = &sdio_ops;
470 sdio_set_drvdata(func, dvobj);
472 psdio = &dvobj->intf_data;
475 if (sdio_init(dvobj) != _SUCCESS) {
479 dvobj->interface_type = RTW_SDIO;
480 rtw_decide_chip_type_by_device_id(dvobj, pdid);
482 rtw_reset_continual_io_error(dvobj);
486 if (status != _SUCCESS && dvobj) {
487 sdio_set_drvdata(func, NULL);
489 devobj_deinit(dvobj);
497 static void sdio_dvobj_deinit(struct sdio_func *func)
499 struct dvobj_priv *dvobj = sdio_get_drvdata(func);
501 sdio_set_drvdata(func, NULL);
504 sdio_free_irq(dvobj);
505 devobj_deinit(dvobj);
511 u8 rtw_set_hal_ops(PADAPTER padapter)
513 /* alloc memory for HAL DATA */
514 if (rtw_hal_data_init(padapter) == _FAIL)
517 #if defined(CONFIG_RTL8188E)
518 if (rtw_get_chip_type(padapter) == RTL8188E)
519 rtl8188es_set_hal_ops(padapter);
522 #if defined(CONFIG_RTL8723B)
523 if (rtw_get_chip_type(padapter) == RTL8723B)
524 rtl8723bs_set_hal_ops(padapter);
527 #if defined(CONFIG_RTL8821A)
528 if (rtw_get_chip_type(padapter) == RTL8821)
529 rtl8821as_set_hal_ops(padapter);
532 #if defined(CONFIG_RTL8192E)
533 if (rtw_get_chip_type(padapter) == RTL8192E)
534 rtl8192es_set_hal_ops(padapter);
537 #if defined(CONFIG_RTL8703B)
538 if (rtw_get_chip_type(padapter) == RTL8703B)
539 rtl8703bs_set_hal_ops(padapter);
542 #if defined(CONFIG_RTL8723D)
543 if (rtw_get_chip_type(padapter) == RTL8723D)
544 rtl8723ds_set_hal_ops(padapter);
547 #if defined(CONFIG_RTL8188F)
548 if (rtw_get_chip_type(padapter) == RTL8188F)
549 rtl8188fs_set_hal_ops(padapter);
552 #if defined(CONFIG_RTL8822B)
553 if (rtw_get_chip_type(padapter) == RTL8822B)
554 rtl8822bs_set_hal_ops(padapter);
557 #if defined(CONFIG_RTL8821C)
558 if (rtw_get_chip_type(padapter) == RTL8821C) {
559 if (rtl8821cs_set_hal_ops(padapter) == _FAIL)
564 if (rtw_hal_ops_check(padapter) == _FAIL)
567 if (hal_spec_init(padapter) == _FAIL)
573 static void sd_intf_start(PADAPTER padapter)
575 if (padapter == NULL) {
576 RTW_ERR("%s: padapter is NULL!\n", __func__);
581 rtw_hal_enable_interrupt(padapter);
584 static void sd_intf_stop(PADAPTER padapter)
586 if (padapter == NULL) {
587 RTW_ERR("%s: padapter is NULL!\n", __func__);
592 rtw_hal_disable_interrupt(padapter);
596 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
597 PADAPTER g_test_adapter = NULL;
598 #endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */
600 _adapter *rtw_sdio_primary_adapter_init(struct dvobj_priv *dvobj)
603 PADAPTER padapter = NULL;
605 padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter));
606 if (padapter == NULL)
609 if (loadparam(padapter) != _SUCCESS)
612 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
613 g_test_adapter = padapter;
614 #endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */
615 padapter->dvobj = dvobj;
617 rtw_set_drv_stopped(padapter);/*init*/
619 dvobj->padapters[dvobj->iface_nums++] = padapter;
620 padapter->iface_id = IFACE_ID0;
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;
628 padapter->hw_port = HW_PORT0;
631 /* 3 3. init driver special setting, interface, OS and hardware relative */
633 /* 4 3.1 set hardware operation functions */
634 if (rtw_set_hal_ops(padapter) == _FAIL)
637 /* 3 5. initialize Chip version */
638 padapter->intf_start = &sd_intf_start;
639 padapter->intf_stop = &sd_intf_stop;
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;
646 if (rtw_init_io_priv(padapter, sdio_set_intf_ops) == _FAIL) {
650 rtw_hal_read_chip_version(padapter);
652 rtw_hal_chip_configure(padapter);
654 /* 3 6. read efuse/eeprom data */
655 if (rtw_hal_read_chip_info(padapter) == _FAIL)
658 /* 3 7. init driver common data */
659 if (rtw_init_drv_sw(padapter) == _FAIL) {
663 #ifdef CONFIG_BT_COEXIST
664 if (GET_HAL_DATA(padapter)->EEPROMBluetoothCoexist)
665 rtw_btcoex_Initialize(padapter);
667 rtw_btcoex_wifionly_initialize(padapter);
668 #else /* !CONFIG_BT_COEXIST */
669 rtw_btcoex_wifionly_initialize(padapter);
670 #endif /* CONFIG_BT_COEXIST */
672 /* 3 8. get WLan MAC address */
674 rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter));
676 #ifdef CONFIG_MI_WITH_MBSSID_CAM
677 rtw_mbid_camid_alloc(padapter, adapter_mac_addr(padapter));
680 rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));
681 #endif /* CONFIG_P2P */
683 rtw_hal_disable_interrupt(padapter);
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"
689 , rtw_get_hw_init_completed(padapter)
695 if (status != _SUCCESS && padapter->HalData)
696 rtw_hal_free_data(padapter);
699 if (status != _SUCCESS && padapter) {
700 rtw_vmfree((u8 *)padapter, sizeof(*padapter));
707 static void rtw_sdio_primary_adapter_deinit(_adapter *padapter)
709 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
711 if (check_fwstate(pmlmepriv, _FW_LINKED))
712 rtw_disassoc_cmd(padapter, 0, RTW_CMDF_DIRECTLY);
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);
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);
728 gpio_hostwakeup_free_irq(padapter);
732 /*rtw_cancel_all_timer(if1);*/
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 */
739 rtw_dev_unload(padapter);
740 RTW_INFO("+r871xu_dev_remove, hw_init_completed=%d\n", rtw_get_hw_init_completed(padapter));
742 rtw_free_drv_sw(padapter);
744 /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
745 rtw_os_ndev_free(padapter);
748 rtw_halmac_deinit_adapter(adapter_to_dvobj(padapter));
749 #endif /* RTW_HALMAC */
751 rtw_vmfree((u8 *)padapter, sizeof(_adapter));
753 #ifdef CONFIG_PLATFORM_RTD2880B
754 RTW_INFO("wlan link down\n");
755 rtd2885_wlan_netlink_sendMsg("linkdown", "8712");
758 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
759 g_test_adapter = NULL;
760 #endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */
764 * drv_init() - a device potentially for us
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.
769 static int rtw_drv_init(
770 struct sdio_func *func,
771 const struct sdio_device_id *id)
774 #ifdef CONFIG_CONCURRENT_MODE
777 struct net_device *pnetdev;
778 PADAPTER padapter = NULL;
779 struct dvobj_priv *dvobj;
781 #ifdef CONFIG_PLATFORM_INTEL_BYT
785 struct acpi_device *adev;
788 #if defined(CONFIG_ACPI) && defined(CONFIG_GPIO_WAKEUP)
789 handle = ACPI_HANDLE(&func->dev);
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");
796 adev->flags.power_manageable = 0;
797 RTW_INFO("Disabling ACPI power management support!\n");
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();
803 RTW_INFO("rtw_drv_init: ACPI_HANDLE NOT found!\n");
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);
811 RTW_INFO("rtw_drv_init: ACPI_HANDLE NOT found!\n");
813 #endif /* CONFIG_PLATFORM_INTEL_BYT */
817 dvobj = sdio_dvobj_init(func, id);
822 padapter = rtw_sdio_primary_adapter_init(dvobj);
823 if (padapter == NULL) {
824 RTW_INFO("rtw_init_primary_adapter Failed!\n");
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);
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);
840 /* dev_alloc_name && register_netdev */
841 if (rtw_os_ndevs_init(dvobj) != _SUCCESS)
844 #ifdef CONFIG_HOSTAPD_MLME
845 hostapd_mode_init(padapter);
848 #ifdef CONFIG_PLATFORM_RTD2880B
849 RTW_INFO("wlan link up\n");
850 rtd2885_wlan_netlink_sendMsg("linkup", "8712");
853 if (sdio_alloc_irq(dvobj) != _SUCCESS)
854 goto os_ndevs_deinit;
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__);
864 gpio_hostwakeup_alloc_irq(padapter);
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);
879 if (status != _SUCCESS)
880 rtw_os_ndevs_deinit(dvobj);
882 if (status != _SUCCESS) {
883 #ifdef CONFIG_CONCURRENT_MODE
884 rtw_drv_stop_vir_ifaces(dvobj);
885 rtw_drv_free_vir_ifaces(dvobj);
889 if (status != _SUCCESS && padapter)
890 rtw_sdio_primary_adapter_deinit(padapter);
893 if (status != _SUCCESS)
894 sdio_dvobj_deinit(func);
896 return status == _SUCCESS ? 0 : -ENODEV;
899 static void rtw_dev_remove(struct sdio_func *func)
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);
907 dvobj->processing_dev_remove = _TRUE;
909 /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
910 rtw_os_ndevs_unregister(dvobj);
912 if (!rtw_is_surprise_removed(padapter)) {
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__);
925 #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
926 rtw_unregister_early_suspend(pwrctl);
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);
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);
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);
946 rtw_btcoex_HaltNotify(padapter);
949 rtw_sdio_primary_adapter_deinit(padapter);
951 #ifdef CONFIG_CONCURRENT_MODE
952 rtw_drv_free_vir_ifaces(dvobj);
955 sdio_dvobj_deinit(func);
959 extern int pm_netdev_open(struct net_device *pnetdev, u8 bnormal);
960 extern int pm_netdev_close(struct net_device *pnetdev, u8 bnormal);
962 static int rtw_sdio_suspend(struct device *dev)
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;
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__);
983 if (pwrpriv->bInSuspend == _TRUE) {
984 RTW_INFO("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend);
985 pdbgpriv->dbg_suspend_error_cnt++;
989 ret = rtw_suspend_common(padapter);
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 */
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));
1006 pdbgpriv->dbg_suspend_error_cnt++;
1009 RTW_INFO("cmd: suspend with MMC_PM_KEEP_POWER\n");
1010 sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
1017 int rtw_resume_process(_adapter *padapter)
1019 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1020 struct dvobj_priv *psdpriv = padapter->dvobj;
1021 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1023 if (pwrpriv->bInSuspend == _FALSE) {
1024 pdbgpriv->dbg_resume_error_cnt++;
1025 RTW_INFO("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend);
1029 return rtw_resume_common(padapter);
1032 static int rtw_sdio_resume(struct device *dev)
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;
1040 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1042 RTW_INFO("==> %s (%s:%d)\n", __FUNCTION__, current->comm, current->pid);
1044 pdbgpriv->dbg_resume_cnt++;
1046 if (pwrpriv->bInternalAutoSuspend)
1047 ret = rtw_resume_process(padapter);
1049 #ifdef CONFIG_PLATFORM_INTEL_BYT
1052 if (pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode)
1055 rtw_resume_lock_suspend();
1056 ret = rtw_resume_process(padapter);
1057 rtw_resume_unlock_suspend();
1059 #ifdef CONFIG_RESUME_IN_WORKQUEUE
1060 rtw_resume_in_workqueue(pwrpriv);
1062 if (rtw_is_earlysuspend_registered(pwrpriv)) {
1063 /* jeff: bypass resume here, do in late_resume */
1064 rtw_set_do_late_resume(pwrpriv, _TRUE);
1066 rtw_resume_lock_suspend();
1067 ret = rtw_resume_process(padapter);
1068 rtw_resume_unlock_suspend();
1073 pmlmeext->last_scan_time = rtw_get_current_time();
1074 RTW_INFO("<======== %s return %d\n", __FUNCTION__, ret);
1079 static int rtw_drv_entry(void)
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 */
1089 ret = platform_wifi_power_on();
1091 RTW_INFO("%s: power on failed!!(%d)\n", __FUNCTION__, ret);
1096 sdio_drvpriv.drv_registered = _TRUE;
1097 rtw_suspend_lock_init();
1098 rtw_drv_proc_init();
1099 rtw_ndev_notifier_register();
1101 ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv);
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);
1111 #ifndef CONFIG_PLATFORM_INTEL_BYT
1112 rtw_android_wifictrl_func_add();
1113 #endif /* !CONFIG_PLATFORM_INTEL_BYT */
1117 platform_wifi_power_off();
1120 RTW_PRINT("module init ret=%d\n", ret);
1124 static void rtw_drv_halt(void)
1126 RTW_PRINT("module exit start\n");
1128 sdio_drvpriv.drv_registered = _FALSE;
1130 sdio_unregister_driver(&sdio_drvpriv.r871xs_drv);
1132 rtw_android_wifictrl_func_del();
1134 platform_wifi_power_off();
1136 rtw_suspend_lock_uninit();
1137 rtw_drv_proc_deinit();
1138 rtw_ndev_notifier_unregister();
1140 RTW_PRINT("module exit success\n");
1142 rtw_mstat_dump(RTW_DBGDUMP);
1145 #ifdef CONFIG_PLATFORM_INTEL_BYT
1146 int rtw_sdio_set_power(int on)
1149 if (wlan_en_gpio >= 0) {
1151 gpio_set_value(wlan_en_gpio, 1);
1153 gpio_set_value(wlan_en_gpio, 0);
1158 #endif /* CONFIG_PLATFORM_INTEL_BYT */
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);
1165 int rockchip_wifi_init_module_rtkwifi(void)
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;
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);
1177 rockchip_wifi_power(1);
1178 rockchip_wifi_set_carddetect(1);
1180 return rtw_drv_entry();
1183 void rockchip_wifi_exit_module_rtkwifi(void)
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;
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);
1197 rockchip_wifi_set_carddetect(0);
1198 rockchip_wifi_power(0);
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);
1205 EXPORT_SYMBOL(rockchip_wifi_init_module_rtkwifi);
1206 EXPORT_SYMBOL(rockchip_wifi_exit_module_rtkwifi);
1208 //module_init(rtw_drv_entry);
1209 //module_exit(rtw_drv_halt);