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_RTL8821C
35 #include <rtl8821cs_hal.h> /* rtl8821cs_set_hal_ops() */
36 #endif /* CONFIG_RTL8821C */
38 #ifdef CONFIG_PLATFORM_INTEL_BYT
40 #include <linux/acpi.h>
41 #include <linux/acpi_gpio.h>
42 #include "rtw_android.h"
44 static int wlan_en_gpio = -1;
45 #endif /* CONFIG_PLATFORM_INTEL_BYT */
47 #ifndef dev_to_sdio_func
48 #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev)
52 static struct mmc_host *mmc_host = NULL;
55 static const struct sdio_device_id sdio_ids[] = {
56 #ifdef CONFIG_RTL8723B
57 { SDIO_DEVICE(0x024c, 0xB723), .driver_data = RTL8723B},
59 #ifdef CONFIG_RTL8188E
60 { SDIO_DEVICE(0x024c, 0x8179), .driver_data = RTL8188E},
61 #endif /* CONFIG_RTL8188E */
63 #ifdef CONFIG_RTL8821A
64 { SDIO_DEVICE(0x024c, 0x8821), .driver_data = RTL8821},
65 #endif /* CONFIG_RTL8821A */
67 #ifdef CONFIG_RTL8192E
68 { SDIO_DEVICE(0x024c, 0x818B), .driver_data = RTL8192E},
69 #endif /* CONFIG_RTL8192E */
71 #ifdef CONFIG_RTL8703B
72 { SDIO_DEVICE(0x024c, 0xB703), .driver_data = RTL8703B},
75 #ifdef CONFIG_RTL8188F
76 {SDIO_DEVICE(0x024c, 0xF179), .driver_data = RTL8188F},
78 #ifdef CONFIG_RTL8822B
79 {SDIO_DEVICE(0x024c, 0xB822), .driver_data = RTL8822B},
82 #ifdef CONFIG_RTL8723D
83 { SDIO_DEVICE(0x024c, 0xD723), .driver_data = RTL8723D},
84 { SDIO_DEVICE(0x024c, 0xD724), .driver_data = RTL8723D},
87 #ifdef CONFIG_RTL8821C
88 {SDIO_DEVICE(0x024c, 0xB821), .driver_data = RTL8821C},
91 #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) /* temporarily add this to accept all sdio wlan id */
92 { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) },
94 { /* end: all zeroes */ },
97 MODULE_DEVICE_TABLE(sdio, sdio_ids);
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);
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,
112 struct sdio_drv_priv {
113 struct sdio_driver r871xs_drv;
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))
124 .pm = &rtw_sdio_pm_ops,
129 static struct rtw_if_operations sdio_ops = {
130 .read = rtw_sdio_raw_read,
131 .write = rtw_sdio_raw_write,
134 static void sd_sync_int_hdl(struct sdio_func *func)
136 struct dvobj_priv *psdpriv;
138 psdpriv = sdio_get_drvdata(func);
140 if (!psdpriv->padapters[IFACE_ID0]) {
141 RTW_INFO("%s primary adapter == NULL\n", __func__);
145 rtw_sdio_set_irq_thd(psdpriv, current);
146 sd_int_hdl(psdpriv->padapters[IFACE_ID0]);
147 rtw_sdio_set_irq_thd(psdpriv, NULL);
150 int sdio_alloc_irq(struct dvobj_priv *dvobj)
152 PSDIO_DATA psdio_data;
153 struct sdio_func *func;
156 psdio_data = &dvobj->intf_data;
157 func = psdio_data->func;
159 sdio_claim_host(func);
161 err = sdio_claim_irq(func, &sd_sync_int_hdl);
163 dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++;
164 RTW_PRINT("%s: sdio_claim_irq FAIL(%d)!\n", __func__, err);
166 dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++;
167 dvobj->irq_alloc = 1;
170 sdio_release_host(func);
172 return err ? _FAIL : _SUCCESS;
175 void sdio_free_irq(struct dvobj_priv *dvobj)
177 PSDIO_DATA psdio_data;
178 struct sdio_func *func;
181 if (dvobj->irq_alloc) {
182 psdio_data = &dvobj->intf_data;
183 func = psdio_data->func;
186 sdio_claim_host(func);
187 err = sdio_release_irq(func);
189 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
190 RTW_ERR("%s: sdio_release_irq FAIL(%d)!\n", __func__, err);
192 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
193 sdio_release_host(func);
195 dvobj->irq_alloc = 0;
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)
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
216 static u8 gpio_hostwakeup_alloc_irq(PADAPTER padapter)
222 RTW_INFO("oob_irq ZERO!\n");
226 RTW_INFO("%s : oob_irq = %d\n", __func__, oob_irq);
228 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
229 status = IRQF_NO_SUSPEND;
233 status |= IRQF_TRIGGER_RISING;
235 status |= IRQF_TRIGGER_FALLING;
237 err = request_threaded_irq(oob_irq, gpio_hostwakeup_irq_thread, NULL,
238 status, "rtw_wifi_gpio_wakeup", padapter);
241 RTW_INFO("Oops: can't allocate gpio irq %d err:%d\n", oob_irq, err);
244 RTW_INFO("allocate gpio irq %d ok\n", oob_irq);
246 #ifndef CONFIG_PLATFORM_ARM_SUN8I
247 enable_irq_wake(oob_irq);
252 static void gpio_hostwakeup_free_irq(PADAPTER padapter)
254 wifi_free_gpio(oob_gpio);
259 #ifndef CONFIG_PLATFORM_ARM_SUN8I
260 disable_irq_wake(oob_irq);
262 free_irq(oob_irq, padapter);
266 static u32 sdio_init(struct dvobj_priv *dvobj)
268 PSDIO_DATA psdio_data;
269 struct sdio_func *func;
272 psdio_data = &dvobj->intf_data;
273 func = psdio_data->func;
275 /* 3 1. init SDIO bus */
276 sdio_claim_host(func);
278 err = sdio_enable_func(func);
280 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
281 RTW_PRINT("%s: sdio_enable_func FAIL(%d)!\n", __func__, err);
285 err = sdio_set_block_size(func, 512);
287 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
288 RTW_PRINT("%s: sdio_set_block_size FAIL(%d)!\n", __func__, err);
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);
297 if (dvobj->irq_alloc == 0) {
298 if (sdio_alloc_irq(dvobj) != _SUCCESS) {
299 RTW_ERR("%s: sdio_alloc_irq fail\n", __func__);
305 sdio_release_host(func);
314 static void sdio_deinit(struct dvobj_priv *dvobj)
316 struct sdio_func *func;
319 func = dvobj->intf_data.func;
322 sdio_claim_host(func);
323 err = sdio_disable_func(func);
325 dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++;
326 RTW_ERR("%s: sdio_disable_func(%d)\n", __func__, err);
329 if (dvobj->irq_alloc) {
330 err = sdio_release_irq(func);
332 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
333 RTW_ERR("%s: sdio_release_irq(%d)\n", __func__, err);
335 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
336 dvobj->irq_alloc = 0;
340 sdio_release_host(func);
344 static void rtw_decide_chip_type_by_device_id(struct dvobj_priv *dvobj, const struct sdio_device_id *pdid)
346 dvobj->chip_type = pdid->driver_data;
348 #if defined(CONFIG_RTL8188E)
349 if (dvobj->chip_type == RTL8188E) {
350 dvobj->HardwareType = HARDWARE_TYPE_RTL8188ES;
351 RTW_INFO("CHIP TYPE: RTL8188E\n");
355 #if defined(CONFIG_RTL8723B)
356 dvobj->chip_type = RTL8723B;
357 dvobj->HardwareType = HARDWARE_TYPE_RTL8723BS;
360 #if defined(CONFIG_RTL8821A)
361 if (dvobj->chip_type == RTL8821) {
362 dvobj->HardwareType = HARDWARE_TYPE_RTL8821S;
363 RTW_INFO("CHIP TYPE: RTL8821A\n");
367 #if defined(CONFIG_RTL8192E)
368 if (dvobj->chip_type == RTL8192E) {
369 dvobj->HardwareType = HARDWARE_TYPE_RTL8192ES;
370 RTW_INFO("CHIP TYPE: RTL8192E\n");
374 #if defined(CONFIG_RTL8703B)
375 if (dvobj->chip_type == RTL8703B) {
376 dvobj->HardwareType = HARDWARE_TYPE_RTL8703BS;
377 RTW_INFO("CHIP TYPE: RTL8703B\n");
381 #if defined(CONFIG_RTL8723D)
382 if (dvobj->chip_type == RTL8723D) {
383 dvobj->HardwareType = HARDWARE_TYPE_RTL8723DS;
384 RTW_INFO("CHIP TYPE: RTL8723D\n");
388 #if defined(CONFIG_RTL8188F)
389 if (dvobj->chip_type == RTL8188F) {
390 dvobj->HardwareType = HARDWARE_TYPE_RTL8188FS;
391 RTW_INFO("CHIP TYPE: RTL8188F\n");
395 #if defined(CONFIG_RTL8822B)
396 if (dvobj->chip_type == RTL8822B) {
397 dvobj->HardwareType = HARDWARE_TYPE_RTL8822BS;
398 RTW_INFO("CHIP TYPE: RTL8822B\n");
402 #if defined(CONFIG_RTL8821C)
403 if (dvobj->chip_type == RTL8821C) {
404 dvobj->HardwareType = HARDWARE_TYPE_RTL8821CS;
405 RTW_INFO("CHIP TYPE: RTL8821C\n");
410 static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func, const struct sdio_device_id *pdid)
413 struct dvobj_priv *dvobj = NULL;
416 dvobj = devobj_init();
419 dvobj->intf_ops = &sdio_ops;
421 sdio_set_drvdata(func, dvobj);
423 psdio = &dvobj->intf_data;
426 if (sdio_init(dvobj) != _SUCCESS) {
430 dvobj->interface_type = RTW_SDIO;
431 rtw_decide_chip_type_by_device_id(dvobj, pdid);
433 rtw_reset_continual_io_error(dvobj);
437 if (status != _SUCCESS && dvobj) {
438 sdio_set_drvdata(func, NULL);
440 devobj_deinit(dvobj);
448 static void sdio_dvobj_deinit(struct sdio_func *func)
450 struct dvobj_priv *dvobj = sdio_get_drvdata(func);
452 sdio_set_drvdata(func, NULL);
455 devobj_deinit(dvobj);
461 u8 rtw_set_hal_ops(PADAPTER padapter)
463 /* alloc memory for HAL DATA */
464 if (rtw_hal_data_init(padapter) == _FAIL)
467 #if defined(CONFIG_RTL8188E)
468 if (rtw_get_chip_type(padapter) == RTL8188E)
469 rtl8188es_set_hal_ops(padapter);
472 #if defined(CONFIG_RTL8723B)
473 if (rtw_get_chip_type(padapter) == RTL8723B)
474 rtl8723bs_set_hal_ops(padapter);
477 #if defined(CONFIG_RTL8821A)
478 if (rtw_get_chip_type(padapter) == RTL8821)
479 rtl8821as_set_hal_ops(padapter);
482 #if defined(CONFIG_RTL8192E)
483 if (rtw_get_chip_type(padapter) == RTL8192E)
484 rtl8192es_set_hal_ops(padapter);
487 #if defined(CONFIG_RTL8703B)
488 if (rtw_get_chip_type(padapter) == RTL8703B)
489 rtl8703bs_set_hal_ops(padapter);
492 #if defined(CONFIG_RTL8723D)
493 if (rtw_get_chip_type(padapter) == RTL8723D)
494 rtl8723ds_set_hal_ops(padapter);
497 #if defined(CONFIG_RTL8188F)
498 if (rtw_get_chip_type(padapter) == RTL8188F)
499 rtl8188fs_set_hal_ops(padapter);
502 #if defined(CONFIG_RTL8822B)
503 if (rtw_get_chip_type(padapter) == RTL8822B)
504 rtl8822bs_set_hal_ops(padapter);
507 #if defined(CONFIG_RTL8821C)
508 if (rtw_get_chip_type(padapter) == RTL8821C) {
509 if (rtl8821cs_set_hal_ops(padapter) == _FAIL)
514 if (rtw_hal_ops_check(padapter) == _FAIL)
517 if (hal_spec_init(padapter) == _FAIL)
523 static void sd_intf_start(PADAPTER padapter)
525 if (padapter == NULL) {
526 RTW_ERR("%s: padapter is NULL!\n", __func__);
531 rtw_hal_enable_interrupt(padapter);
534 static void sd_intf_stop(PADAPTER padapter)
536 if (padapter == NULL) {
537 RTW_ERR("%s: padapter is NULL!\n", __func__);
542 rtw_hal_disable_interrupt(padapter);
546 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
547 PADAPTER g_test_adapter = NULL;
548 #endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */
550 _adapter *rtw_sdio_primary_adapter_init(struct dvobj_priv *dvobj)
553 PADAPTER padapter = NULL;
555 padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter));
556 if (padapter == NULL)
559 if (loadparam(padapter) != _SUCCESS)
562 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
563 g_test_adapter = padapter;
564 #endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */
565 padapter->dvobj = dvobj;
567 rtw_set_drv_stopped(padapter);/*init*/
569 dvobj->padapters[dvobj->iface_nums++] = padapter;
570 padapter->iface_id = IFACE_ID0;
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;
578 padapter->hw_port = HW_PORT0;
581 /* 3 3. init driver special setting, interface, OS and hardware relative */
583 /* 4 3.1 set hardware operation functions */
584 if (rtw_set_hal_ops(padapter) == _FAIL)
587 /* 3 5. initialize Chip version */
588 padapter->intf_start = &sd_intf_start;
589 padapter->intf_stop = &sd_intf_stop;
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;
596 if (rtw_init_io_priv(padapter, sdio_set_intf_ops) == _FAIL) {
600 rtw_hal_read_chip_version(padapter);
602 rtw_hal_chip_configure(padapter);
604 /* 3 6. read efuse/eeprom data */
605 rtw_hal_read_chip_info(padapter);
608 /* 3 7. init driver common data */
609 if (rtw_init_drv_sw(padapter) == _FAIL) {
613 #ifdef CONFIG_BT_COEXIST
614 rtw_btcoex_Initialize(padapter);
615 #endif /* CONFIG_BT_COEXIST */
617 /* 3 8. get WLan MAC address */
619 rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter));
621 #ifdef CONFIG_MI_WITH_MBSSID_CAM
622 rtw_mbid_camid_alloc(padapter, adapter_mac_addr(padapter));
625 rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));
626 #endif /* CONFIG_P2P */
628 rtw_hal_disable_interrupt(padapter);
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"
634 , rtw_get_hw_init_completed(padapter)
640 if (status != _SUCCESS && padapter->HalData)
641 rtw_hal_free_data(padapter);
644 if (status != _SUCCESS && padapter) {
645 rtw_vmfree((u8 *)padapter, sizeof(*padapter));
652 static void rtw_sdio_primary_adapter_deinit(_adapter *padapter)
654 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
656 if (check_fwstate(pmlmepriv, _FW_LINKED))
657 rtw_disassoc_cmd(padapter, 0, _FALSE);
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);
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);
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 */
679 /*rtw_cancel_all_timer(if1);*/
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 */
686 rtw_dev_unload(padapter);
687 RTW_INFO("+r871xu_dev_remove, hw_init_completed=%d\n", rtw_get_hw_init_completed(padapter));
689 rtw_free_drv_sw(padapter);
691 /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
692 rtw_os_ndev_free(padapter);
695 rtw_halmac_deinit_adapter(adapter_to_dvobj(padapter));
696 #endif /* RTW_HALMAC */
698 rtw_vmfree((u8 *)padapter, sizeof(_adapter));
700 #ifdef CONFIG_PLATFORM_RTD2880B
701 RTW_INFO("wlan link down\n");
702 rtd2885_wlan_netlink_sendMsg("linkdown", "8712");
705 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
706 g_test_adapter = NULL;
707 #endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */
711 * drv_init() - a device potentially for us
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.
716 static int rtw_drv_init(
717 struct sdio_func *func,
718 const struct sdio_device_id *id)
721 #ifdef CONFIG_CONCURRENT_MODE
724 struct net_device *pnetdev;
725 PADAPTER padapter = NULL;
726 struct dvobj_priv *dvobj;
728 #ifdef CONFIG_PLATFORM_INTEL_BYT
732 struct acpi_device *adev;
735 #if defined(CONFIG_ACPI) && defined(CONFIG_GPIO_WAKEUP)
736 handle = ACPI_HANDLE(&func->dev);
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");
743 adev->flags.power_manageable = 0;
744 RTW_INFO("Disabling ACPI power management support!\n");
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();
750 RTW_INFO("rtw_drv_init: ACPI_HANDLE NOT found!\n");
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);
758 RTW_INFO("rtw_drv_init: ACPI_HANDLE NOT found!\n");
760 #endif /* CONFIG_PLATFORM_INTEL_BYT */
764 dvobj = sdio_dvobj_init(func, id);
769 padapter = rtw_sdio_primary_adapter_init(dvobj);
770 if (padapter == NULL) {
771 RTW_INFO("rtw_init_primary_adapter Failed!\n");
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);
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);
787 /* dev_alloc_name && register_netdev */
788 if (rtw_os_ndevs_init(dvobj) != _SUCCESS)
791 #ifdef CONFIG_HOSTAPD_MLME
792 hostapd_mode_init(padapter);
795 #ifdef CONFIG_PLATFORM_RTD2880B
796 RTW_INFO("wlan link up\n");
797 rtd2885_wlan_netlink_sendMsg("linkup", "8712");
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__);
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 */
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);
825 if (status != _SUCCESS)
826 rtw_os_ndevs_deinit(dvobj);
828 if (status != _SUCCESS) {
829 #ifdef CONFIG_CONCURRENT_MODE
830 rtw_drv_stop_vir_ifaces(dvobj);
831 rtw_drv_free_vir_ifaces(dvobj);
835 if (status != _SUCCESS && padapter)
836 rtw_sdio_primary_adapter_deinit(padapter);
839 if (status != _SUCCESS)
840 sdio_dvobj_deinit(func);
842 return status == _SUCCESS ? 0 : -ENODEV;
845 static void rtw_dev_remove(struct sdio_func *func)
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];
853 dvobj->processing_dev_remove = _TRUE;
855 /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
856 rtw_os_ndevs_unregister(dvobj);
858 if (!rtw_is_surprise_removed(padapter)) {
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__);
871 #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
872 rtw_unregister_early_suspend(pwrctl);
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);
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);
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);
891 rtw_btcoex_HaltNotify(padapter);
894 rtw_sdio_primary_adapter_deinit(padapter);
896 #ifdef CONFIG_CONCURRENT_MODE
897 rtw_drv_free_vir_ifaces(dvobj);
900 sdio_dvobj_deinit(func);
904 extern int pm_netdev_open(struct net_device *pnetdev, u8 bnormal);
905 extern int pm_netdev_close(struct net_device *pnetdev, u8 bnormal);
907 static int rtw_sdio_suspend(struct device *dev)
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;
920 if (psdpriv->processing_dev_remove == _TRUE) {
921 RTW_ERR("%s processing_dev_remove is _TRUE\n", __func__);
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__);
933 if (pwrpriv->bInSuspend == _TRUE) {
934 RTW_INFO("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend);
935 pdbgpriv->dbg_suspend_error_cnt++;
939 ret = rtw_suspend_common(padapter);
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 */
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));
956 pdbgpriv->dbg_suspend_error_cnt++;
959 RTW_INFO("cmd: suspend with MMC_PM_KEEP_POWER\n");
960 sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
967 int rtw_resume_process(_adapter *padapter)
969 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
970 struct dvobj_priv *psdpriv = padapter->dvobj;
971 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
973 if (pwrpriv->bInSuspend == _FALSE) {
974 pdbgpriv->dbg_resume_error_cnt++;
975 RTW_INFO("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend);
979 return rtw_resume_common(padapter);
982 static int rtw_sdio_resume(struct device *dev)
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;
990 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
992 RTW_INFO("==> %s (%s:%d)\n", __FUNCTION__, current->comm, current->pid);
994 pdbgpriv->dbg_resume_cnt++;
996 if (pwrpriv->bInternalAutoSuspend)
997 ret = rtw_resume_process(padapter);
999 #ifdef CONFIG_PLATFORM_INTEL_BYT
1002 if (pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode)
1005 rtw_resume_lock_suspend();
1006 ret = rtw_resume_process(padapter);
1007 rtw_resume_unlock_suspend();
1009 #ifdef CONFIG_RESUME_IN_WORKQUEUE
1010 rtw_resume_in_workqueue(pwrpriv);
1012 if (rtw_is_earlysuspend_registered(pwrpriv)) {
1013 /* jeff: bypass resume here, do in late_resume */
1014 rtw_set_do_late_resume(pwrpriv, _TRUE);
1016 rtw_resume_lock_suspend();
1017 ret = rtw_resume_process(padapter);
1018 rtw_resume_unlock_suspend();
1023 pmlmeext->last_scan_time = rtw_get_current_time();
1024 RTW_INFO("<======== %s return %d\n", __FUNCTION__, ret);
1029 static int rtw_drv_entry(void)
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 */
1039 ret = platform_wifi_power_on();
1041 RTW_INFO("%s: power on failed!!(%d)\n", __FUNCTION__, ret);
1046 sdio_drvpriv.drv_registered = _TRUE;
1047 rtw_suspend_lock_init();
1048 rtw_drv_proc_init();
1049 rtw_ndev_notifier_register();
1051 ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv);
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);
1061 #ifndef CONFIG_PLATFORM_INTEL_BYT
1062 rtw_android_wifictrl_func_add();
1063 #endif /* !CONFIG_PLATFORM_INTEL_BYT */
1067 platform_wifi_power_off();
1070 RTW_PRINT("module init ret=%d\n", ret);
1074 static void rtw_drv_halt(void)
1076 RTW_PRINT("module exit start\n");
1078 sdio_drvpriv.drv_registered = _FALSE;
1080 sdio_unregister_driver(&sdio_drvpriv.r871xs_drv);
1082 rtw_android_wifictrl_func_del();
1084 platform_wifi_power_off();
1086 rtw_suspend_lock_uninit();
1087 rtw_drv_proc_deinit();
1088 rtw_ndev_notifier_unregister();
1090 RTW_PRINT("module exit success\n");
1092 rtw_mstat_dump(RTW_DBGDUMP);
1095 #ifdef CONFIG_PLATFORM_INTEL_BYT
1096 int rtw_sdio_set_power(int on)
1099 if (wlan_en_gpio >= 0) {
1101 gpio_set_value(wlan_en_gpio, 1);
1103 gpio_set_value(wlan_en_gpio, 0);
1108 #endif /* CONFIG_PLATFORM_INTEL_BYT */
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);
1116 int rockchip_wifi_init_module_rtkwifi(void)
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;
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);
1128 rockchip_wifi_power(1);
1129 rockchip_wifi_set_carddetect(1);
1131 return rtw_drv_entry();
1134 void rockchip_wifi_exit_module_rtkwifi(void)
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;
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);
1148 rockchip_wifi_set_carddetect(0);
1149 rockchip_wifi_power(0);
1152 #ifdef CONFIG_WIFI_BUILD_MODULE
1153 module_init(rockchip_wifi_init_module_rtkwifi);
1154 module_exit(rockchip_wifi_exit_module_rtkwifi);
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);
1160 EXPORT_SYMBOL(rockchip_wifi_init_module_rtkwifi);
1161 EXPORT_SYMBOL(rockchip_wifi_exit_module_rtkwifi);
1164 //module_init(rtw_drv_entry);
1165 //module_exit(rtw_drv_halt);