* [PATCH 1/2] mac80211: make beacon filtering per virtual interface
2012-01-19 8:29 [PATCH 0/2] per interface configuration Johannes Berg
@ 2012-01-19 8:29 ` Johannes Berg
2012-01-20 6:22 ` Luciano Coelho
2012-01-19 8:29 ` [PATCH 2/2] mac80211: make CQM RSSI support " Johannes Berg
1 sibling, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2012-01-19 8:29 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Due to firmware limitations, we may not be able to
support beacon filtering on all virtual interfaces.
To allow this in mac80211, introduce per-interface
driver capability flags that the driver sets when
an interface is added.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
drivers/net/wireless/p54/main.c | 3 ++-
drivers/net/wireless/rtlwifi/base.c | 1 -
drivers/net/wireless/rtlwifi/core.c | 2 ++
drivers/net/wireless/wl1251/main.c | 3 ++-
drivers/net/wireless/wl12xx/main.c | 3 ++-
include/net/mac80211.h | 29 ++++++++++++++++++++---------
net/mac80211/debugfs.c | 2 --
net/mac80211/mlme.c | 2 +-
8 files changed, 29 insertions(+), 16 deletions(-)
--- a/include/net/mac80211.h 2012-01-19 09:10:33.000000000 +0100
+++ b/include/net/mac80211.h 2012-01-19 09:22:06.000000000 +0100
@@ -852,6 +852,16 @@ struct ieee80211_channel_switch {
};
/**
+ * enum ieee80211_vif_flags - virtual interface flags
+ *
+ * @IEEE80211_VIF_BEACON_FILTER: the device performs beacon filtering
+ * on this virtual interface to avoid unnecessary CPU wakeups
+ */
+enum ieee80211_vif_flags {
+ IEEE80211_VIF_BEACON_FILTER = BIT(0),
+};
+
+/**
* struct ieee80211_vif - per-interface data
*
* Data in this structure is continually present for driver
@@ -863,6 +873,10 @@ struct ieee80211_channel_switch {
* @addr: address of this interface
* @p2p: indicates whether this AP or STA interface is a p2p
* interface, i.e. a GO or p2p-sta respectively
+ * @driver_flags: flags/capabilities the driver has for this interface,
+ * these need to be set (or cleared) when the interface is added
+ * or, if supported by the driver, the interface type is changed
+ * at runtime, mac80211 will never touch this field
* @drv_priv: data area for driver use, will always be aligned to
* sizeof(void *).
*/
@@ -871,6 +885,7 @@ struct ieee80211_vif {
struct ieee80211_bss_conf bss_conf;
u8 addr[ETH_ALEN];
bool p2p;
+ u32 driver_flags;
/* must be last */
u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
};
@@ -1079,10 +1094,6 @@ enum sta_notify_cmd {
* @IEEE80211_HW_MFP_CAPABLE:
* Hardware supports management frame protection (MFP, IEEE 802.11w).
*
- * @IEEE80211_HW_BEACON_FILTER:
- * Hardware supports dropping of irrelevant beacon frames to
- * avoid waking up cpu.
- *
* @IEEE80211_HW_SUPPORTS_STATIC_SMPS:
* Hardware supports static spatial multiplexing powersave,
* ie. can turn off all but one chain even on HT connections
@@ -1150,7 +1161,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_PS_NULLFUNC_STACK = 1<<11,
IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12,
IEEE80211_HW_MFP_CAPABLE = 1<<13,
- IEEE80211_HW_BEACON_FILTER = 1<<14,
+ /* reuse bit 14 */
IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15,
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16,
IEEE80211_HW_SUPPORTS_UAPSD = 1<<17,
@@ -1446,8 +1457,8 @@ void ieee80211_free_txskb(struct ieee802
* way the host will only receive beacons where some relevant information
* (for example ERP protection or WMM settings) have changed.
*
- * Beacon filter support is advertised with the %IEEE80211_HW_BEACON_FILTER
- * hardware capability. The driver needs to enable beacon filter support
+ * Beacon filter support is advertised with the %IEEE80211_VIF_BEACON_FILTER
+ * interface capability. The driver needs to enable beacon filter support
* whenever power save is enabled, that is %IEEE80211_CONF_PS is set. When
* power save is enabled, the stack will not check for beacon loss and the
* driver needs to notify about loss of beacons with ieee80211_beacon_loss().
@@ -3316,7 +3327,7 @@ struct sk_buff *ieee80211_ap_probereq_ge
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
*
- * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER and
+ * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER and
* %IEEE80211_CONF_PS is set, the driver needs to inform whenever the
* hardware is not receiving beacons with this function.
*/
@@ -3327,7 +3338,7 @@ void ieee80211_beacon_loss(struct ieee80
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
*
- * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER, and
+ * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and
* %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver
* needs to inform if the connection to the AP has been lost.
*
--- a/net/mac80211/debugfs.c 2012-01-19 09:10:33.000000000 +0100
+++ b/net/mac80211/debugfs.c 2012-01-19 09:22:06.000000000 +0100
@@ -247,8 +247,6 @@ static ssize_t hwflags_read(struct file
sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n");
if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE)
sf += snprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n");
- if (local->hw.flags & IEEE80211_HW_BEACON_FILTER)
- sf += snprintf(buf + sf, mxln - sf, "BEACON_FILTER\n");
if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS)
sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n");
if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
--- a/net/mac80211/mlme.c 2012-01-19 09:10:33.000000000 +0100
+++ b/net/mac80211/mlme.c 2012-01-19 09:22:06.000000000 +0100
@@ -127,7 +127,7 @@ static void run_again(struct ieee80211_i
void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
{
- if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
+ if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
return;
mod_timer(&sdata->u.mgd.bcn_mon_timer,
--- a/drivers/net/wireless/p54/main.c 2012-01-19 09:10:33.000000000 +0100
+++ b/drivers/net/wireless/p54/main.c 2012-01-19 09:10:34.000000000 +0100
@@ -228,6 +228,8 @@ static int p54_add_interface(struct ieee
{
struct p54_common *priv = dev->priv;
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+
mutex_lock(&priv->conf_mutex);
if (priv->mode != NL80211_IFTYPE_MONITOR) {
mutex_unlock(&priv->conf_mutex);
@@ -734,7 +736,6 @@ struct ieee80211_hw *p54_init_common(siz
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK |
- IEEE80211_HW_BEACON_FILTER |
IEEE80211_HW_REPORTS_TX_ACK_STATUS;
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
--- a/drivers/net/wireless/rtlwifi/base.c 2012-01-19 09:10:33.000000000 +0100
+++ b/drivers/net/wireless/rtlwifi/base.c 2012-01-19 09:10:34.000000000 +0100
@@ -310,7 +310,6 @@ static void _rtl_init_mac80211(struct ie
/* <5> set hw caps */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_BEACON_FILTER |
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_CONNECTION_MONITOR |
/* IEEE80211_HW_SUPPORTS_CQM_RSSI | */
--- a/drivers/net/wireless/rtlwifi/core.c 2012-01-19 09:10:33.000000000 +0100
+++ b/drivers/net/wireless/rtlwifi/core.c 2012-01-19 09:22:03.000000000 +0100
@@ -112,6 +112,8 @@ static int rtl_op_add_interface(struct i
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
int err = 0;
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+
if (mac->vif) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("vif has been set!! mac->vif = 0x%p\n", mac->vif));
--- a/drivers/net/wireless/wl1251/main.c 2012-01-19 09:10:33.000000000 +0100
+++ b/drivers/net/wireless/wl1251/main.c 2012-01-19 09:22:06.000000000 +0100
@@ -514,6 +514,8 @@ static int wl1251_op_add_interface(struc
struct wl1251 *wl = hw->priv;
int ret = 0;
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+
wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
vif->type, vif->addr);
@@ -1338,7 +1340,6 @@ int wl1251_init_ieee80211(struct wl1251
wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_BEACON_FILTER |
IEEE80211_HW_SUPPORTS_UAPSD |
IEEE80211_HW_SUPPORTS_CQM_RSSI;
--- a/drivers/net/wireless/wl12xx/main.c 2012-01-19 09:10:33.000000000 +0100
+++ b/drivers/net/wireless/wl12xx/main.c 2012-01-19 09:22:06.000000000 +0100
@@ -2060,6 +2060,8 @@ static int wl1271_op_add_interface(struc
u8 role_type;
bool booted = false;
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+
wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
ieee80211_vif_type_p2p(vif), vif->addr);
@@ -4898,7 +4900,6 @@ static int wl1271_init_ieee80211(struct
wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
- IEEE80211_HW_BEACON_FILTER |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_SUPPORTS_UAPSD |
IEEE80211_HW_HAS_RATE_CONTROL |
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 2/2] mac80211: make CQM RSSI support per virtual interface
2012-01-19 8:29 [PATCH 0/2] per interface configuration Johannes Berg
2012-01-19 8:29 ` [PATCH 1/2] mac80211: make beacon filtering per virtual interface Johannes Berg
@ 2012-01-19 8:29 ` Johannes Berg
2012-01-19 11:37 ` Eliad Peller
` (2 more replies)
1 sibling, 3 replies; 10+ messages in thread
From: Johannes Berg @ 2012-01-19 8:29 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Similar to the previous beacon filtering patch,
make CQM RSSI support depend on the flags that
the driver set for virtual interfaces.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
drivers/net/wireless/wl1251/main.c | 6 +++---
drivers/net/wireless/wl12xx/main.c | 4 ++--
include/net/mac80211.h | 14 +++++++-------
net/mac80211/cfg.c | 10 ++--------
net/mac80211/debugfs.c | 2 --
net/mac80211/mlme.c | 4 ++--
6 files changed, 16 insertions(+), 24 deletions(-)
--- a/include/net/mac80211.h 2012-01-19 09:22:06.000000000 +0100
+++ b/include/net/mac80211.h 2012-01-19 09:24:42.000000000 +0100
@@ -856,9 +856,14 @@ struct ieee80211_channel_switch {
*
* @IEEE80211_VIF_BEACON_FILTER: the device performs beacon filtering
* on this virtual interface to avoid unnecessary CPU wakeups
+ * @IEEE80211_VIF_SUPPORTS_CQM_RSSI: the device can do connection quality
+ * monitoring on this virtual interface -- i.e. it can monitor
+ * connection quality related parameters, such as the RSSI level and
+ * provide notifications if configured trigger levels are reached.
*/
enum ieee80211_vif_flags {
IEEE80211_VIF_BEACON_FILTER = BIT(0),
+ IEEE80211_VIF_SUPPORTS_CQM_RSSI = BIT(1),
};
/**
@@ -1119,11 +1124,6 @@ enum sta_notify_cmd {
* When this flag is set, signaling beacon-loss will cause an immediate
* change to disassociated state.
*
- * @IEEE80211_HW_SUPPORTS_CQM_RSSI:
- * Hardware can do connection quality monitoring - i.e. it can monitor
- * connection quality related parameters, such as the RSSI level and
- * provide notifications if configured trigger levels are reached.
- *
* @IEEE80211_HW_NEED_DTIM_PERIOD:
* This device needs to know the DTIM period for the BSS before
* associating.
@@ -1167,7 +1167,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_UAPSD = 1<<17,
IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18,
IEEE80211_HW_CONNECTION_MONITOR = 1<<19,
- IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20,
+ /* reuse bit 20 */
IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21,
IEEE80211_HW_AP_LINK_PS = 1<<22,
IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23,
@@ -3408,7 +3408,7 @@ void ieee80211_enable_dyn_ps(struct ieee
* @rssi_event: the RSSI trigger event type
* @gfp: context flags
*
- * When the %IEEE80211_HW_SUPPORTS_CQM_RSSI is set, and a connection quality
+ * When the %IEEE80211_VIF_SUPPORTS_CQM_RSSI is set, and a connection quality
* monitoring is configured with an rssi threshold, the driver will inform
* whenever the rssi level reaches the threshold.
*/
--- a/net/mac80211/cfg.c 2012-01-19 09:22:06.000000000 +0100
+++ b/net/mac80211/cfg.c 2012-01-19 09:24:42.000000000 +0100
@@ -1862,7 +1862,6 @@ static int ieee80211_set_cqm_rssi_config
s32 rssi_thold, u32 rssi_hyst)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_vif *vif = &sdata->vif;
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
@@ -1873,14 +1872,9 @@ static int ieee80211_set_cqm_rssi_config
bss_conf->cqm_rssi_thold = rssi_thold;
bss_conf->cqm_rssi_hyst = rssi_hyst;
- if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
- if (sdata->vif.type != NL80211_IFTYPE_STATION)
- return -EOPNOTSUPP;
- return 0;
- }
-
/* tell the driver upon association, unless already associated */
- if (sdata->u.mgd.associated)
+ if (sdata->u.mgd.associated &&
+ sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
return 0;
--- a/net/mac80211/debugfs.c 2012-01-19 09:22:06.000000000 +0100
+++ b/net/mac80211/debugfs.c 2012-01-19 09:24:42.000000000 +0100
@@ -257,8 +257,6 @@ static ssize_t hwflags_read(struct file
sf += snprintf(buf + sf, mxln - sf, "REPORTS_TX_ACK_STATUS\n");
if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
sf += snprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n");
- if (local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)
- sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_CQM_RSSI\n");
if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)
sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n");
if (local->hw.flags & IEEE80211_HW_AP_LINK_PS)
--- a/net/mac80211/mlme.c 2012-01-19 09:22:06.000000000 +0100
+++ b/net/mac80211/mlme.c 2012-01-19 09:24:42.000000000 +0100
@@ -1043,7 +1043,7 @@ static void ieee80211_set_associated(str
bss_info_changed |= BSS_CHANGED_BSSID;
/* Tell the driver to monitor connection quality (if supported) */
- if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
+ if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI &&
bss_conf->cqm_rssi_thold)
bss_info_changed |= BSS_CHANGED_CQM;
@@ -1891,7 +1891,7 @@ static void ieee80211_rx_mgmt_beacon(str
if (bss_conf->cqm_rssi_thold &&
ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
- !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
+ !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) {
int sig = ifmgd->ave_beacon_signal / 16;
int last_event = ifmgd->last_cqm_event_signal;
int thold = bss_conf->cqm_rssi_thold;
--- a/drivers/net/wireless/wl1251/main.c 2012-01-19 09:22:06.000000000 +0100
+++ b/drivers/net/wireless/wl1251/main.c 2012-01-19 09:24:42.000000000 +0100
@@ -514,7 +514,8 @@ static int wl1251_op_add_interface(struc
struct wl1251 *wl = hw->priv;
int ret = 0;
- vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
+ IEEE80211_VIF_SUPPORTS_CQM_RSSI;
wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
vif->type, vif->addr);
@@ -1340,8 +1341,7 @@ int wl1251_init_ieee80211(struct wl1251
wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_SUPPORTS_UAPSD |
- IEEE80211_HW_SUPPORTS_CQM_RSSI;
+ IEEE80211_HW_SUPPORTS_UAPSD;
wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
--- a/drivers/net/wireless/wl12xx/main.c 2012-01-19 09:22:06.000000000 +0100
+++ b/drivers/net/wireless/wl12xx/main.c 2012-01-19 09:24:42.000000000 +0100
@@ -2060,7 +2060,8 @@ static int wl1271_op_add_interface(struc
u8 role_type;
bool booted = false;
- vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
+ IEEE80211_VIF_SUPPORTS_CQM_RSSI;
wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
ieee80211_vif_type_p2p(vif), vif->addr);
@@ -4904,7 +4905,6 @@ static int wl1271_init_ieee80211(struct
IEEE80211_HW_SUPPORTS_UAPSD |
IEEE80211_HW_HAS_RATE_CONTROL |
IEEE80211_HW_CONNECTION_MONITOR |
- IEEE80211_HW_SUPPORTS_CQM_RSSI |
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_SPECTRUM_MGMT |
IEEE80211_HW_AP_LINK_PS |
^ permalink raw reply [flat|nested] 10+ messages in thread