Commit 22f64bd3 authored by John W. Linville's avatar John W. Linville
parents 64b6f46f 5c9fc93b
...@@ -666,6 +666,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, ...@@ -666,6 +666,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
if (sta->sdata->dev != dev) if (sta->sdata->dev != dev)
continue; continue;
sinfo.filled = 0;
sta_set_sinfo(sta, &sinfo);
i = 0; i = 0;
ADD_STA_STATS(sta); ADD_STA_STATS(sta);
} }
......
...@@ -290,7 +290,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, ...@@ -290,7 +290,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
struct minstrel_rate *msr, *mr; struct minstrel_rate *msr, *mr;
unsigned int ndx; unsigned int ndx;
bool mrr_capable; bool mrr_capable;
bool prev_sample = mi->prev_sample; bool prev_sample;
int delta; int delta;
int sampling_ratio; int sampling_ratio;
...@@ -314,6 +314,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, ...@@ -314,6 +314,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
(mi->sample_count + mi->sample_deferred / 2); (mi->sample_count + mi->sample_deferred / 2);
/* delta < 0: no sampling required */ /* delta < 0: no sampling required */
prev_sample = mi->prev_sample;
mi->prev_sample = false; mi->prev_sample = false;
if (delta < 0 || (!mrr_capable && prev_sample)) if (delta < 0 || (!mrr_capable && prev_sample))
return; return;
......
...@@ -804,10 +804,18 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, ...@@ -804,10 +804,18 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
rate->count = 1;
if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
rate->idx = mp->cck_rates[idx];
rate->flags = 0;
return;
}
rate->idx = sample_idx % MCS_GROUP_RATES + rate->idx = sample_idx % MCS_GROUP_RATES +
(sample_group->streams - 1) * MCS_GROUP_RATES; (sample_group->streams - 1) * MCS_GROUP_RATES;
rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
rate->count = 1;
} }
static void static void
......
...@@ -936,8 +936,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) ...@@ -936,8 +936,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
/* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ /*
if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { * Drop duplicate 802.11 retransmissions
* (IEEE 802.11-2012: 9.3.2.10 "Duplicate detection and recovery")
*/
if (rx->skb->len >= 24 && rx->sta &&
!ieee80211_is_ctl(hdr->frame_control) &&
!ieee80211_is_qos_nullfunc(hdr->frame_control) &&
!is_multicast_ether_addr(hdr->addr1)) {
if (unlikely(ieee80211_has_retry(hdr->frame_control) && if (unlikely(ieee80211_has_retry(hdr->frame_control) &&
rx->sta->last_seq_ctrl[rx->seqno_idx] == rx->sta->last_seq_ctrl[rx->seqno_idx] ==
hdr->seq_ctrl)) { hdr->seq_ctrl)) {
......
...@@ -4770,9 +4770,9 @@ do { \ ...@@ -4770,9 +4770,9 @@ do { \
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1, FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
mask, NL80211_MESHCONF_FORWARDING, mask, NL80211_MESHCONF_FORWARDING,
nla_get_u8); nla_get_u8);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, 1, 255, FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
mask, NL80211_MESHCONF_RSSI_THRESHOLD, mask, NL80211_MESHCONF_RSSI_THRESHOLD,
nla_get_u32); nla_get_s32);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16, FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16,
mask, NL80211_MESHCONF_HT_OPMODE, mask, NL80211_MESHCONF_HT_OPMODE,
nla_get_u16); nla_get_u16);
...@@ -6613,12 +6613,14 @@ EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb); ...@@ -6613,12 +6613,14 @@ EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb);
void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
{ {
struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
void *hdr = ((void **)skb->cb)[1]; void *hdr = ((void **)skb->cb)[1];
struct nlattr *data = ((void **)skb->cb)[2]; struct nlattr *data = ((void **)skb->cb)[2];
nla_nest_end(skb, data); nla_nest_end(skb, data);
genlmsg_end(skb, hdr); genlmsg_end(skb, hdr);
genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp); genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0,
nl80211_testmode_mcgrp.id, gfp);
} }
EXPORT_SYMBOL(cfg80211_testmode_event); EXPORT_SYMBOL(cfg80211_testmode_event);
#endif #endif
...@@ -10064,7 +10066,8 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, ...@@ -10064,7 +10066,8 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
genlmsg_end(msg, hdr); genlmsg_end(msg, hdr);
genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
nl80211_mlme_mcgrp.id, gfp);
return; return;
nla_put_failure: nla_put_failure:
......
...@@ -2279,7 +2279,9 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy) ...@@ -2279,7 +2279,9 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
static void reg_timeout_work(struct work_struct *work) static void reg_timeout_work(struct work_struct *work)
{ {
REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n"); REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
rtnl_lock();
restore_regulatory_settings(true); restore_regulatory_settings(true);
rtnl_unlock();
} }
int __init regulatory_init(void) int __init regulatory_init(void)
......
...@@ -34,8 +34,10 @@ struct cfg80211_conn { ...@@ -34,8 +34,10 @@ struct cfg80211_conn {
CFG80211_CONN_SCAN_AGAIN, CFG80211_CONN_SCAN_AGAIN,
CFG80211_CONN_AUTHENTICATE_NEXT, CFG80211_CONN_AUTHENTICATE_NEXT,
CFG80211_CONN_AUTHENTICATING, CFG80211_CONN_AUTHENTICATING,
CFG80211_CONN_AUTH_FAILED,
CFG80211_CONN_ASSOCIATE_NEXT, CFG80211_CONN_ASSOCIATE_NEXT,
CFG80211_CONN_ASSOCIATING, CFG80211_CONN_ASSOCIATING,
CFG80211_CONN_ASSOC_FAILED,
CFG80211_CONN_DEAUTH, CFG80211_CONN_DEAUTH,
CFG80211_CONN_CONNECTED, CFG80211_CONN_CONNECTED,
} state; } state;
...@@ -164,6 +166,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) ...@@ -164,6 +166,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
NULL, 0, NULL, 0,
params->key, params->key_len, params->key, params->key_len,
params->key_idx, NULL, 0); params->key_idx, NULL, 0);
case CFG80211_CONN_AUTH_FAILED:
return -ENOTCONN;
case CFG80211_CONN_ASSOCIATE_NEXT: case CFG80211_CONN_ASSOCIATE_NEXT:
BUG_ON(!rdev->ops->assoc); BUG_ON(!rdev->ops->assoc);
wdev->conn->state = CFG80211_CONN_ASSOCIATING; wdev->conn->state = CFG80211_CONN_ASSOCIATING;
...@@ -188,10 +192,17 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) ...@@ -188,10 +192,17 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
WLAN_REASON_DEAUTH_LEAVING, WLAN_REASON_DEAUTH_LEAVING,
false); false);
return err; return err;
case CFG80211_CONN_ASSOC_FAILED:
cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0,
WLAN_REASON_DEAUTH_LEAVING, false);
return -ENOTCONN;
case CFG80211_CONN_DEAUTH: case CFG80211_CONN_DEAUTH:
cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0, NULL, 0,
WLAN_REASON_DEAUTH_LEAVING, false); WLAN_REASON_DEAUTH_LEAVING, false);
/* free directly, disconnected event already sent */
cfg80211_sme_free(wdev);
return 0; return 0;
default: default:
return 0; return 0;
...@@ -371,7 +382,7 @@ bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status) ...@@ -371,7 +382,7 @@ bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status)
return true; return true;
} }
wdev->conn->state = CFG80211_CONN_DEAUTH; wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
schedule_work(&rdev->conn_work); schedule_work(&rdev->conn_work);
return false; return false;
} }
...@@ -383,7 +394,13 @@ void cfg80211_sme_deauth(struct wireless_dev *wdev) ...@@ -383,7 +394,13 @@ void cfg80211_sme_deauth(struct wireless_dev *wdev)
void cfg80211_sme_auth_timeout(struct wireless_dev *wdev) void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
{ {
cfg80211_sme_free(wdev); struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
if (!wdev->conn)
return;
wdev->conn->state = CFG80211_CONN_AUTH_FAILED;
schedule_work(&rdev->conn_work);
} }
void cfg80211_sme_disassoc(struct wireless_dev *wdev) void cfg80211_sme_disassoc(struct wireless_dev *wdev)
...@@ -399,7 +416,13 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev) ...@@ -399,7 +416,13 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev)
void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev) void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
{ {
cfg80211_sme_disassoc(wdev); struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
if (!wdev->conn)
return;
wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
schedule_work(&rdev->conn_work);
} }
static int cfg80211_sme_connect(struct wireless_dev *wdev, static int cfg80211_sme_connect(struct wireless_dev *wdev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment