/** * @brief This function frees the structure of adapter * * @param pmadapter A pointer to mlan_adapter structure * * @return N/A */ t_void wlan_free_adapter(pmlan_adapter pmadapter) { mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks; ENTER(); if (!pmadapter) { PRINTM(MERROR, "The adapter is MNULL.\n"); LEAVE(); return; } wlan_cancel_all_pending_cmd(pmadapter); /* Free command buffer */ PRINTM(MINFO, "Free Command buffer\n"); wlan_free_cmd_buffer(pmadapter); util_free_list_head(&pmadapter->cmd_free_q, pmadapter->callbacks.moal_free_lock); util_free_list_head(&pmadapter->cmd_pending_q, pmadapter->callbacks.moal_free_lock); util_free_list_head(&pmadapter->scan_pending_q, pmadapter->callbacks.moal_free_lock); if (pmadapter->cmd_timer_is_set) { /* Cancel command timeout timer */ pcb->moal_stop_timer(pmadapter->pmlan_cmd_timer); pmadapter->cmd_timer_is_set = MFALSE; } PRINTM(MINFO, "Free ScanTable\n"); if (pmadapter->pscan_table) { pcb->moal_mfree((t_u8 *) pmadapter->pscan_table); pmadapter->pscan_table = MNULL; } if (pmadapter->mp_regs_buf) { pcb->moal_mfree((t_u8 *) pmadapter->mp_regs_buf); pmadapter->mp_regs_buf = MNULL; pmadapter->mp_regs = MNULL; } #if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR) wlan_free_sdio_mpa_buffers(pmadapter); #endif wlan_free_mlan_buffer(&pmadapter->callbacks, pmadapter->psleep_cfm); LEAVE(); return; }
/** * @brief This function frees the structure of adapter * * @param pmadapter A pointer to mlan_adapter structure * * @return N/A */ t_void wlan_free_adapter(pmlan_adapter pmadapter) { mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks; ENTER(); if (!pmadapter) { PRINTM(ERROR, "The adapter is MNULL.\n"); LEAVE(); return; } wlan_cancel_all_pending_cmd(pmadapter); /* Free command buffer */ PRINTM(INFO, "Free Command buffer\n"); wlan_free_cmd_buffer(pmadapter); util_free_list_head(&pmadapter->cmd_free_q, pmadapter->callbacks.moal_free_lock); util_free_list_head(&pmadapter->cmd_pending_q, pmadapter->callbacks.moal_free_lock); util_free_list_head(&pmadapter->scan_pending_q, pmadapter->callbacks.moal_free_lock); if (pmadapter->cmd_timer_is_set) { /* Cancel command timeout timer */ pcb->moal_stop_timer(pmadapter->pmlan_cmd_timer); pmadapter->cmd_timer_is_set = MFALSE; } if (pmadapter->hb_host_timer_is_set) { pcb->moal_stop_timer(pmadapter->hb_host_timer); pmadapter->hb_host_timer_is_set = MFALSE; } if (pmadapter->hb_dev_timer_is_set) { pcb->moal_stop_timer(pmadapter->hb_device_timer); pmadapter->hb_dev_timer_is_set = MFALSE; } PRINTM(INFO, "Free ScanTable\n"); if (pmadapter->pscan_table) { pcb->moal_mfree((t_u8 *) pmadapter->pscan_table); pmadapter->pscan_table = MNULL; } LEAVE(); return; }
/** * @brief This function releases the lock variables * * @param pmadapter A pointer to a mlan_adapter structure * * @return None * */ t_void wlan_free_lock_list(IN pmlan_adapter pmadapter) { pmlan_private priv = MNULL; pmlan_callbacks pcb = &pmadapter->callbacks; t_s32 i = 0; t_s32 j = 0; ENTER(); if (pmadapter->pmlan_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, pmadapter->pmlan_lock); if (pmadapter->pint_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, pmadapter->pint_lock); if (pmadapter->pmain_proc_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, pmadapter->pmain_proc_lock); if (pmadapter->pmlan_cmd_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, pmadapter->pmlan_cmd_lock); for (i = 0; i < pmadapter->priv_num; i++) { if (pmadapter->priv[i]) { priv = pmadapter->priv[i]; if (priv->rx_pkt_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, priv->rx_pkt_lock); if (priv->wmm.ra_list_spinlock) pcb->moal_free_lock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock); #ifdef STA_SUPPORT if (priv->curr_bcn_buf_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, priv->curr_bcn_buf_lock); #endif } } /* Free lists */ util_free_list_head((t_void *) pmadapter->pmoal_handle, &pmadapter->bypass_txq, pmadapter->callbacks.moal_free_lock); util_free_list_head((t_void *) pmadapter->pmoal_handle, &pmadapter->cmd_free_q, pmadapter->callbacks.moal_free_lock); util_free_list_head((t_void *) pmadapter->pmoal_handle, &pmadapter->cmd_pending_q, pmadapter->callbacks.moal_free_lock); util_free_list_head((t_void *) pmadapter->pmoal_handle, &pmadapter->scan_pending_q, pmadapter->callbacks.moal_free_lock); for (i = 0; i < pmadapter->priv_num; i++) util_free_list_head((t_void *) pmadapter->pmoal_handle, &pmadapter->bssprio_tbl[i].bssprio_head, pcb->moal_free_lock); for (i = 0; i < pmadapter->priv_num; i++) { if (pmadapter->priv[i]) { priv = pmadapter->priv[i]; util_free_list_head((t_void *) pmadapter->pmoal_handle, &priv->sta_list, priv->adapter->callbacks.moal_free_lock); for (j = 0; j < MAX_NUM_TID; ++j) util_free_list_head((t_void *) priv->adapter->pmoal_handle, &priv->wmm.tid_tbl_ptr[j].ra_list, priv->adapter->callbacks.moal_free_lock); util_free_list_head((t_void *) priv->adapter->pmoal_handle, &priv->tx_ba_stream_tbl_ptr, priv->adapter->callbacks.moal_free_lock); util_free_list_head((t_void *) priv->adapter->pmoal_handle, &priv->rx_reorder_tbl_ptr, priv->adapter->callbacks.moal_free_lock); util_scalar_free((t_void *) priv->adapter->pmoal_handle, &priv->wmm.tx_pkts_queued, priv->adapter->callbacks.moal_free_lock); util_scalar_free((t_void *) priv->adapter->pmoal_handle, &priv->wmm.highest_queued_prio, priv->adapter->callbacks.moal_free_lock); } } LEAVE(); return; }
/** * @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; }