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);
}
Ejemplo n.º 2
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 (test_bit(ATH_OP_INVALID, &common->op_flags)) {
		ath_dbg(common, 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 CPTCFG_MAC80211_LEDS
	cancel_work_sync(&priv->led_work);
#endif
	ath9k_htc_stop_ani(priv);

	mutex_lock(&priv->mutex);

	ath9k_htc_stop_btcoex(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);

	set_bit(ATH_OP_INVALID, &common->op_flags);

	ath_dbg(common, CONFIG, "Driver halt\n");
	mutex_unlock(&priv->mutex);
}
Ejemplo n.º 3
0
static int ath_pci_suspend(struct device *device)
{
	struct pci_dev *pdev = to_pci_dev(device);
	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
	struct ath_softc *sc = hw->priv;

	/* The device has to be moved to FULLSLEEP forcibly.
	 * Otherwise the chip never moved to full sleep,
	 * when no interface is up.
	 */
	ath9k_hw_disable(sc->sc_ah);
	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);

	return 0;
}
Ejemplo n.º 4
0
static int ath_pci_suspend(struct device *device)
{
	struct pci_dev *pdev = to_pci_dev(device);
	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
	struct ath_softc *sc = hw->priv;
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);

	if (test_bit(ATH_OP_WOW_ENABLED, &common->op_flags)) {
		dev_info(&pdev->dev, "WOW is enabled, bypassing PCI suspend\n");
		return 0;
	}

	/* The device has to be moved to FULLSLEEP forcibly.
	 * Otherwise the chip never moved to full sleep,
	 * when no interface is up.
	 */
	ath9k_stop_btcoex(sc);
	ath9k_hw_disable(sc->sc_ah);
	del_timer_sync(&sc->sleep_timer);
	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);

	return 0;
}