From patchwork Tue Dec 17 20:44:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emmanuel Grumbach X-Patchwork-Id: 3365331 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1176E9F3AE for ; Tue, 17 Dec 2013 20:45:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C5CF7203C4 for ; Tue, 17 Dec 2013 20:45:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6127E203AD for ; Tue, 17 Dec 2013 20:45:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753874Ab3LQUpA (ORCPT ); Tue, 17 Dec 2013 15:45:00 -0500 Received: from mail-ee0-f50.google.com ([74.125.83.50]:32783 "EHLO mail-ee0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753870Ab3LQUo7 (ORCPT ); Tue, 17 Dec 2013 15:44:59 -0500 Received: by mail-ee0-f50.google.com with SMTP id c41so3192244eek.9 for ; Tue, 17 Dec 2013 12:44:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WNzG20H70SLirwOXqACjjZkl8Tz+IJeMXq8JB7MlVmU=; b=lNTbGKeGe9DFz8xZqohHsGWLP4651R3Vka4xkRPDbytomvKss2DdhRPm04NkQLaOi/ wD3xrfgUsqaquetgvuNlb+1wR5GbCi3Kp4jvVcYUHnCQQWQ5aHIo5V46G0uJQOTFPeVY mzteP71EkQpcQClqDrdJImKKi6HnAlRGXvIjrWLAvRLBheHFuI8+bfiF3+s0R5qkdMdZ 2OWHGbdfkDT7xpSv8oEpfjhtReYHZq/TFkooUWtGzFcEWAF+/EaCld8Ty8uvKNsijyKd UEcqCoUREp8pww84EAy1DGvDv8GIMvxa+01d/J//5Z60r9p0VSpdGWtWnmfhjX1KNjxH x+yA== X-Received: by 10.15.32.73 with SMTP id z49mr25152040eeu.27.1387313097833; Tue, 17 Dec 2013 12:44:57 -0800 (PST) Received: from localhost.localdomain (93-173-242-52.bb.netvision.net.il. [93.173.242.52]) by mx.google.com with ESMTPSA id 4sm56278497eed.14.2013.12.17.12.44.56 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 17 Dec 2013 12:44:57 -0800 (PST) From: Emmanuel Grumbach To: linux-wireless@vger.kernel.org Cc: Alexander Bondar , Emmanuel Grumbach Subject: [PATCH 09/36] iwlwifi: mvm: Disable power save for monitor interface Date: Tue, 17 Dec 2013 22:44:12 +0200 Message-Id: <1387313079-28123-9-git-send-email-egrumbach@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <52B0B72A.5070704@gmail.com> References: <52B0B72A.5070704@gmail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Alexander Bondar When monitor interface is activated device power save needs to be disabled. Re-consider power management status on other active interfaces when monitor interface is bound or unbound. Signed-off-by: Alexander Bondar Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 15 ++++++++++----- drivers/net/wireless/iwlwifi/mvm/mvm.h | 10 +++++++--- drivers/net/wireless/iwlwifi/mvm/power.c | 22 ++++++++++++++++++---- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index e1c379a..d36105f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1610,7 +1610,13 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw, goto out_unlock; /* - * Setting the quota at this stage is only required for monitor + * Power state must be updated before quotas, + * otherwise fw will complain. + */ + mvm->bound_vif_cnt++; + iwl_mvm_power_update_binding(mvm, vif, true); + + /* Setting the quota at this stage is only required for monitor * interfaces. For the other types, the bss_info changed flow * will handle quota settings. */ @@ -1621,13 +1627,12 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw, goto out_remove_binding; } - mvm->bound_vif_cnt++; - iwl_mvm_power_update_binding(mvm, vif); - goto out_unlock; out_remove_binding: iwl_mvm_binding_remove_vif(mvm, vif); + mvm->bound_vif_cnt--; + iwl_mvm_power_update_binding(mvm, vif, false); out_unlock: mutex_unlock(&mvm->mutex); if (ret) @@ -1662,7 +1667,7 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw, out_unlock: mvmvif->phy_ctxt = NULL; mvm->bound_vif_cnt--; - iwl_mvm_power_update_binding(mvm, vif); + iwl_mvm_power_update_binding(mvm, vif, false); mutex_unlock(&mvm->mutex); } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 51b0e9a..7295f8e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -164,7 +164,7 @@ struct iwl_mvm_power_ops { int (*power_update_device_mode)(struct iwl_mvm *mvm); int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); void (*power_update_binding)(struct iwl_mvm *mvm, - struct ieee80211_vif *vif); + struct ieee80211_vif *vif, bool assign); #ifdef CONFIG_IWLWIFI_DEBUGFS int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, char *buf, int bufsz); @@ -568,6 +568,9 @@ struct iwl_mvm { u8 last_agg_queue; u8 bound_vif_cnt; + + /* Indicate if device power save is allowed */ + bool ps_prevented; }; /* Extract MVM priv from op_mode and _hw */ @@ -787,10 +790,11 @@ static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm) } static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) + struct ieee80211_vif *vif, + bool assign) { if (mvm->pm_ops->power_update_binding) - mvm->pm_ops->power_update_binding(mvm, vif); + mvm->pm_ops->power_update_binding(mvm, vif, assign); } void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index d5d4935..cfed105 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -301,7 +301,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); cmd->keep_alive_seconds = cpu_to_le16(keep_alive); - if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) + if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM || + mvm->ps_prevented) return; cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); @@ -447,7 +448,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, sizeof(cmd), &cmd); } -static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) +static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable) { struct iwl_device_power_cmd cmd = { .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), @@ -456,7 +457,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) return 0; - if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) + if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM || + force_disable) cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -473,6 +475,11 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) &cmd); } +static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) +{ + return _iwl_mvm_power_update_device(mvm, false); +} + void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); @@ -525,8 +532,15 @@ static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac, } static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) + struct ieee80211_vif *vif, + bool assign) { + if (vif->type == NL80211_IFTYPE_MONITOR) { + int ret = _iwl_mvm_power_update_device(mvm, assign); + mvm->ps_prevented = assign; + WARN_ONCE(ret, "Failed to update power device state\n"); + } + ieee80211_iterate_active_interfaces(mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_power_binding_iterator,