diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-mac80211.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.h | 11 |
3 files changed, 26 insertions, 22 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 8b26f3217823..8c7ca7318c00 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -196,6 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
196 | WIPHY_FLAG_IBSS_RSN; | 196 | WIPHY_FLAG_IBSS_RSN; |
197 | 197 | ||
198 | if (nic(priv)->fw.ucode_wowlan.code.len && | 198 | if (nic(priv)->fw.ucode_wowlan.code.len && |
199 | trans(priv)->ops->wowlan_suspend && | ||
199 | device_can_wakeup(trans(priv)->dev)) { | 200 | device_can_wakeup(trans(priv)->dev)) { |
200 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | 201 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | |
201 | WIPHY_WOWLAN_DISCONNECT | | 202 | WIPHY_WOWLAN_DISCONNECT | |
@@ -412,9 +413,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | |||
412 | 413 | ||
413 | device_set_wakeup_enable(trans(priv)->dev, true); | 414 | device_set_wakeup_enable(trans(priv)->dev, true); |
414 | 415 | ||
415 | /* Now let the ucode operate on its own */ | 416 | iwl_trans_wowlan_suspend(trans(priv)); |
416 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, | ||
417 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
418 | 417 | ||
419 | goto out; | 418 | goto out; |
420 | 419 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index f47426a5ef4d..bb8f2fdf1281 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -1303,6 +1303,17 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1303 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 1303 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | ||
1307 | { | ||
1308 | /* let the ucode operate on its own */ | ||
1309 | iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, | ||
1310 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
1311 | |||
1312 | iwl_disable_interrupts(trans); | ||
1313 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
1314 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1315 | } | ||
1316 | |||
1306 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 1317 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
1307 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 1318 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
1308 | u8 sta_id, u8 tid) | 1319 | u8 sta_id, u8 tid) |
@@ -1641,25 +1652,6 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1641 | #ifdef CONFIG_PM_SLEEP | 1652 | #ifdef CONFIG_PM_SLEEP |
1642 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) | 1653 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) |
1643 | { | 1654 | { |
1644 | /* | ||
1645 | * This function is called when system goes into suspend state | ||
1646 | * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend | ||
1647 | * function first but since iwlagn_mac_stop() has no knowledge of | ||
1648 | * who the caller is, | ||
1649 | * it will not call apm_ops.stop() to stop the DMA operation. | ||
1650 | * Calling apm_ops.stop here to make sure we stop the DMA. | ||
1651 | * | ||
1652 | * But of course ... if we have configured WoWLAN then we did other | ||
1653 | * things already :-) | ||
1654 | */ | ||
1655 | if (!trans->shrd->wowlan) { | ||
1656 | iwl_apm_stop(trans); | ||
1657 | } else { | ||
1658 | iwl_disable_interrupts(trans); | ||
1659 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
1660 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1661 | } | ||
1662 | |||
1663 | return 0; | 1655 | return 0; |
1664 | } | 1656 | } |
1665 | 1657 | ||
@@ -2227,6 +2219,8 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2227 | .start_fw = iwl_trans_pcie_start_fw, | 2219 | .start_fw = iwl_trans_pcie_start_fw, |
2228 | .stop_device = iwl_trans_pcie_stop_device, | 2220 | .stop_device = iwl_trans_pcie_stop_device, |
2229 | 2221 | ||
2222 | .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, | ||
2223 | |||
2230 | .wake_any_queue = iwl_trans_pcie_wake_any_queue, | 2224 | .wake_any_queue = iwl_trans_pcie_wake_any_queue, |
2231 | 2225 | ||
2232 | .send_cmd = iwl_trans_pcie_send_cmd, | 2226 | .send_cmd = iwl_trans_pcie_send_cmd, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index e2f21cfc2cd4..83f04c9d77e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -210,6 +210,9 @@ struct iwl_host_cmd { | |||
210 | * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* | 210 | * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* |
211 | * @stop_device:stops the whole device (embedded CPU put to reset) | 211 | * @stop_device:stops the whole device (embedded CPU put to reset) |
212 | * May sleep | 212 | * May sleep |
213 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during | ||
214 | * suspend. This is optional, if not implemented WoWLAN will not be | ||
215 | * supported. This callback may sleep. | ||
213 | * @send_cmd:send a host command | 216 | * @send_cmd:send a host command |
214 | * May sleep only if CMD_SYNC is set | 217 | * May sleep only if CMD_SYNC is set |
215 | * @tx: send an skb | 218 | * @tx: send an skb |
@@ -247,6 +250,8 @@ struct iwl_trans_ops { | |||
247 | void (*fw_alive)(struct iwl_trans *trans); | 250 | void (*fw_alive)(struct iwl_trans *trans); |
248 | void (*stop_device)(struct iwl_trans *trans); | 251 | void (*stop_device)(struct iwl_trans *trans); |
249 | 252 | ||
253 | void (*wowlan_suspend)(struct iwl_trans *trans); | ||
254 | |||
250 | void (*wake_any_queue)(struct iwl_trans *trans, | 255 | void (*wake_any_queue)(struct iwl_trans *trans, |
251 | enum iwl_rxon_context_id ctx, | 256 | enum iwl_rxon_context_id ctx, |
252 | const char *msg); | 257 | const char *msg); |
@@ -396,6 +401,12 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) | |||
396 | trans->state = IWL_TRANS_NO_FW; | 401 | trans->state = IWL_TRANS_NO_FW; |
397 | } | 402 | } |
398 | 403 | ||
404 | static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) | ||
405 | { | ||
406 | might_sleep(); | ||
407 | trans->ops->wowlan_suspend(trans); | ||
408 | } | ||
409 | |||
399 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, | 410 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, |
400 | enum iwl_rxon_context_id ctx, | 411 | enum iwl_rxon_context_id ctx, |
401 | const char *msg) | 412 | const char *msg) |