summaryrefslogtreecommitdiff
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/agg-tx.c2
-rw-r--r--net/mac80211/debugfs_key.c17
-rw-r--r--net/mac80211/ibss.c14
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/mlme.c4
-rw-r--r--net/mac80211/rc80211_minstrel.c9
-rw-r--r--net/mac80211/rx.c9
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/mac80211/status.c6
-rw-r--r--net/mac80211/wpa.c5
11 files changed, 58 insertions, 15 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 4152ed1034b..eb9df22418f 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -445,7 +445,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
trace_api_start_tx_ba_session(pubsta, tid);
- if (WARN_ON(!local->ops->ampdu_action))
+ if (WARN_ON_ONCE(!local->ops->ampdu_action))
return -EINVAL;
if ((tid >= IEEE80211_NUM_TIDS) ||
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 2d4235497f1..c3a3082b72e 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -199,6 +199,22 @@ static ssize_t key_icverrors_read(struct file *file, char __user *userbuf,
}
KEY_OPS(icverrors);
+static ssize_t key_mic_failures_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_key *key = file->private_data;
+ char buf[20];
+ int len;
+
+ if (key->conf.cipher != WLAN_CIPHER_SUITE_TKIP)
+ return -EINVAL;
+
+ len = scnprintf(buf, sizeof(buf), "%u\n", key->u.tkip.mic_failures);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+KEY_OPS(mic_failures);
+
static ssize_t key_key_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
@@ -260,6 +276,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
DEBUGFS_ADD(rx_spec);
DEBUGFS_ADD(replays);
DEBUGFS_ADD(icverrors);
+ DEBUGFS_ADD(mic_failures);
DEBUGFS_ADD(key);
DEBUGFS_ADD(ifindex);
};
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index fa862b24a7e..8881fc77fb1 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -201,6 +201,20 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
bss_change |= BSS_CHANGED_BASIC_RATES;
bss_change |= BSS_CHANGED_HT;
bss_change |= BSS_CHANGED_IBSS;
+
+ /*
+ * In 5 GHz/802.11a, we can always use short slot time.
+ * (IEEE 802.11-2012 18.3.8.7)
+ *
+ * In 2.4GHz, we must always use long slots in IBSS for compatibility
+ * reasons.
+ * (IEEE 802.11-2012 19.4.5)
+ *
+ * HT follows these specifications (IEEE 802.11-2012 20.3.18)
+ */
+ sdata->vif.bss_conf.use_short_slot = chan->band == IEEE80211_BAND_5GHZ;
+ bss_change |= BSS_CHANGED_ERP_SLOT;
+
sdata->vif.bss_conf.ibss_joined = true;
sdata->vif.bss_conf.ibss_creator = creator;
ieee80211_bss_info_change_notify(sdata, bss_change);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 40c36d5d737..09a80b55cf5 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -862,7 +862,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
rcu_assign_pointer(local->p2p_sdata, NULL);
/* fall through */
default:
- flush_work(&sdata->work);
+ cancel_work_sync(&sdata->work);
/*
* When we get here, the interface is marked down.
* Call rcu_barrier() to wait both for the RX path
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 7cff0d3a519..382dc44ed33 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -81,6 +81,9 @@ struct ieee80211_key {
/* last received RSC */
struct tkip_ctx rx[IEEE80211_NUM_TIDS];
+
+ /* number of mic failures */
+ u32 mic_failures;
} tkip;
struct {
atomic64_t tx_pn;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 09556303c7e..7753a9ca98a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2360,9 +2360,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
return RX_MGMT_CFG80211_RX_ASSOC;
}
+
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_mgmt *mgmt,
- size_t len,
+ struct ieee80211_mgmt *mgmt, size_t len,
struct ieee80211_rx_status *rx_status,
struct ieee802_11_elems *elems,
bool beacon)
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 79633ae06fd..8c5acdc0622 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -154,6 +154,7 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb)
{
+ struct minstrel_priv *mp = priv;
struct minstrel_sta_info *mi = priv_sta;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *ar = info->status.rates;
@@ -181,6 +182,10 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
if (mi->sample_deferred > 0)
mi->sample_deferred--;
+
+ if (time_after(jiffies, mi->stats_update +
+ (mp->update_interval * HZ) / 1000))
+ minstrel_update_stats(mp, mi);
}
@@ -235,10 +240,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;
- if (time_after(jiffies, mi->stats_update + (mp->update_interval *
- HZ) / 1000))
- minstrel_update_stats(mp, mi);
-
ndx = mi->max_tp_rate;
if (mrr)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index db343fa8033..580704eba8b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -378,9 +378,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
* the SKB because it has a bad FCS/PLCP checksum.
*/
- /* room for the radiotap header based on driver features */
- needed_headroom = ieee80211_rx_radiotap_space(local, status);
-
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
present_fcs_len = FCS_LEN;
@@ -399,6 +396,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
return remove_monitor_info(local, origskb);
}
+ /* room for the radiotap header based on driver features */
+ needed_headroom = ieee80211_rx_radiotap_space(local, status);
+
if (should_drop_frame(origskb, present_fcs_len)) {
/* only need to expand headroom if necessary */
skb = origskb;
@@ -2333,7 +2333,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
if (len < IEEE80211_MIN_ACTION_SIZE)
return RX_DROP_UNUSABLE;
- if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
+ if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
+ mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED)
return RX_DROP_UNUSABLE;
if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f7176ac5a53..8ed83dcc149 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -118,7 +118,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
struct ieee80211_tim_ie *tim_ie = elems->tim;
bss->dtim_period = tim_ie->dtim_period;
if (!elems->parse_error)
- bss->valid_data |= IEEE80211_BSS_VALID_DTIM;
+ bss->valid_data |= IEEE80211_BSS_VALID_DTIM;
}
/* If the beacon had no TIM IE, or it was invalid, use 1 */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index ab50285fcba..07d99578a2b 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -502,7 +502,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
- ieee80211_set_bar_pending(sta, tid, ssn);
+ if (local->hw.flags &
+ IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL)
+ ieee80211_stop_tx_ba_session(&sta->sta, tid);
+ else
+ ieee80211_set_bar_pending(sta, tid, ssn);
}
}
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 8bd2f5c6a56..c175ee866ff 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -104,7 +104,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
*/
if (status->flag & (RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED)) {
if (status->flag & RX_FLAG_MMIC_ERROR)
- goto mic_fail;
+ goto mic_fail_no_key;
if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key &&
rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)
@@ -161,6 +161,9 @@ update_iv:
return RX_CONTINUE;
mic_fail:
+ rx->key->u.tkip.mic_failures++;
+
+mic_fail_no_key:
/*
* In some cases the key can be unset - e.g. a multicast packet, in
* a driver that supports HW encryption. Send up the key idx only if