summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/mvm
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2013-10-02 16:58:09 +0300
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-02-03 22:23:39 +0200
commit98ee7783062335984f5979cea6a08e79982a4061 (patch)
treeeff12a357e6afc9b3d14960038942ea747069ddc /drivers/net/wireless/iwlwifi/mvm
parentb3370d47f02eaeef52557259709589d81fdc573b (diff)
iwlwifi: add very first D0i3 support
When the bus is in D0i3, we can't send regular commands to the firmware. This means that we need to add a state to remember what is our d0i3 state and make sure that only d0i3 exit commands can be sent. Add flags to CMD_ flags and transport status for this purpose. Commands with CMD_HIGH_PRIO set are queued at the head of the command queue, behind other high priority commands. Commands with CMD_SEND_IN_IDLE set can be sent while the transport is idle (without taking rpm reference). Commands with CMD_MAKE_TRANS_IDLE set indicate that command completion should mark the transport as idle (and release the bus). Commands with CMD_WAKE_UP_TRANS set instruct the transport to exit from idle when this command is completed. The transport is marked as idle (STATUS_TRANS_IDLE) when the FW enters D0i3 state. This bit is cleared when it enters D0 state again. Process only commands with CMD_SEND_IN_IDLE flag while the transport is idle. Other enqueued commands will be processed only later, right after exiting D0i3. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Eliad Peller <eliadx.peller@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c15
2 files changed, 14 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 32844e3f5a85..3bf5f82658c5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -199,6 +199,7 @@ enum {
PROT_OFFLOAD_CONFIG_CMD = 0xd4,
OFFLOADS_QUERY_CMD = 0xd5,
REMOTE_WAKE_CONFIG_CMD = 0xd6,
+ D0I3_END_CMD = 0xed,
/* for WoWLAN in particular */
WOWLAN_PATTERNS = 0xe0,
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 0f87bc3b38d2..6e46b7c70473 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -291,6 +291,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(REDUCE_TX_POWER_CMD),
CMD(TX_ANT_CONFIGURATION_CMD),
CMD(D3_CONFIG_CMD),
+ CMD(D0I3_END_CMD),
CMD(PROT_OFFLOAD_CONFIG_CMD),
CMD(OFFLOADS_QUERY_CMD),
CMD(REMOTE_WAKE_CONFIG_CMD),
@@ -815,17 +816,27 @@ static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+ u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
+ struct iwl_d3_manager_config d3_cfg_cmd = {
+ .min_sleep_time = cpu_to_le32(1000),
+ };
IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
- return 0;
+
+ return iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD,
+ flags | CMD_MAKE_TRANS_IDLE,
+ sizeof(d3_cfg_cmd), &d3_cfg_cmd);
}
static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+ u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
+ CMD_WAKE_UP_TRANS;
IWL_DEBUG_RPM(mvm, "MVM exiting D0i3\n");
- return 0;
+
+ return iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
}
static const struct iwl_op_mode_ops iwl_mvm_ops = {