/** * @brief This function unregisters MOAL from MLAN module. * * @param pmlan_adapter A pointer to a mlan_device structure * allocated in MOAL * * @return MLAN_STATUS_SUCCESS * The deregistration succeeded. */ mlan_status mlan_unregister(IN t_void * pmlan_adapter) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter; pmlan_callbacks pcb; t_s32 i = 0; MASSERT(pmlan_adapter); ENTER(); pcb = &pmadapter->callbacks; /* Free adapter structure */ wlan_free_adapter(pmadapter); /* Free timers */ wlan_free_timer(pmadapter); /* Free lock variables */ wlan_free_lock_list(pmadapter); /* Free private structures */ for (i = 0; i < pmadapter->priv_num; i++) { if (pmadapter->priv[i]) { if (pcb->moal_vmalloc && pcb->moal_vfree) pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter->priv[i]); else pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter->priv[i]); } } /* Free mlan_adapter */ if (pcb->moal_vmalloc && pcb->moal_vfree) pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter); else pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter); LEAVE(); return ret; }
/** * @brief This function adds the card. it will probe the * card, allocate the wlan_priv and initialize the device. * * @param card A pointer to card * @return A pointer to wlan_private structure */ wlan_private * wlan_add_card(void *card) { struct net_device *dev = NULL; wlan_private *priv = NULL; ENTER(); if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) goto exit_sem_err; /* Allocate an Ethernet device and register it */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) if (!(dev = init_etherdev(dev, sizeof(wlan_private)))) { #else if (!(dev = alloc_etherdev(sizeof(wlan_private)))) { #endif PRINTM(MSG, "Init ethernet device failed!\n"); goto exit_add_err; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) /* Allocate device name */ if (dev_alloc_name(dev, "mlan%d") < 0) { PRINTM(ERROR, "Could not allocate device name!\n"); goto err_kmalloc; } #endif priv = (wlan_private *) netdev_priv(dev); /* allocate buffer for wlan_adapter */ if (!(priv->adapter = kmalloc(sizeof(wlan_adapter), GFP_KERNEL))) { PRINTM(MSG, "Allocate buffer for wlan_adapter failed!\n"); goto err_kmalloc; } /* init wlan_adapter */ memset(priv->adapter, 0, sizeof(wlan_adapter)); priv->wlan_dev.netdev = dev; priv->wlan_dev.card = card; ((struct sdio_mmc_card *) card)->priv = priv; wlanpriv = priv; //XXX FB global var a virer ? #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) SET_MODULE_OWNER(dev); #endif /* Setup the OS Interface to our functions */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) dev->open = wlan_open; dev->hard_start_xmit = wlan_hard_start_xmit; dev->stop = wlan_close; dev->do_ioctl = wlan_do_ioctl; dev->set_mac_address = wlan_set_mac_address; dev->set_multicast_list = wlan_set_multicast_list; dev->tx_timeout = wlan_tx_timeout; dev->get_stats = wlan_get_stats; #else dev->netdev_ops = &wlan_netdev_ops; #endif dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT; dev->hard_header_len += sizeof(TxPD); dev->hard_header_len += SDIO_HEADER_LEN; dev->hard_header_len += HEADER_ALIGNMENT; #ifdef WIRELESS_EXT #if WIRELESS_EXT < 21 dev->get_wireless_stats = wlan_get_wireless_stats; #endif dev->wireless_handlers = (struct iw_handler_def *) &wlan_handler_def; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) dev->features |= NETIF_F_DYNALLOC; #endif dev->flags |= IFF_BROADCAST | IFF_MULTICAST; /* init SW */ if (wlan_init_sw(priv)) { PRINTM(FATAL, "Software Init Failed\n"); goto err_kmalloc; } PRINTM(INFO, "Starting kthread...\n"); priv->MainThread.priv = priv; wlan_create_thread(wlan_service_main_thread, &priv->MainThread, "wlan_main_service"); ConfigureThreadPriority(); #ifdef REASSOCIATION priv->ReassocThread.priv = priv; wlan_create_thread(wlan_reassociation_thread, &priv->ReassocThread, "wlan_reassoc_service"); #endif /* REASSOCIATION */ while ((priv->MainThread.pid == 0) #ifdef REASSOCIATION || (priv->ReassocThread.pid == 0) #endif ) { os_sched_timeout(2); } /* * Register the device. Fill up the private data structure with * relevant information from the card and request for the required * IRQ. */ if (sbi_register_dev(priv) < 0) { PRINTM(FATAL, "Failed to register wlan device!\n"); goto err_registerdev; } SET_NETDEV_DEV(dev, priv->hotplug_device); /* init FW and HW */ if (wlan_init_fw(priv)) { PRINTM(FATAL, "Firmware Init Failed\n"); goto err_init_fw; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) SET_NETDEV_DEVTYPE(dev, &wlan_type); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) if (register_netdev(dev)) { printk(KERN_ERR "Cannot register network device!\n"); goto err_init_fw; } #endif os_carrier_off(priv); os_stop_queue(priv); PRINTM(INFO, "%s: WLAN 802.11 Adapter revision 0x%02X\n", dev->name, priv->adapter->chip_rev); #ifdef CONFIG_PROC_FS wlan_proc_entry(priv, dev); #ifdef PROC_DEBUG wlan_debug_entry(priv, dev); #endif #endif /* CONFIG_PROC_FS */ OS_REL_SEMAPHORE(&AddRemoveCardSem); LEAVE(); return priv; err_init_fw: sbi_unregister_dev(priv); err_registerdev: priv->adapter->SurpriseRemoved = TRUE; if (priv->MainThread.pid) { /* Stop the thread servicing the interrupts */ wake_up_interruptible(&priv->MainThread.waitQ); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) wlan_terminate_thread(&priv->MainThread); #endif } #ifdef REASSOCIATION if (priv->ReassocThread.pid) { wake_up_interruptible(&priv->ReassocThread.waitQ); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) wlan_terminate_thread(&priv->ReassocThread); #endif } #endif /* REASSOCIATION */ /* waiting for main thread quit */ while (priv->MainThread.pid #ifdef REASSOCIATION || priv->ReassocThread.pid #endif ) { os_sched_timeout(2); } err_kmalloc: if (dev->reg_state == NETREG_REGISTERED) unregister_netdev(dev); wlan_free_adapter(priv); priv->wlan_dev.netdev = NULL; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) free_netdev(dev); #endif ((struct sdio_mmc_card *) card)->priv = NULL; wlanpriv = NULL; exit_add_err: OS_REL_SEMAPHORE(&AddRemoveCardSem); exit_sem_err: LEAVE(); return NULL; } /** * @brief This function removes the card. * * @param card A pointer to card * @return WLAN_STATUS_SUCCESS */ int wlan_remove_card(void *card) { wlan_private *priv = ((struct sdio_mmc_card *) card)->priv; wlan_adapter *Adapter = NULL; struct net_device *dev; union iwreq_data wrqu; ENTER(); if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) goto exit_sem_err; if (!priv || !(Adapter = priv->adapter)) goto exit_remove; Adapter->SurpriseRemoved = TRUE; #ifdef REASSOCIATION if (Adapter->ReassocTimerIsSet == TRUE) { wlan_cancel_timer(&Adapter->MrvDrvTimer); Adapter->ReassocTimerIsSet = FALSE; } #endif if (Adapter->MediaConnectStatus == WlanMediaStateConnected) { Adapter->MediaConnectStatus = WlanMediaStateDisconnected; memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); wlan_clean_txrx(priv); } /* Release all pending commands */ wlan_clear_pending_cmd(priv); dev = priv->wlan_dev.netdev; /* Last reference is our one */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) PRINTM(INFO, "refcnt = %d\n", atomic_read(&dev->refcnt)); #else PRINTM(INFO, "refcnt = %d\n", netdev_refcnt_read(dev)); #endif PRINTM(INFO, "netdev_finish_unregister: %s\n", dev->name); if (dev->reg_state == NETREG_REGISTERED) unregister_netdev(dev); PRINTM(INFO, "Unregister finish\n"); if (priv->MainThread.pid) { /* Stop the thread servicing the interrupts */ wake_up_interruptible(&priv->MainThread.waitQ); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) wlan_terminate_thread(&priv->MainThread); #endif } #ifdef REASSOCIATION if (priv->ReassocThread.pid) { wake_up_interruptible(&priv->ReassocThread.waitQ); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) wlan_terminate_thread(&priv->ReassocThread); #endif } #endif /* REASSOCIATION */ /* waiting for thread quit */ while (priv->MainThread.pid #ifdef REASSOCIATION || priv->ReassocThread.pid #endif ) { os_sched_timeout(1); } wake_up_interruptible(&Adapter->HS_wait_q); if (Adapter->IsDeepSleep == TRUE) { Adapter->IsDeepSleep = FALSE; wake_up_interruptible(&Adapter->ds_awake_q); } #ifdef CONFIG_PROC_FS #ifdef PROC_DEBUG wlan_debug_remove(priv); #endif wlan_proc_remove(priv); #endif PRINTM(INFO, "unregister device\n"); sbi_unregister_dev(priv); PRINTM(INFO, "Free Adapter\n"); wlan_free_adapter(priv); priv->wlan_dev.netdev = NULL; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) free_netdev(dev); #endif wlanpriv = NULL; exit_remove: OS_REL_SEMAPHORE(&AddRemoveCardSem); exit_sem_err: LEAVE(); return WLAN_STATUS_SUCCESS; }
/** * @brief Shutdown firmware * * @param pmlan_adapter A pointer to mlan_adapter structure * * @return MLAN_STATUS_SUCCESS * The firmware shutdown call succeeded. * MLAN_STATUS_PENDING * The firmware shutdown call is pending. * MLAN_STATUS_FAILURE * The firmware shutdown call failed. */ mlan_status mlan_shutdown_fw(IN t_void * pmlan_adapter) { mlan_status ret = MLAN_STATUS_PENDING; mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter; mlan_private *priv = MNULL; pmlan_callbacks pcb; t_s32 i = 0; ENTER(); MASSERT(pmlan_adapter); /* mlan already shutdown */ if (pmadapter->hw_status == WlanHardwareStatusNotReady) return MLAN_STATUS_SUCCESS; pmadapter->hw_status = WlanHardwareStatusClosing; /* wait for mlan_process to complete */ if (pmadapter->mlan_processing) { PRINTM(MWARN, "mlan main processing is still running\n"); return ret; } /* shut down mlan */ PRINTM(MINFO, "Shutdown mlan...\n"); pcb = &pmadapter->callbacks; /* Clean up Tx/Rx queues and delete BSS priority table */ for (i = 0; i < MLAN_MAX_BSS_NUM; i++) { if (pmadapter->priv[i]) { priv = pmadapter->priv[i]; wlan_clean_txrx(priv); wlan_wmm_cleanup_node(priv); pcb->moal_free_lock(pmadapter->pmoal_handle, priv->rx_pkt_lock); wlan_delete_bsspriotbl(priv); pcb->moal_free_lock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock); #ifdef UAP_SUPPORT if (priv->bss_type == MLAN_BSS_TYPE_UAP) { wlan_delete_station_list(priv); util_free_list_head((t_void *) pmadapter->pmoal_handle, &priv->sta_list, priv->adapter->callbacks.moal_free_lock); } #endif /* UAP_SUPPORT */ } } for (i = 0; i < MLAN_MAX_BSS_NUM; i++) util_free_list_head((t_void *) pmadapter->pmoal_handle, &pmadapter->bssprio_tbl[i].bssprio_head, pcb->moal_free_lock); if (pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->pmlan_lock) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto exit_shutdown_fw; } /* Free adapter structure */ wlan_free_adapter(pmadapter); if (pcb->moal_spin_unlock(pmadapter->pmoal_handle, pmadapter->pmlan_lock) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto exit_shutdown_fw; } /* Notify completion */ ret = wlan_shutdown_fw_complete(pmadapter); exit_shutdown_fw: LEAVE(); return ret; }
/** * @brief This function registers MOAL to MLAN module. * * @param pmdevice A pointer to a mlan_device structure * allocated in MOAL * @param ppmlan_adapter A pointer to a t_void pointer to store * mlan_adapter structure pointer as the context * * @return MLAN_STATUS_SUCCESS * The registration succeeded. * MLAN_STATUS_FAILURE * The registration failed. * * mlan_status mlan_register ( * IN pmlan_device pmdevice, * OUT t_void **ppmlan_adapter * ); * * Comments * MOAL constructs mlan_device data structure to pass moal_handle and * mlan_callback table to MLAN. MLAN returns mlan_adapter pointer to * the ppmlan_adapter buffer provided by MOAL. * Headers: * declared in mlan_decl.h * See Also * mlan_unregister */ mlan_status mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter) { mlan_status ret = MLAN_STATUS_SUCCESS; pmlan_adapter pmadapter = MNULL; pmlan_callbacks pcb = MNULL; t_u8 i = 0; t_u32 j = 0; MASSERT(pmdevice); MASSERT(ppmlan_adapter); MASSERT(pmdevice->callbacks.moal_print); #ifdef DEBUG_LEVEL1 print_callback = pmdevice->callbacks.moal_print; get_sys_time_callback = pmdevice->callbacks.moal_get_system_time; #endif assert_callback = pmdevice->callbacks.moal_assert; ENTER(); MASSERT(pmdevice->callbacks.moal_malloc); MASSERT(pmdevice->callbacks.moal_memset); MASSERT(pmdevice->callbacks.moal_memmove); /* Allocate memory for adapter structure */ if (pmdevice->callbacks.moal_vmalloc && pmdevice->callbacks.moal_vfree) ret = pmdevice->callbacks.moal_vmalloc(pmdevice->pmoal_handle, sizeof(mlan_adapter), (t_u8 **) & pmadapter); else ret = pmdevice->callbacks.moal_malloc(pmdevice->pmoal_handle, sizeof(mlan_adapter), MLAN_MEM_DEF, (t_u8 **) & pmadapter); if ((ret != MLAN_STATUS_SUCCESS) || !pmadapter) { ret = MLAN_STATUS_FAILURE; goto exit_register; } pmdevice->callbacks.moal_memset(pmdevice->pmoal_handle, pmadapter, 0, sizeof(mlan_adapter)); pcb = &pmadapter->callbacks; /* Save callback functions */ pmdevice->callbacks.moal_memmove(pmadapter->pmoal_handle, pcb, &pmdevice->callbacks, sizeof(mlan_callbacks)); /* Assertion for all callback functions */ MASSERT(pcb->moal_init_fw_complete); MASSERT(pcb->moal_shutdown_fw_complete); MASSERT(pcb->moal_send_packet_complete); MASSERT(pcb->moal_recv_packet); MASSERT(pcb->moal_recv_event); MASSERT(pcb->moal_ioctl_complete); MASSERT(pcb->moal_write_reg); MASSERT(pcb->moal_read_reg); MASSERT(pcb->moal_alloc_mlan_buffer); MASSERT(pcb->moal_free_mlan_buffer); MASSERT(pcb->moal_write_data_sync); MASSERT(pcb->moal_read_data_sync); MASSERT(pcb->moal_mfree); MASSERT(pcb->moal_memcpy); MASSERT(pcb->moal_memcmp); MASSERT(pcb->moal_get_system_time); MASSERT(pcb->moal_init_timer); MASSERT(pcb->moal_free_timer); MASSERT(pcb->moal_start_timer); MASSERT(pcb->moal_stop_timer); MASSERT(pcb->moal_init_lock); MASSERT(pcb->moal_free_lock); MASSERT(pcb->moal_spin_lock); MASSERT(pcb->moal_spin_unlock); MASSERT(pcb->moal_tcp_ack_tx_ind); /* Save pmoal_handle */ pmadapter->pmoal_handle = pmdevice->pmoal_handle; if ((pmdevice->int_mode == INT_MODE_GPIO) && (pmdevice->gpio_pin == 0)) { PRINTM(MERROR, "SDIO_GPIO_INT_CONFIG: Invalid GPIO Pin\n"); ret = MLAN_STATUS_FAILURE; goto error; } pmadapter->init_para.int_mode = pmdevice->int_mode; pmadapter->init_para.gpio_pin = pmdevice->gpio_pin; /* card specific probing has been deferred until now .. */ ret = wlan_sdio_probe(pmadapter); if (MLAN_STATUS_SUCCESS != ret) { ret = MLAN_STATUS_FAILURE; goto error; } #ifdef DEBUG_LEVEL1 mlan_drvdbg = pmdevice->drvdbg; #endif #ifdef MFG_CMD_SUPPORT pmadapter->init_para.mfg_mode = pmdevice->mfg_mode; #endif #ifdef SDIO_MULTI_PORT_TX_AGGR pmadapter->init_para.mpa_tx_cfg = pmdevice->mpa_tx_cfg; #endif #ifdef SDIO_MULTI_PORT_RX_AGGR pmadapter->init_para.mpa_rx_cfg = pmdevice->mpa_rx_cfg; #endif pmadapter->init_para.auto_ds = pmdevice->auto_ds; pmadapter->init_para.ps_mode = pmdevice->ps_mode; if (pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_2K || pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_4K || pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_8K) pmadapter->init_para.max_tx_buf = pmdevice->max_tx_buf; #ifdef STA_SUPPORT pmadapter->init_para.cfg_11d = pmdevice->cfg_11d; #else pmadapter->init_para.cfg_11d = 0; #endif pmadapter->init_para.dfs_master_radar_det_en = DFS_MASTER_RADAR_DETECT_EN; pmadapter->init_para.dfs_slave_radar_det_en = DFS_SLAVE_RADAR_DETECT_EN; pmadapter->init_para.fw_crc_check = pmdevice->fw_crc_check; pmadapter->rx_work_flag = pmdevice->rx_work; pmadapter->priv_num = 0; for (i = 0; i < MLAN_MAX_BSS_NUM; i++) { pmadapter->priv[i] = MNULL; if (pmdevice->bss_attr[i].active == MTRUE) { /* For valid bss_attr, allocate memory for private structure */ if (pcb->moal_vmalloc && pcb->moal_vfree) ret = pcb->moal_vmalloc(pmadapter->pmoal_handle, sizeof(mlan_private), (t_u8 **) & pmadapter-> priv[i]); else ret = pcb->moal_malloc(pmadapter->pmoal_handle, sizeof(mlan_private), MLAN_MEM_DEF, (t_u8 **) & pmadapter-> priv[i]); if (ret != MLAN_STATUS_SUCCESS || !pmadapter->priv[i]) { ret = MLAN_STATUS_FAILURE; goto error; } pmadapter->priv_num++; memset(pmadapter, pmadapter->priv[i], 0, sizeof(mlan_private)); pmadapter->priv[i]->adapter = pmadapter; /* Save bss_type, frame_type & bss_priority */ pmadapter->priv[i]->bss_type = (t_u8) pmdevice->bss_attr[i].bss_type; pmadapter->priv[i]->frame_type = (t_u8) pmdevice->bss_attr[i].frame_type; pmadapter->priv[i]->bss_priority = (t_u8) pmdevice->bss_attr[i].bss_priority; if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_STA) pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_STA; else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_UAP) pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_UAP; #ifdef WIFI_DIRECT_SUPPORT else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_WIFIDIRECT) { pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_STA; if (pmdevice->bss_attr[i].bss_virtual) pmadapter->priv[i]->bss_virtual = MTRUE; } #endif /* Save bss_index and bss_num */ pmadapter->priv[i]->bss_index = i; pmadapter->priv[i]->bss_num = (t_u8) pmdevice->bss_attr[i].bss_num; /* init function table */ for (j = 0; mlan_ops[j]; j++) { if (mlan_ops[j]->bss_role == GET_BSS_ROLE(pmadapter->priv[i])) { memcpy(pmadapter, &pmadapter->priv[i]->ops, mlan_ops[j], sizeof(mlan_operations)); } } } } /* Initialize lock variables */ if (wlan_init_lock_list(pmadapter) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto error; } /* Allocate memory for member of adapter structure */ if (wlan_allocate_adapter(pmadapter)) { ret = MLAN_STATUS_FAILURE; goto error; } /* Initialize timers */ if (wlan_init_timer(pmadapter) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto error; } /* Return pointer of mlan_adapter to MOAL */ *ppmlan_adapter = pmadapter; goto exit_register; error: PRINTM(MINFO, "Leave mlan_register with error\n"); /* Free timers */ wlan_free_timer(pmadapter); /* Free adapter structure */ wlan_free_adapter(pmadapter); /* Free lock variables */ wlan_free_lock_list(pmadapter); for (i = 0; i < MLAN_MAX_BSS_NUM; i++) { if (pmadapter->priv[i]) { if (pcb->moal_vmalloc && pcb->moal_vfree) pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter->priv[i]); else pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter->priv[i]); } } if (pcb->moal_vmalloc && pcb->moal_vfree) pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter); else pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter); exit_register: LEAVE(); return ret; }
/** * @brief This function removes the card. * * @param priv A pointer to card * @return WLAN_STATUS_SUCCESS */ static int wlan_remove_card(void *card) { wlan_private *priv = &w99702_priv_data0; wlan_adapter *Adapter; //struct net_device *dev; struct cyg_netdevtab_entry *dev; struct eth_drv_sc *sc; union iwreq_data wrqu; ENTER(); if (!priv) { LEAVE(); return WLAN_STATUS_SUCCESS; } Adapter = priv->adapter; if (!Adapter) { LEAVE(); return WLAN_STATUS_SUCCESS; } dev = priv->wlan_dev.netdev; sc = (struct eth_drv_sc *)dev->device_instance; // wake_up_interruptible(&Adapter->ds_awake_q); cyg_cond_broadcast(&Adapter->ds_cond_q); if (Adapter->CurCmd) { diag_printf("Wake up current cmdwait_q\n"); // wake_up_interruptible(&Adapter->CurCmd->cmdwait_q); cyg_flag_setbits( &Adapter->CurCmd->cmdwait_flag_q, 3 ); } Adapter->CurCmd = NULL; if (Adapter->PSMode == Wlan802_11PowerModeMAX_PSP) { Adapter->PSMode = Wlan802_11PowerModeCAM; PSWakeup(priv, HostCmd_OPTION_WAITFORRSP); } if (Adapter->IsDeepSleep == TRUE) { Adapter->IsDeepSleep = FALSE; sbi_exit_deep_sleep(priv); } memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); /* Disable interrupts on the card as we cannot handle them after RESET */ sbi_disable_host_int(priv); PrepareAndSendCommand(priv, HostCmd_CMD_802_11_RESET, 0, 0, 0, NULL); cyg_thread_delay(20); //udelay(200*1000); #ifdef ENABLE_PM pm_unregister(wlan_pm_dev); #endif /* Flush all the packets upto the OS before stopping */ // wlan_send_rxskbQ(priv); eth_drv_dsr(0, 0, (cyg_addrword_t)sc); cleanup_txqueues(priv); // os_stop_queue(priv); // os_carrier_off(priv); Adapter->SurpriseRemoved = TRUE; /* Stop the thread servicing the interrupts */ //wake_up_interruptible(&priv->MainThread.waitQ); cyg_flag_setbits( &priv->MainThread.waitQ_flag_q, 1 ); #ifdef REASSOCIATION //wake_up_interruptible(&priv->ReassocThread.waitQ); cyg_flag_setbits( &priv->ReassocThread.waitQ_flag_q, 1 ); #endif /* REASSOCIATION */ #ifdef PROC_DEBUG wlan_debug_remove(priv); #endif // wlan_proc_remove(priv); diag_printf("unregester dev\n"); sbi_unregister_dev(priv); diag_printf("Free Adapter\n"); wlan_free_adapter(priv); /* Last reference is our one */ // diag_printf("refcnt = %d\n", atomic_read(&dev->refcnt)); // diag_printf("netdev_finish_unregister: %s%s.\n", dev->name, // (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style"); // unregister_netdev(dev); diag_printf("Unregister finish\n"); priv->wlan_dev.netdev = NULL; //free_netdev(dev); //wlanpriv = NULL; LEAVE(); return WLAN_STATUS_SUCCESS; }