From 35b88623692f7ffbfdf16e4c2358784a060c20ed Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 29 Dec 2011 14:41:39 +0200 Subject: mac80211: check sta_apply_parameters() return value Bail out if sta_apply_parameters() returns an error. Signed-off-by: Eliad Peller Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 296620d6ca0c..d86730fe75c8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1001,6 +1001,7 @@ static int ieee80211_change_station(struct wiphy *wiphy, struct ieee80211_local *local = wiphy_priv(wiphy); struct sta_info *sta; struct ieee80211_sub_if_data *vlansdata; + int err; mutex_lock(&local->sta_mtx); @@ -1040,7 +1041,11 @@ static int ieee80211_change_station(struct wiphy *wiphy, ieee80211_send_layer2_update(sta); } - sta_apply_parameters(local, sta, params); + err = sta_apply_parameters(local, sta, params); + if (err) { + mutex_unlock(&local->sta_mtx); + return err; + } if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates) rate_control_rate_init(sta); -- cgit v1.2.3 From ea086359a63bd0dd85c1d784d0425340649613fa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 19 Jan 2012 09:29:58 +0100 Subject: mac80211: make CQM RSSI support per virtual interface 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 Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d86730fe75c8..74c9301681e5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1873,7 +1873,6 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, 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; @@ -1884,14 +1883,9 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, 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; -- cgit v1.2.3 From 94f9065648a2645b28187b44ec7778c30cf58758 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Sat, 21 Jan 2012 01:02:16 +0800 Subject: {nl,cfg,mac}80211: Add support of setting non-forwarding entity in Mesh A mesh node that joins the mesh network is by default a forwarding entity. This patch allows the mesh node to set as non-forwarding entity. Whenever dot11MeshForwarding is set to 0, the mesh node can prevent itself from forwarding the traffic which is not destined to him. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 74c9301681e5..98460783c2d3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1346,6 +1346,8 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, conf->dot11MeshHWMPRannInterval = nconf->dot11MeshHWMPRannInterval; } + if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) + conf->dot11MeshForwarding = nconf->dot11MeshForwarding; return 0; } -- cgit v1.2.3 From 83d5cc012441531ab0bf6f99881958e964e9cf11 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 12 Jan 2012 09:31:10 +0100 Subject: mac80211: station state transition error handling In the future, when we start notifying drivers, state transitions could potentially fail. To make it easier to distinguish between programming bugs and driver failures: * rename sta_info_move_state() to sta_info_pre_move_state() which can only be called before the station is inserted (and check this with a new station flag). * rename sta_info_move_state_checked() to just plain sta_info_move_state(), as it will be the regular function that can fail for more than just one reason (bad transition or an error from the driver) This makes the programming model easier -- one of the functions can only be called before insertion and can't fail, the other can fail. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 98460783c2d3..dc7420441574 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -776,12 +776,10 @@ static int sta_apply_parameters(struct ieee80211_local *local, if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED) && !test_sta_flag(sta, WLAN_STA_AUTH)) { - ret = sta_info_move_state_checked(sta, - IEEE80211_STA_AUTH); + ret = sta_info_move_state(sta, IEEE80211_STA_AUTH); if (ret) return ret; - ret = sta_info_move_state_checked(sta, - IEEE80211_STA_ASSOC); + ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); if (ret) return ret; } @@ -789,11 +787,9 @@ static int sta_apply_parameters(struct ieee80211_local *local, if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) - ret = sta_info_move_state_checked(sta, - IEEE80211_STA_AUTHORIZED); + ret = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); else if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) - ret = sta_info_move_state_checked(sta, - IEEE80211_STA_ASSOC); + ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); if (ret) return ret; } @@ -805,12 +801,10 @@ static int sta_apply_parameters(struct ieee80211_local *local, if (!(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) && test_sta_flag(sta, WLAN_STA_AUTH)) { - ret = sta_info_move_state_checked(sta, - IEEE80211_STA_AUTH); + ret = sta_info_move_state(sta, IEEE80211_STA_AUTH); if (ret) return ret; - ret = sta_info_move_state_checked(sta, - IEEE80211_STA_NONE); + ret = sta_info_move_state(sta, IEEE80211_STA_NONE); if (ret) return ret; } @@ -944,8 +938,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, if (!sta) return -ENOMEM; - sta_info_move_state(sta, IEEE80211_STA_AUTH); - sta_info_move_state(sta, IEEE80211_STA_ASSOC); + sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); + sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); err = sta_apply_parameters(local, sta, params); if (err) { -- cgit v1.2.3 From 19468413e8d98d44be8daf0acaf8d576dfc53fa2 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Sat, 28 Jan 2012 17:25:33 +0100 Subject: mac80211: add support for mcs masks * Handle MCS masks set by the user. * Match rates provided by the rate control algorithm to the mask set, also in HT mode, and switch back to legacy mode if necessary. * add debugfs files to observate the rate selection Signed-off-by: Simon Wunderlich Signed-off-by: Mathias Kretschmer Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index dc7420441574..d15ba0d0de94 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1902,8 +1902,11 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, return ret; } - for (i = 0; i < IEEE80211_NUM_BANDS; i++) + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { sdata->rc_rateidx_mask[i] = mask->control[i].legacy; + memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs, + sizeof(mask->control[i].mcs)); + } return 0; } -- cgit v1.2.3 From 66e67e418908442389d3a9e6509985f01cbaf9b0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 20 Jan 2012 13:55:27 +0100 Subject: mac80211: redesign auth/assoc This is the second part of the auth/assoc redesign, the mac80211 part. This moves the auth/assoc code out of the work abstraction and into the MLME, so that we don't flip channels all the time etc. The only downside is that when we are associated, we need to drop the association in order to create a connection to another AP, but for most drivers this is actually desirable and the ability to do was never used by any applications. If we want to implement resource reservation with FT-OTA, we'd probably best do it with explicit R-O-C in wpa_s. Signed-off-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 d15ba0d0de94..c3de921c8cfd 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2028,7 +2028,7 @@ ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb) if (wk->offchan_tx.wait && !wk->offchan_tx.status) cfg80211_mgmt_tx_status(wk->sdata->dev, (unsigned long) wk->offchan_tx.frame, - wk->ie, wk->ie_len, false, GFP_KERNEL); + wk->data, wk->data_len, false, GFP_KERNEL); return WORK_DONE_DESTROY; } @@ -2179,8 +2179,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, wk->done = ieee80211_offchan_tx_done; wk->offchan_tx.frame = skb; wk->offchan_tx.wait = wait; - wk->ie_len = len; - memcpy(wk->ie, buf, len); + wk->data_len = len; + memcpy(wk->data, buf, len); ieee80211_add_work(wk); return 0; -- cgit v1.2.3 From 8860020e0be1f03d83dc9e9e93e18a4ddbe01038 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 13 Feb 2012 15:17:18 +0100 Subject: cfg80211: restructure AP/GO mode API The AP/GO mode API isn't very clearly defined, it has "set beacon" and "new beacon" etc. Modify the API to the following: * start AP -- all settings * change beacon -- new beacon data * stop AP -- stop AP mode operation This also reflects in the nl80211 API, rename the commands there correspondingly (but keep the old names for compatibility.) Overall, this makes it much clearer what's going on in the API. Kalle developed the ath6kl changes, I created the rest of the patch. Signed-off-by: Kalle Valo Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 146 ++++++++++++++++++++++------------------------------- 1 file changed, 59 insertions(+), 87 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c3de921c8cfd..f7eb25aabf8f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -489,27 +489,13 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, return ret; } -static void ieee80211_config_ap_ssid(struct ieee80211_sub_if_data *sdata, - struct beacon_parameters *params) -{ - struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; - - bss_conf->ssid_len = params->ssid_len; - - if (params->ssid_len) - memcpy(bss_conf->ssid, params->ssid, params->ssid_len); - - bss_conf->hidden_ssid = - (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); -} - static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, - u8 *resp, size_t resp_len) + const u8 *resp, size_t resp_len) { struct sk_buff *new, *old; if (!resp || !resp_len) - return -EINVAL; + return 1; old = rtnl_dereference(sdata->u.ap.probe_resp); @@ -520,50 +506,28 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, memcpy(skb_put(new, resp_len), resp, resp_len); rcu_assign_pointer(sdata->u.ap.probe_resp, new); - synchronize_rcu(); - - if (old) + if (old) { + /* TODO: use call_rcu() */ + synchronize_rcu(); dev_kfree_skb(old); + } return 0; } -/* - * This handles both adding a beacon and setting new beacon info - */ -static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, - struct beacon_parameters *params) +static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, + struct cfg80211_beacon_data *params) { struct beacon_data *new, *old; int new_head_len, new_tail_len; - int size; - int err = -EINVAL; - u32 changed = 0; + int size, err; + u32 changed = BSS_CHANGED_BEACON; old = rtnl_dereference(sdata->u.ap.beacon); - /* head must not be zero-length */ - if (params->head && !params->head_len) - return -EINVAL; - - /* - * This is a kludge. beacon interval should really be part - * of the beacon information. - */ - if (params->interval && - (sdata->vif.bss_conf.beacon_int != params->interval)) { - sdata->vif.bss_conf.beacon_int = params->interval; - ieee80211_bss_info_change_notify(sdata, - BSS_CHANGED_BEACON_INT); - } - /* Need to have a beacon head if we don't have one yet */ if (!params->head && !old) - return err; - - /* sorry, no way to start beaconing without dtim period */ - if (!params->dtim_period && !old) - return err; + return -EINVAL; /* new or old head? */ if (params->head) @@ -586,12 +550,6 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, /* start filling the new info now */ - /* new or old dtim period? */ - if (params->dtim_period) - new->dtim_period = params->dtim_period; - else - new->dtim_period = old->dtim_period; - /* * pointers go into the block we allocated, * memory is | beacon_data | head | tail | @@ -614,46 +572,37 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, if (old) memcpy(new->tail, old->tail, new_tail_len); - sdata->vif.bss_conf.dtim_period = new->dtim_period; - - rcu_assign_pointer(sdata->u.ap.beacon, new); - - synchronize_rcu(); - - kfree(old); - err = ieee80211_set_probe_resp(sdata, params->probe_resp, params->probe_resp_len); - if (!err) + if (err < 0) + return err; + if (err == 0) changed |= BSS_CHANGED_AP_PROBE_RESP; - ieee80211_config_ap_ssid(sdata, params); - changed |= BSS_CHANGED_BEACON_ENABLED | - BSS_CHANGED_BEACON | - BSS_CHANGED_SSID; + rcu_assign_pointer(sdata->u.ap.beacon, new); + + if (old) + kfree_rcu(old, rcu_head); - ieee80211_bss_info_change_notify(sdata, changed); - return 0; + return changed; } -static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, - struct beacon_parameters *params) +static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ap_settings *params) { - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct beacon_data *old; struct ieee80211_sub_if_data *vlan; - int ret; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); + u32 changed = BSS_CHANGED_BEACON_INT | + BSS_CHANGED_BEACON_ENABLED | + BSS_CHANGED_BEACON | + BSS_CHANGED_SSID; + int err; old = rtnl_dereference(sdata->u.ap.beacon); if (old) return -EALREADY; - ret = ieee80211_config_beacon(sdata, params); - if (ret) - return ret; - /* * Apply control port protocol, this allows us to * not encrypt dynamic WEP control frames. @@ -667,14 +616,32 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, params->crypto.control_port_no_encrypt; } + sdata->vif.bss_conf.beacon_int = params->beacon_interval; + sdata->vif.bss_conf.dtim_period = params->dtim_period; + + sdata->vif.bss_conf.ssid_len = params->ssid_len; + if (params->ssid_len) + memcpy(sdata->vif.bss_conf.ssid, params->ssid, + params->ssid_len); + sdata->vif.bss_conf.hidden_ssid = + (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); + + err = ieee80211_assign_beacon(sdata, ¶ms->beacon); + if (err < 0) + return err; + changed |= err; + + ieee80211_bss_info_change_notify(sdata, changed); + return 0; } -static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, - struct beacon_parameters *params) +static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_beacon_data *params) { struct ieee80211_sub_if_data *sdata; struct beacon_data *old; + int err; sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -682,10 +649,14 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, if (!old) return -ENOENT; - return ieee80211_config_beacon(sdata, params); + err = ieee80211_assign_beacon(sdata, params); + if (err < 0) + return err; + ieee80211_bss_info_change_notify(sdata, err); + return 0; } -static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) +static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) { struct ieee80211_sub_if_data *sdata; struct beacon_data *old; @@ -697,10 +668,11 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) return -ENOENT; RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); - synchronize_rcu(); - kfree(old); + + kfree_rcu(old, rcu_head); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); + return 0; } @@ -2699,9 +2671,9 @@ struct cfg80211_ops mac80211_config_ops = { .get_key = ieee80211_get_key, .set_default_key = ieee80211_config_default_key, .set_default_mgmt_key = ieee80211_config_default_mgmt_key, - .add_beacon = ieee80211_add_beacon, - .set_beacon = ieee80211_set_beacon, - .del_beacon = ieee80211_del_beacon, + .start_ap = ieee80211_start_ap, + .change_beacon = ieee80211_change_beacon, + .stop_ap = ieee80211_stop_ap, .add_station = ieee80211_add_station, .del_station = ieee80211_del_station, .change_station = ieee80211_change_station, -- cgit v1.2.3 From 63c9c5e77c36f8793dddf0e905a4bc43a0972735 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 24 Feb 2012 13:50:51 +0100 Subject: cfg80211: remove cookies from callbacks In "cfg80211: no cookies in cfg80211_send_XXX()" Holger Schurig removed the cookies in the calls from mac80211 to cfg80211, but the ones in the other direction were left in. Remove them now. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f7eb25aabf8f..6a77d4c910f9 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1595,19 +1595,15 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_deauth_request *req, - void *cookie) + struct cfg80211_deauth_request *req) { - return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev), - req, cookie); + return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev), req); } static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_disassoc_request *req, - void *cookie) + struct cfg80211_disassoc_request *req) { - return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev), - req, cookie); + return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev), req); } static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, -- cgit v1.2.3 From 5533513784a88049e19dd2ab380a452b61e5171e Mon Sep 17 00:00:00 2001 From: Ashok Nagarajan Date: Tue, 28 Feb 2012 17:04:08 -0800 Subject: {nl,cfg,mac}80211: Implement RSSI threshold for mesh peering Mesh peer links are established only if average rssi of the peer candidate satisfies the threshold. This is not in 802.11s specification but was requested by David Fulgham, an open80211s user. This is a way to avoid marginal peer links with stations that are barely within range. This patch adds a new mesh configuration parameter, mesh_rssi_threshold. This feature is supported only for hardwares that report signal in dBm. Signed-off-by: Ashok Nagarajan Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 6a77d4c910f9..ab31cc56a2fb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1314,6 +1314,14 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, } if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) conf->dot11MeshForwarding = nconf->dot11MeshForwarding; + if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { + /* our RSSI threshold implementation is supported only for + * devices that report signal in dBm. + */ + if (!(sdata->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)) + return -ENOTSUPP; + conf->rssi_threshold = nconf->rssi_threshold; + } return 0; } -- cgit v1.2.3 From 6b62bf326393deede630731a933713de9d574128 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Mon, 5 Mar 2012 15:31:48 -0800 Subject: mac80211: fix mesh airtime link metric estimating Airtime link metric estimation was broken in HT mesh, use cfg80211_calculate_bitrate to get the right rate value. Also factor out tx rate copying from sta_set_sinfo(). Signed-off-by: Thomas Pedersen Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'net/mac80211/cfg.c') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ab31cc56a2fb..677d65929780 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -336,6 +336,20 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in rate->mcs = idx; } +void sta_set_rate_info_tx(struct sta_info *sta, + const struct ieee80211_tx_rate *rate, + struct rate_info *rinfo) +{ + rinfo->flags = 0; + if (rate->flags & IEEE80211_TX_RC_MCS) + rinfo->flags |= RATE_INFO_FLAGS_MCS; + if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + if (rate->flags & IEEE80211_TX_RC_SHORT_GI) + rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; + rate_idx_to_bitrate(rinfo, sta, rate->idx); +} + static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = sta->sdata; @@ -378,14 +392,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); } - sinfo->txrate.flags = 0; - if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) - sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; - if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; - if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI) - sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx); + sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); sinfo->rxrate.flags = 0; if (sta->last_rx_rate_flag & RX_FLAG_HT) -- cgit v1.2.3