From: Gavin Li <g...@thegavinli.com> Open up the filter if there is a monitor interface configured; this allows all packets on the channel to be captured even if the device is in STA mode and associated to a BSS.
Signed-off-by: Gavin Li <g...@thegavinli.com> --- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 3 +- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 42 +++++++++++++++++++---- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 ++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index fd2fc46e2fe5..ea98fc040aa8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -752,7 +752,8 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, cpu_to_le32(vif->bss_conf.use_short_slot ? MAC_FLG_SHORT_SLOT : 0); - cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP); + cmd->filter_flags = cpu_to_le32(mvm->addl_filter_flags | + MAC_FILTER_ACCEPT_GRP); for (i = 0; i < IEEE80211_NUM_ACS; i++) { u8 txf = iwl_mvm_ac_to_tx_fifo[i]; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index db5ad222e5ea..7c6d30ea3cf1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1641,6 +1641,13 @@ static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw, return (u64)(unsigned long)cmd; } +static void iwl_mvm_addl_ff_iface_iterator( + void *_mvm, u8 *mac, struct ieee80211_vif *vif) +{ + struct iwl_mvm *mvm = _mvm; + iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); +} + static void iwl_mvm_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, @@ -1648,20 +1655,41 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw, { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mcast_filter_cmd *cmd = (void *)(unsigned long)multicast; + const u32 supported_filters = + FIF_BCN_PRBRESP_PROMISC | + FIF_CONTROL | + FIF_OTHER_BSS | + FIF_PROBE_REQ; + u32 addl_filter_flags = 0; + + *total_flags &= supported_filters; + if (*total_flags & FIF_BCN_PRBRESP_PROMISC) + addl_filter_flags |= MAC_FILTER_IN_BEACON; + if (*total_flags & FIF_CONTROL) + addl_filter_flags |= MAC_FILTER_IN_CONTROL_AND_MGMT; + if (*total_flags & FIF_OTHER_BSS) + addl_filter_flags |= MAC_FILTER_IN_CONTROL_AND_MGMT | + MAC_FILTER_IN_PROMISC | + MAC_FILTER_IN_BEACON; + if (*total_flags & FIF_PROBE_REQ) + addl_filter_flags |= MAC_FILTER_IN_PROBE_REQUEST; + /* replace previous configuration */ mutex_lock(&mvm->mutex); - /* replace previous configuration */ + if (mvm->addl_filter_flags != addl_filter_flags) { + mvm->addl_filter_flags = addl_filter_flags; + ieee80211_iterate_active_interfaces( + mvm->hw, IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_addl_ff_iface_iterator, mvm); + } + kfree(mvm->mcast_filter_cmd); mvm->mcast_filter_cmd = cmd; + if (cmd) + iwl_mvm_recalc_multicast(mvm); - if (!cmd) - goto out; - - iwl_mvm_recalc_multicast(mvm); -out: mutex_unlock(&mvm->mutex); - *total_flags = 0; } static void iwl_mvm_config_iface_filter(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 52f8d7a6a7dc..827c413157c7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -832,6 +832,9 @@ struct iwl_mvm { /* configured by mac80211 */ u32 rts_threshold; + /* packets to pass as requested by mac80211 */ + u32 addl_filter_flags; + /* Scan status, cmd (pre-allocated) and auxiliary station */ unsigned int scan_status; void *scan_cmd; -- 2.14.1