From b460713a5a2927998729fd22d9c649bcc9f1a9de Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Pouiller?= <jerome.pouiller@silabs.com> Date: Wed, 15 Apr 2020 18:11:30 +0200 Subject: [PATCH] staging: wfx: rework wfx_configure_filter() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit wfx_configure_filter() lacks of coherency. In add, some corner cases seems to not been handled properly. Rework the whole function(). Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com> Link: https://lore.kernel.org/r/20200415161147.69738-4-Jerome.Pouiller@silabs.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/staging/wfx/sta.c | 41 +++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 14e2f106b042a..ec949ce0b2564 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -203,7 +203,6 @@ u64 wfx_prepare_multicast(struct ieee80211_hw *hw, ha->addr); i++; } - wvif->mcast_filter.enable = true; wvif->mcast_filter.num_addresses = count; } @@ -218,16 +217,46 @@ void wfx_configure_filter(struct ieee80211_hw *hw, struct wfx_vif *wvif = NULL; struct wfx_dev *wdev = hw->priv; - *total_flags &= FIF_OTHER_BSS | FIF_FCSFAIL | FIF_PROBE_REQ; + // Notes: + // - Probe responses (FIF_BCN_PRBRESP_PROMISC) are never filtered + // - PS-Poll (FIF_PSPOLL) are never filtered + // - RTS, CTS and Ack (FIF_CONTROL) are always filtered + // - Broken frames (FIF_FCSFAIL and FIF_PLCPFAIL) are always filtered + // - Firmware does (yet) allow to forward unicast traffic sent to + // other stations (aka. promiscuous mode) + *total_flags &= FIF_BCN_PRBRESP_PROMISC | FIF_ALLMULTI | FIF_OTHER_BSS | + FIF_PROBE_REQ | FIF_PSPOLL; mutex_lock(&wdev->conf_mutex); while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { mutex_lock(&wvif->scan_lock); - wvif->filter_bssid = (*total_flags & - (FIF_OTHER_BSS | FIF_PROBE_REQ)) ? 0 : 1; - wvif->disable_beacon_filter = !(*total_flags & FIF_PROBE_REQ); - wfx_fwd_probe_req(wvif, true); + + // Note: FIF_BCN_PRBRESP_PROMISC covers probe response and + // beacons from other BSS + if (*total_flags & FIF_BCN_PRBRESP_PROMISC) + wvif->disable_beacon_filter = true; + else + wvif->disable_beacon_filter = false; + + if (*total_flags & FIF_ALLMULTI) { + wvif->mcast_filter.enable = false; + } else if (!wvif->mcast_filter.num_addresses) { + dev_dbg(wdev->dev, "disabling unconfigured multicast filter"); + wvif->mcast_filter.enable = false; + } else { + wvif->mcast_filter.enable = true; + } wfx_update_filtering(wvif); + + if (*total_flags & FIF_OTHER_BSS) + wvif->filter_bssid = false; + else + wvif->filter_bssid = true; + + if (*total_flags & FIF_PROBE_REQ) + wfx_fwd_probe_req(wvif, true); + else + wfx_fwd_probe_req(wvif, false); mutex_unlock(&wvif->scan_lock); } mutex_unlock(&wdev->conf_mutex); -- 2.30.2