From 2f91a96799d155d56a0663dbe00fc45c6721a763 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Mon, 3 Dec 2012 22:21:30 +0100 Subject: mac80211: adapt slot time in IBSS mode In 5GHz/802.11a, we are allowed to use short slot times. Doing this may increases performance by 20% for legacy connections (54 MBit/s). I can confirm this in my tests (27% more throughput using iperf), and also have a small positive effect (5% more throughput) for HT rates, tested on 1 stream. Signed-off-by: Simon Wunderlich Signed-off-by: Mathias Kretschmer Signed-off-by: Johannes Berg --- net/mac80211/ibss.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'net') diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 11a6a1bde2fd..700d0ed736c9 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); -- cgit v1.2.3 From a6662dbae0b3a7a91317ec88b5aa0cf8d716f183 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 4 Dec 2012 20:49:42 +0100 Subject: cfg80211: check no-OFDM flag for channels wider than 20 MHz For channels wider than 20 MHz OFDM will be used, so when checking whether or not a channel is usable, check for the no-OFDM flag if the channel is wider than 20 MHz. Signed-off-by: Johannes Berg --- net/wireless/chan.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net') diff --git a/net/wireless/chan.c b/net/wireless/chan.c index b5f69831e318..a7990bb16529 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -265,6 +265,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, /* TODO: missing regulatory check on 80/160 bandwidth */ + if (width > 20) + prohibited_flags |= IEEE80211_CHAN_NO_OFDM; + if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, width, prohibited_flags)) return false; -- cgit v1.2.3 From b98ea05861d76f458029096e8b2939fcb58e9530 Mon Sep 17 00:00:00 2001 From: Saravana Date: Tue, 4 Dec 2012 19:47:42 +0530 Subject: mac80211: add debug file for mic failure The mic failure count provides the number of mic failures that have happened on a given key (without a countermeasure being started, since that would remove the key). Signed-off-by: Saravana [fix NULL pointer issues] Signed-off-by: Johannes Berg --- net/mac80211/debugfs_key.c | 17 +++++++++++++++++ net/mac80211/key.h | 3 +++ net/mac80211/wpa.c | 5 ++++- 3 files changed, 24 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 2d4235497f1b..c3a3082b72e5 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/key.h b/net/mac80211/key.h index 7cff0d3a519c..382dc44ed330 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/wpa.c b/net/mac80211/wpa.c index 8bd2f5c6a56e..c175ee866ff4 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 -- cgit v1.2.3 From 5b632fe85ec82e5c43740b52e74c66df50a37db3 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 3 Dec 2012 12:56:33 +0100 Subject: mac80211: introduce IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL Commit f0425beda4d404a6e751439b562100b902ba9c98 "mac80211: retry sending failed BAR frames later instead of tearing down aggr" caused regression on rt2x00 hardware (connection hangs). This regression was fixed by commit be03d4a45c09ee5100d3aaaedd087f19bc20d01 "rt2x00: Don't let mac80211 send a BAR when an AMPDU subframe fails". But the latter commit caused yet another problem reported in https://bugzilla.kernel.org/show_bug.cgi?id=42828#c22 After long discussion in this thread: http://mid.gmane.org/20121018075615.GA18212@redhat.com and testing various alternative solutions, which failed on one or other setup, we have no other good fix for the issues like just revert both mentioned earlier commits. To do not affect other hardware which benefit from commit f0425beda4d404a6e751439b562100b902ba9c98, instead of reverting it, introduce flag that when used will restore mac80211 behaviour before the commit. Cc: stable@vger.kernel.org Signed-off-by: Stanislaw Gruszka [replaced link with mid.gmane.org that has message-id] Signed-off-by: Johannes Berg --- net/mac80211/status.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 6400037dd8ec..04f6bf292a57 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); } } -- cgit v1.2.3 From 751413eadc8f0c7691a6cbd40a913ef0ae6b2ce4 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 5 Dec 2012 14:36:12 +0100 Subject: mac80211: skip radiotap space calculation if no monitor exists The radiotap header length "needed_headroom" is only required if we're sending the skb to a monitor interface. Hence, move the calculation a bit later so the calculation can be skipped if no monitor interface is present. Signed-off-by: Helmut Schaa Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index db343fa8033c..e4ee32748994 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; -- cgit v1.2.3 From 815b8092bd5242d580038213da9179a5a4f69116 Mon Sep 17 00:00:00 2001 From: Marco Porsch Date: Wed, 5 Dec 2012 15:04:26 -0800 Subject: mac80211: don't drop mesh peering frames from unknown STA Previously, mesh peering frames from a STA without a station entry were being dropped. Mesh Peering Open and other frames (WLAN_CATEGORY_SELF_PROTECTED) are valid mesh peering frames even if received from a yet unknown station; the STA entry will be created in mesh_peer_init later. The problem didn't occur previously since both STAs receive each other's beacons which created the STA entry. However, this causes an unnecessary delay and beacons might not be received if either node is in PS mode. Signed-off-by: Marco Porsch [reword commit log a bit] Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index e4ee32748994..580704eba8b8 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -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)) -- cgit v1.2.3 From 0b7dff4faed07f55be2a98dd0eafc02623174236 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 5 Dec 2012 09:49:14 +0100 Subject: mac80211: cancel work instead of waiting for it to do nothing If the sdata work is pending while the interface is stopped, we currently flush it. If it's not running this means waiting for it to run, which could take a while if the workqueue is backlogged. However, the work exits right away if it starts to run while the interface is already stopping. There's no point in waiting for that, so use cancel_work_sync() instead. Reported-by: Ben Greear Tested-by: Ben Greear Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 40c36d5d7377..09a80b55cf5a 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 -- cgit v1.2.3 From 50c16e2251b63224c05e35d80d434a479a312b4a Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Fri, 7 Dec 2012 12:19:34 +0530 Subject: mac80211: warn only once if ampdu_action isn't assigned New drivers that might not support ampdu_action yet while in development cause a lot of warnings, use WARN_ON_ONCE instead. Signed-off-by: T Krushna Chaitanya Signed-off-by: Johannes Berg --- net/mac80211/agg-tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 4152ed1034b8..eb9df22418f0 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) || -- cgit v1.2.3 From e7d83ed8d0c486fc342e93291e31b3283e3721e7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 7 Dec 2012 11:58:26 +0100 Subject: wext: explicitly cast -110 to u8 This doesn't generate any different code, but will suppress a spurious smatch warning. Signed-off-by: Johannes Berg --- net/wireless/wext-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index f9680c9cf9b3..d997d0f0c54a 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -176,7 +176,7 @@ int cfg80211_wext_giwrange(struct net_device *dev, case CFG80211_SIGNAL_TYPE_NONE: break; case CFG80211_SIGNAL_TYPE_MBM: - range->max_qual.level = -110; + range->max_qual.level = (u8)-110; range->max_qual.qual = 70; range->avg_qual.qual = 35; range->max_qual.updated |= IW_QUAL_DBM; -- cgit v1.2.3 From 8e3c1b77435d93c0207d4701ca5b3e84d40c983d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 10 Dec 2012 13:44:19 +0100 Subject: mac80211: a few whitespace fixes Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 4 ++-- net/mac80211/scan.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 09556303c7e1..7753a9ca98a6 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/scan.c b/net/mac80211/scan.c index d7c190b80670..cb3df39d5fa6 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 */ -- cgit v1.2.3 From 8acbcddb5fb3a1dc081defe51b6ac42a7ab0b398 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Nov 2012 18:27:56 +0100 Subject: minstrel: update stats after processing status Instead of updating stats before sending a packet, update them after processing the packet's status. This makes minstrel in line with minstrel_ht. Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 79633ae06fd6..8c5acdc06226 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) -- cgit v1.2.3