static void ath9k_htc_stop(struct ieee80211_hw *hw)
{
	struct ath9k_htc_priv *priv = hw->priv;
	struct ath_hw *ah = priv->ah;
	struct ath_common *common = ath9k_hw_common(ah);
	int ret = 0;
	u8 cmd_rsp;

	mutex_lock(&priv->mutex);

	if (priv->op_flags & OP_INVALID) {
		ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
		mutex_unlock(&priv->mutex);
		return;
	}

	ath9k_htc_ps_wakeup(priv);
	htc_stop(priv->htc);
	WMI_CMD(WMI_DISABLE_INTR_CMDID);
	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
	WMI_CMD(WMI_STOP_RECV_CMDID);

	tasklet_kill(&priv->swba_tasklet);
	tasklet_kill(&priv->rx_tasklet);
	tasklet_kill(&priv->tx_tasklet);

	skb_queue_purge(&priv->tx_queue);

	mutex_unlock(&priv->mutex);

	/* Cancel all the running timers/work .. */
	cancel_work_sync(&priv->fatal_work);
	cancel_work_sync(&priv->ps_work);
	cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
	ath9k_htc_stop_ani(priv);
	ath9k_led_stop_brightness(priv);

	mutex_lock(&priv->mutex);

	if (ah->btcoex_hw.enabled) {
		ath9k_hw_btcoex_disable(ah);
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
			ath_htc_cancel_btcoex_work(priv);
	}

	/* Remove a monitor interface if it's present. */
	if (priv->ah->is_monitoring)
		ath9k_htc_remove_monitor_interface(priv);

	ath9k_hw_phy_disable(ah);
	ath9k_hw_disable(ah);
	ath9k_htc_ps_restore(priv);
	ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);

	priv->op_flags |= OP_INVALID;

	ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
	mutex_unlock(&priv->mutex);
}
Example #2
0
void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
{
	struct ath_hw *ah = priv->ah;

	if (ah->btcoex_hw.enabled &&
	    ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
			ath_htc_cancel_btcoex_work(priv);
		ath9k_hw_btcoex_disable(ah);
	}
}
Example #3
0
static void ath9k_htc_stop(struct ieee80211_hw *hw)
{
	struct ath9k_htc_priv *priv = hw->priv;
	struct ath_hw *ah = priv->ah;
	struct ath_common *common = ath9k_hw_common(ah);
	int ret __attribute__ ((unused));
	u8 cmd_rsp;

	mutex_lock(&priv->mutex);

	if (priv->op_flags & OP_INVALID) {
		ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
		mutex_unlock(&priv->mutex);
		return;
	}

	ath9k_htc_ps_wakeup(priv);

	WMI_CMD(WMI_DISABLE_INTR_CMDID);
	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
	WMI_CMD(WMI_STOP_RECV_CMDID);

	tasklet_kill(&priv->rx_tasklet);

	del_timer_sync(&priv->tx.cleanup_timer);
	ath9k_htc_tx_drain(priv);
	ath9k_wmi_event_drain(priv);

	mutex_unlock(&priv->mutex);

	/* Cancel all the running timers/work .. */
	cancel_work_sync(&priv->fatal_work);
	cancel_work_sync(&priv->ps_work);

#ifdef CONFIG_MAC80211_LEDS
	cancel_work_sync(&priv->led_work);
#endif
	ath9k_htc_stop_ani(priv);

	mutex_lock(&priv->mutex);

	if (ah->btcoex_hw.enabled) {
		ath9k_hw_btcoex_disable(ah);
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
			ath_htc_cancel_btcoex_work(priv);
	}

	/* Remove a monitor interface if it's present. */
	if (priv->ah->is_monitoring)
		ath9k_htc_remove_monitor_interface(priv);

	ath9k_hw_phy_disable(ah);
	ath9k_hw_disable(ah);
	ath9k_htc_ps_restore(priv);
	ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);

	priv->op_flags |= OP_INVALID;

	ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
	mutex_unlock(&priv->mutex);
}