From patchwork Sun Jan 30 19:11:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gnedt X-Patchwork-Id: 518191 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0UNUCQT007293 for ; Sun, 30 Jan 2011 23:31:59 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752037Ab1A3TLc (ORCPT ); Sun, 30 Jan 2011 14:11:32 -0500 Received: from mail.platinumzone24.at ([88.198.159.93]:60211 "EHLO mail.platinumzone24.at" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751523Ab1A3TLb (ORCPT ); Sun, 30 Jan 2011 14:11:31 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.platinumzone24.at (Postfix) with ESMTP id 14A8E850052; Sun, 30 Jan 2011 20:11:31 +0100 (CET) X-Virus-Scanned: amavisd-new at platinumzone24.at Received: from mail.platinumzone24.at ([127.0.0.1]) by localhost (localhost [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ALFwdNg2RMA1; Sun, 30 Jan 2011 20:11:24 +0100 (CET) Received: from [192.168.10.2] (212-183-124-82.adsl.highway.telekom.at [212.183.124.82]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: david.gnedt@platinumzone24.at) by mail.platinumzone24.at (Postfix) with ESMTP id 6403185004A; Sun, 30 Jan 2011 20:11:14 +0100 (CET) Message-ID: <4D45B7D1.5030005@davizone.at> Date: Sun, 30 Jan 2011 20:11:13 +0100 From: David Gnedt User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101208 Thunderbird/3.1.7 MIME-Version: 1.0 To: "John W. Linville" CC: linux-wireless@vger.kernel.org, Kalle Valo , Grazvydas Ignotas , "Denis 'GNUtoo' Carikli" Subject: [PATCH 13/18] wl1251: rework configure_filter() callback References: <4D45A5EE.6040108@davizone.at> In-Reply-To: <4D45A5EE.6040108@davizone.at> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sun, 30 Jan 2011 23:31:59 +0000 (UTC) diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/wl1251/cmd.c index 886da13..e70ec79 100644 --- a/drivers/net/wireless/wl1251/cmd.c +++ b/drivers/net/wireless/wl1251/cmd.c @@ -300,15 +300,6 @@ int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, join->rx_config_options = wl->rx_config; join->rx_filter_options = wl->rx_filter; - /* - * FIXME: disable temporarily all filters because after commit - * 9cef8737 "mac80211: fix managed mode BSSID handling" broke - * association. The filter logic needs to be implemented properly - * and once that is done, this hack can be removed. - */ - join->rx_config_options = 0; - join->rx_filter_options = WL1251_DEFAULT_RX_FILTER; - join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS | RATE_MASK_5_5MBPS | RATE_MASK_11MBPS; diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 5078705..cc49e2b 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -349,33 +349,6 @@ out: return ret; } -static void wl1251_filter_work(struct work_struct *work) -{ - struct wl1251 *wl = - container_of(work, struct wl1251, filter_work); - int ret; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1251_STATE_OFF) - goto out; - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int, - wl->dtim_period); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1251 *wl = hw->priv; @@ -481,7 +454,6 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); - cancel_work_sync(&wl->filter_work); mutex_lock(&wl->mutex); @@ -622,6 +594,16 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) ret = wl1251_acx_feature_cfg(wl, mode); if (ret < 0) goto out_sleep; + + if (wl->monitor_present) + wl->rx_config |= CFG_RX_ALL_GOOD; + else + wl->rx_config &= ~CFG_RX_ALL_GOOD; + + /* update filters immediately */ + ret = wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter); + if (ret < 0) + goto out_sleep; } if (channel != wl->channel) { @@ -691,6 +673,7 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, unsigned int *total,u64 multicast) { struct wl1251 *wl = hw->priv; + int ret; wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter"); @@ -701,15 +684,22 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, /* no filters which we support changed */ return; - /* FIXME: wl->rx_config and wl->rx_filter are not protected */ + mutex_lock(&wl->mutex); + + if (wl->state == WL1251_STATE_OFF) + goto out; + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; wl->rx_config = WL1251_DEFAULT_RX_CONFIG; wl->rx_filter = WL1251_DEFAULT_RX_FILTER; - if (*total & FIF_PROMISC_IN_BSS) { + if (!is_zero_ether_addr(wl->bssid)) wl->rx_config |= CFG_BSSID_FILTER_EN; - wl->rx_config |= CFG_RX_ALL_GOOD; - } + if (*total & FIF_PROMISC_IN_BSS) + wl->rx_config &= ~CFG_UNI_FILTER_EN; if (*total & FIF_ALLMULTI) /* * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive @@ -724,15 +714,27 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, } if (*total & FIF_CONTROL) wl->rx_filter |= CFG_RX_CTL_EN; - if (*total & FIF_OTHER_BSS) - wl->rx_filter &= ~CFG_BSSID_FILTER_EN; + if (*total & FIF_OTHER_BSS) { + wl->rx_config &= ~CFG_BSSID_FILTER_EN; + wl->rx_config &= ~CFG_SSID_FILTER_EN; + } + if (wl->monitor_present) + wl->rx_config |= CFG_RX_ALL_GOOD; - /* - * FIXME: workqueues need to be properly cancelled on stop(), for - * now let's just disable changing the filter settings. They will - * be updated any on config(). - */ - /* schedule_work(&wl->filter_work); */ + wl1251_debug(DEBUG_MAC80211, "mac80211 filter total 0x%02x" + " changed 0x%02x rx_config 0x%02x rx_filter 0x%02x", + *total, changed, wl->rx_config, wl->rx_filter); + + /* apply configured filters */ + ret = wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); } /* HW encryption */ @@ -999,6 +1001,11 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BSSID) { memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); + if (is_zero_ether_addr(wl->bssid)) + wl->rx_config &= ~CFG_BSSID_FILTER_EN; + else + wl->rx_config |= CFG_BSSID_FILTER_EN; + skb = ieee80211_nullfunc_get(wl->hw, wl->vif); if (!skb) goto out_sleep; @@ -1513,7 +1520,6 @@ struct ieee80211_hw *wl1251_alloc_hw(void) skb_queue_head_init(&wl->tx_queue); - INIT_WORK(&wl->filter_work, wl1251_filter_work); INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); wl->channel = WL1251_DEFAULT_CHANNEL; wl->monitor_present = false; diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index 875c1bf..1f9579c 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -92,13 +92,11 @@ enum { true); \ } while (0) -#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ - CFG_BSSID_FILTER_EN) +#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN) #define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \ CFG_RX_MGMT_EN | \ CFG_RX_DATA_EN | \ - CFG_RX_CTL_EN | \ CFG_RX_BCN_EN | \ CFG_RX_AUTH_EN | \ CFG_RX_ASSOC_EN) @@ -316,7 +314,6 @@ struct wl1251 { bool tx_queue_stopped; struct work_struct tx_work; - struct work_struct filter_work; /* Pending TX frames */ struct sk_buff *tx_frames[16];