/* * This function is used to shutdown the driver. * * The following operations are performed sequentially - * - Check if already shut down * - Make sure the main process has stopped * - Clean up the Tx and Rx queues * - Delete BSS priority tables * - Free the adapter * - Notify completion */ int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) { int ret = -EINPROGRESS; struct mwifiex_private *priv; s32 i; unsigned long flags; struct sk_buff *skb; /* mwifiex already shutdown */ if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY) return 0; adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING; /* wait for mwifiex_process to complete */ if (adapter->mwifiex_processing) { dev_warn(adapter->dev, "main process is still running\n"); return ret; } /* shut down mwifiex */ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); /* Clean up Tx/Rx queues and delete BSS priority table */ for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { priv = adapter->priv[i]; mwifiex_clean_txrx(priv); mwifiex_delete_bss_prio_tbl(priv); } } spin_lock_irqsave(&adapter->mwifiex_lock, flags); if (adapter->if_ops.data_complete) { while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) { struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); priv = adapter->priv[rx_info->bss_num]; if (priv) priv->stats.rx_dropped++; adapter->if_ops.data_complete(adapter, skb); } } /* Free adapter structure */ mwifiex_free_adapter(adapter); spin_unlock_irqrestore(&adapter->mwifiex_lock, flags); /* Notify completion */ ret = mwifiex_shutdown_fw_complete(adapter); return ret; }
/* * This function is used to shutdown the driver. * * The following operations are performed sequentially - * - Check if already shut down * - Make sure the main process has stopped * - Clean up the Tx and Rx queues * - Delete BSS priority tables * - Free the adapter * - Notify completion */ int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) { int ret = -EINPROGRESS; struct mwifiex_private *priv; s32 i; unsigned long flags; /* mwifiex already shutdown */ if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY) return 0; adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING; /* wait for mwifiex_process to complete */ if (adapter->mwifiex_processing) { dev_warn(adapter->dev, "main process is still running\n"); return ret; } /* cancel current command */ if (adapter->curr_cmd) { dev_warn(adapter->dev, "curr_cmd is still in processing\n"); del_timer(&adapter->cmd_timer); mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); adapter->curr_cmd = NULL; } /* shut down mwifiex */ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); /* Clean up Tx/Rx queues and delete BSS priority table */ for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { priv = adapter->priv[i]; mwifiex_clean_txrx(priv); mwifiex_delete_bss_prio_tbl(priv); } } spin_lock_irqsave(&adapter->mwifiex_lock, flags); /* Free adapter structure */ mwifiex_free_adapter(adapter); spin_unlock_irqrestore(&adapter->mwifiex_lock, flags); /* Notify completion */ ret = mwifiex_shutdown_fw_complete(adapter); return ret; }
/* * This function frees the private structure, including cleans * up the TX and RX queues and frees the BSS priority tables. */ void mwifiex_free_priv(struct mwifiex_private *priv) { mwifiex_clean_txrx(priv); mwifiex_delete_bss_prio_tbl(priv); mwifiex_free_curr_bcn(priv); }
/* * This function is used to shutdown the driver. * * The following operations are performed sequentially - * - Check if already shut down * - Make sure the main process has stopped * - Clean up the Tx and Rx queues * - Delete BSS priority tables * - Free the adapter * - Notify completion */ int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) { int ret = -EINPROGRESS; struct mwifiex_private *priv; s32 i; unsigned long flags; struct sk_buff *skb; /* mwifiex already shutdown */ if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY) return 0; adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING; /* wait for mwifiex_process to complete */ if (adapter->mwifiex_processing) { mwifiex_dbg(adapter, WARN, "main process is still running\n"); return ret; } /* cancel current command */ if (adapter->curr_cmd) { mwifiex_dbg(adapter, WARN, "curr_cmd is still in processing\n"); del_timer_sync(&adapter->cmd_timer); mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd); adapter->curr_cmd = NULL; } /* shut down mwifiex */ mwifiex_dbg(adapter, MSG, "info: shutdown mwifiex...\n"); /* Clean up Tx/Rx queues and delete BSS priority table */ for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { priv = adapter->priv[i]; mwifiex_clean_auto_tdls(priv); mwifiex_abort_cac(priv); mwifiex_clean_txrx(priv); mwifiex_delete_bss_prio_tbl(priv); } } atomic_set(&adapter->tx_queued, 0); while ((skb = skb_dequeue(&adapter->tx_data_q))) mwifiex_write_data_complete(adapter, skb, 0, 0); spin_lock_irqsave(&adapter->rx_proc_lock, flags); while ((skb = skb_dequeue(&adapter->rx_data_q))) { struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); atomic_dec(&adapter->rx_pending); priv = adapter->priv[rx_info->bss_num]; if (priv) priv->stats.rx_dropped++; dev_kfree_skb_any(skb); } spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); spin_lock(&adapter->mwifiex_lock); mwifiex_adapter_cleanup(adapter); spin_unlock(&adapter->mwifiex_lock); /* Notify completion */ ret = mwifiex_shutdown_fw_complete(adapter); return ret; }
/* * This function is used to shutdown the driver. * * The following operations are performed sequentially - * - Check if already shut down * - Make sure the main process has stopped * - Clean up the Tx and Rx queues * - Delete BSS priority tables * - Free the adapter * - Notify completion */ int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) { int ret = -EINPROGRESS; struct mwifiex_private *priv; s32 i; struct sk_buff *skb; /* mwifiex already shutdown */ if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY) return 0; adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING; /* wait for mwifiex_process to complete */ if (adapter->mwifiex_processing) { dev_warn(adapter->dev, "main process is still running\n"); return ret; } /* cancel current command */ if (adapter->curr_cmd) { dev_warn(adapter->dev, "curr_cmd is still in processing\n"); del_timer(&adapter->cmd_timer); mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd); adapter->curr_cmd = NULL; } /* shut down mwifiex */ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); /* Clean up Tx/Rx queues and delete BSS priority table */ for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { priv = adapter->priv[i]; mwifiex_clean_txrx(priv); mwifiex_delete_bss_prio_tbl(priv); } } spin_lock(&adapter->mwifiex_lock); if (adapter->if_ops.data_complete) { while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) { struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); priv = adapter->priv[rx_info->bss_num]; if (priv) priv->stats.rx_dropped++; dev_kfree_skb_any(skb); adapter->if_ops.data_complete(adapter); } } mwifiex_adapter_cleanup(adapter); spin_unlock(&adapter->mwifiex_lock); /* Notify completion */ ret = mwifiex_shutdown_fw_complete(adapter); return ret; }