From 252aa631f88080920a7083ac5a5844ffc5463629 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 May 2010 12:17:12 +0200 Subject: cfg80211: make action channel type optional When sending action frames, we want to verify that we do that on the correct channel. However, checking the channel type in addition can get in the way, since the channel type could change on the fly during an association, and it's not useful to have the channel type anyway since it has no effect on the transmission. Therefore, make it optional to specify so that if wanted, it can still be checked, but is not required. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c7000a6ca379..f8c49c5ad8aa 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1554,10 +1554,12 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, + bool channel_type_valid, const u8 *buf, size_t len, u64 *cookie) { return ieee80211_mgd_action(IEEE80211_DEV_TO_SUB_IF(dev), chan, - channel_type, buf, len, cookie); + channel_type, channel_type_valid, + buf, len, cookie); } struct cfg80211_ops mac80211_config_ops = { -- cgit v1.2.3 From bc10502dba37d3b210efd9f3867212298f13b78e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 3 Jun 2010 03:21:52 -0700 Subject: net: use __packed annotation cleanup patch. Use new __packed annotation in net/ and include/ (except netfilter) Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/mac80211/cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c7000a6ca379..a2ed0f7b5568 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -600,7 +600,7 @@ struct iapp_layer2_update { u8 ssap; /* 0 */ u8 control; u8 xid_info[3]; -} __attribute__ ((packed)); +} __packed; static void ieee80211_send_layer2_update(struct sta_info *sta) { -- cgit v1.2.3 From ad0e2b5a00dbec303e4682b403bb6703d11dcdb2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 1 Jun 2010 10:19:19 +0200 Subject: mac80211: simplify key locking Since I recently made station management able to sleep, I can now rework key management as well; since it will no longer need a spinlock and can also use a mutex instead, a bunch of code to allow drivers' set_key to sleep while key management is protected by a spinlock can now be removed. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f8c49c5ad8aa..952845e7072a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -120,6 +120,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_key *key; int err; + if (!netif_running(dev)) + return -ENETDOWN; + sdata = IEEE80211_DEV_TO_SUB_IF(dev); switch (params->cipher) { @@ -145,7 +148,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, if (!key) return -ENOMEM; - rcu_read_lock(); + mutex_lock(&sdata->local->sta_mtx); if (mac_addr) { sta = sta_info_get_bss(sdata, mac_addr); @@ -160,7 +163,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, err = 0; out_unlock: - rcu_read_unlock(); + mutex_unlock(&sdata->local->sta_mtx); return err; } @@ -174,7 +177,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, sdata = IEEE80211_DEV_TO_SUB_IF(dev); - rcu_read_lock(); + mutex_lock(&sdata->local->sta_mtx); if (mac_addr) { ret = -ENOENT; @@ -202,7 +205,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, ret = 0; out_unlock: - rcu_read_unlock(); + mutex_unlock(&sdata->local->sta_mtx); return ret; } @@ -305,15 +308,10 @@ static int ieee80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx) { - struct ieee80211_sub_if_data *sdata; - - rcu_read_lock(); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - sdata = IEEE80211_DEV_TO_SUB_IF(dev); ieee80211_set_default_key(sdata, key_idx); - rcu_read_unlock(); - return 0; } -- cgit v1.2.3 From 9d38d85de0270e3927bffab94973a9c78d1dc800 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 9 Jun 2010 17:20:33 +0200 Subject: cfg80211/mac80211: allow action frame TX/RX in IBSS When in IBSS mode, currently action frame TX and RX cannot be used. Allow using it to talk to any peer, or for public action frames. Also, while at it, restructure the code in mac80211 to make it easier to add this for other interface types in the future. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 952845e7072a..59f597d0c6a0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1555,9 +1555,55 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, bool channel_type_valid, const u8 *buf, size_t len, u64 *cookie) { - return ieee80211_mgd_action(IEEE80211_DEV_TO_SUB_IF(dev), chan, - channel_type, channel_type_valid, - buf, len, cookie); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct sta_info *sta; + const struct ieee80211_mgmt *mgmt = (void *)buf; + u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | + IEEE80211_TX_CTL_REQ_TX_STATUS; + + /* Check that we are on the requested channel for transmission */ + if (chan != local->tmp_channel && + chan != local->oper_channel) + return -EBUSY; + if (channel_type_valid && + (channel_type != local->tmp_channel_type && + channel_type != local->_oper_channel_type)) + return -EBUSY; + + switch (sdata->vif.type) { + case NL80211_IFTYPE_ADHOC: + if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) + break; + rcu_read_lock(); + sta = sta_info_get(sdata, mgmt->da); + rcu_read_unlock(); + if (!sta) + return -ENOLINK; + break; + case NL80211_IFTYPE_STATION: + if (!(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED)) + flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + break; + default: + return -EOPNOTSUPP; + } + + skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); + if (!skb) + return -ENOMEM; + skb_reserve(skb, local->hw.extra_tx_headroom); + + memcpy(skb_put(skb, len), buf, len); + + IEEE80211_SKB_CB(skb)->flags = flags; + + skb->dev = sdata->dev; + ieee80211_tx_skb(sdata, skb); + + *cookie = (unsigned long) skb; + return 0; } struct cfg80211_ops mac80211_config_ops = { -- cgit v1.2.3 From ff61638105db6f5832ef8700436ba6aa6d3a2fda Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Wed, 9 Jun 2010 09:51:52 +0300 Subject: mac80211: Fix ps-qos network latency handling The ps-qos latency handling is broken. It uses predetermined latency values to select specific dynamic PS timeouts. With common AP configurations, these values overlap with beacon interval and are therefore essentially useless (for network latencies less than the beacon interval, PSM is disabled.) This patch remedies the problem by replacing the predetermined network latency values with one high value (1900ms) which is used to go trigger full psm. For backwards compatibility, the value 2000ms is still mapped to a dynamic ps timeout of 100ms. Currently also the mac80211 internal value for storing user space configured dynamic PSM values is incorrectly in the driver visible ieee80211_conf struct. Move it to the ieee80211_local struct. Signed-off-by: Juuso Oikarinen Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 59f597d0c6a0..003b6addf5fa 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1446,7 +1446,6 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_conf *conf = &local->hw.conf; if (sdata->vif.type != NL80211_IFTYPE_STATION) return -EOPNOTSUPP; @@ -1455,11 +1454,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, return -EOPNOTSUPP; if (enabled == sdata->u.mgd.powersave && - timeout == conf->dynamic_ps_forced_timeout) + timeout == local->dynamic_ps_forced_timeout) return 0; sdata->u.mgd.powersave = enabled; - conf->dynamic_ps_forced_timeout = timeout; + local->dynamic_ps_forced_timeout = timeout; /* no change, but if automatic follow powersave */ mutex_lock(&sdata->u.mgd.mtx); -- cgit v1.2.3 From fa61cf70a6ae1089e459e4b59b2e8d8e90d8535e Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Wed, 23 Jun 2010 12:12:37 +0300 Subject: cfg80211/mac80211: Update set_tx_power to use mBm instead of dBm units In preparation for a TX power setting interface in the nl80211, change the .set_tx_power function to use mBm units instead of dBm for greater accuracy and smaller power levels. Also, already in advance move the tx_power_setting enumeration to nl80211. This change affects the .tx_set_power function prototype. As a result, the corresponding changes are needed to modules using it. These are mac80211, iwmc3200wifi and rndis_wlan. Cc: Samuel Ortiz Cc: Jussi Kivilinna Signed-off-by: Juuso Oikarinen Acked-by: Samuel Ortiz Acked-by: Jussi Kivilinna Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 003b6addf5fa..f4efbfa4f237 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1329,28 +1329,28 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) } static int ieee80211_set_tx_power(struct wiphy *wiphy, - enum tx_power_setting type, int dbm) + enum nl80211_tx_power_setting type, int mbm) { struct ieee80211_local *local = wiphy_priv(wiphy); struct ieee80211_channel *chan = local->hw.conf.channel; u32 changes = 0; switch (type) { - case TX_POWER_AUTOMATIC: + case NL80211_TX_POWER_AUTOMATIC: local->user_power_level = -1; break; - case TX_POWER_LIMITED: - if (dbm < 0) - return -EINVAL; - local->user_power_level = dbm; + case NL80211_TX_POWER_LIMITED: + if (mbm < 0 || (mbm % 100)) + return -EOPNOTSUPP; + local->user_power_level = MBM_TO_DBM(mbm); break; - case TX_POWER_FIXED: - if (dbm < 0) - return -EINVAL; + case NL80211_TX_POWER_FIXED: + if (mbm < 0 || (mbm % 100)) + return -EOPNOTSUPP; /* TODO: move to cfg80211 when it knows the channel */ - if (dbm > chan->max_power) + if (MBM_TO_DBM(mbm) > chan->max_power) return -EINVAL; - local->user_power_level = dbm; + local->user_power_level = MBM_TO_DBM(mbm); break; } -- cgit v1.2.3 From ff3074a4dd6c0963e6a7eaac48175a62f589c143 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 29 Jun 2010 13:55:04 -0400 Subject: mac80211: remove unnecessary check in ieee80211_dump_survey This check is duplicated in drv_get_survey. Reported-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f4efbfa4f237..e55970bf2ba0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -413,9 +413,6 @@ static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev, { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - if (!local->ops->get_survey) - return -EOPNOTSUPP; - return drv_get_survey(local, idx, survey); } -- cgit v1.2.3 From 3473187d2459a078e00e5fac8aafc30af69c57fa Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 7 Jul 2010 15:07:49 -0400 Subject: mac80211: remove wep dependency The current mac80211 code assumes that WEP is always available. If WEP fails to initialize, ieee80211_register_hw will always fail. In some cases (e.g. FIPS certification), the cryptography used by WEP is unavailable. However, in such cases there is no good reason why CCMP encryption (or even no link level encryption) cannot be used. So, this patch removes mac80211's assumption that WEP (and TKIP) will always be available for use. Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index e55970bf2ba0..5b8b4460b69f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -143,6 +143,11 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, return -EINVAL; } + /* reject WEP and TKIP keys if WEP failed to initialize */ + if ((alg == ALG_WEP || alg == ALG_TKIP) && + IS_ERR(sdata->local->wep_tx_tfm)) + return -EINVAL; + key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key, params->seq_len, params->seq); if (!key) -- cgit v1.2.3 From 4ced3f74dae18715920cb680098ec7ff4345d0a3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 19 Jul 2010 16:39:04 +0200 Subject: mac80211: move QoS-enable to BSS info Ever since commit e1b3ec1a2a336c328c336cfa5485a5f0484cc90d Author: Stanislaw Gruszka Date: Mon Mar 29 12:18:34 2010 +0200 mac80211: explicitly disable/enable QoS mac80211 is telling drivers, in particular iwlwifi, whether QoS is enabled or not. However, this is only relevant for station mode, since only then will any device send nullfunc frames and need to know whether they should be QoS frames or not. In other modes, there are (currently) no frames the device is supposed to send. When you now consider virtual interfaces, it becomes apparent that the current mechanism is inadequate since it enables/disables QoS on a global scale, where for nullfunc frames it has to be on a per-interface scale. Due to the above considerations, we can change the way mac80211 advertises the QoS state to drivers to only ever advertise it as "off" in station mode, and make it a per-BSS setting. Tested-by: Stanislaw Gruszka Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5b8b4460b69f..35b07ea0633a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1154,10 +1154,6 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, return -EINVAL; } - /* enable WMM or activate new settings */ - local->hw.conf.flags |= IEEE80211_CONF_QOS; - drv_config(local, IEEE80211_CONF_CHANGE_QOS); - return 0; } -- cgit v1.2.3 From 66c524210ab9217528b01b63c43903545e03a58c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 22 Jul 2010 13:58:51 +0200 Subject: mac80211: remove bogus rcu_read_lock() Another remnant of the previous key locking scheme needs to be removed -- this causes a warning otherwise as ieee80211_set_default_mgmt_key will acquire a mutex. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 35b07ea0633a..db82da90df76 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -324,15 +324,10 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx) { - struct ieee80211_sub_if_data *sdata; - - rcu_read_lock(); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - sdata = IEEE80211_DEV_TO_SUB_IF(dev); ieee80211_set_default_mgmt_key(sdata, key_idx); - rcu_read_unlock(); - return 0; } -- cgit v1.2.3 From 32162a4dab0e6a4ca7f886a01173b5f9b80843be Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 26 Jul 2010 15:52:03 -0700 Subject: mac80211: Fix key freeing to handle unlinked keys Key locking simplification removed key->sdata != NULL verification from ieee80211_key_free(). While that is fine for most use cases, there is one path where this function can be called with an unlinked key (i.e., key->sdata == NULL && key->local == NULL). This results in a NULL pointer dereference with the current implementation. This is known to happen at least with FT protocol when wpa_supplicant tries to configure the key before association. Avoid the issue by passing in the local pointer to ieee80211_key_free(). In addition, do not clear the key from hw_accel or debugfs if it has not yet been added. At least the hw_accel one could trigger another NULL pointer dereference. Signed-off-by: Jouni Malinen Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b769567949be..dab6b8efe5fa 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -158,7 +158,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, if (mac_addr) { sta = sta_info_get_bss(sdata, mac_addr); if (!sta) { - ieee80211_key_free(key); + ieee80211_key_free(sdata->local, key); err = -ENOENT; goto out_unlock; } @@ -192,7 +192,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, goto out_unlock; if (sta->key) { - ieee80211_key_free(sta->key); + ieee80211_key_free(sdata->local, sta->key); WARN_ON(sta->key); ret = 0; } @@ -205,7 +205,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, goto out_unlock; } - ieee80211_key_free(sdata->keys[key_idx]); + ieee80211_key_free(sdata->local, sdata->keys[key_idx]); WARN_ON(sdata->keys[key_idx]); ret = 0; -- cgit v1.2.3