aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-mac80211.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h11
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
1306static 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
1306static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, 1317static 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
1642static int iwl_trans_pcie_suspend(struct iwl_trans *trans) 1653static 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
404static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans)
405{
406 might_sleep();
407 trans->ops->wowlan_suspend(trans);
408}
409
399static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, 410static 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)