Commit c66cfd53 authored by John W. Linville's avatar John W. Linville

Merge branch 'for-john' of git://git.sipsolutions.net/mac80211-next

parents ecbbec2e 8acbcddb
...@@ -2223,7 +2223,7 @@ static int __init init_mac80211_hwsim(void) ...@@ -2223,7 +2223,7 @@ static int __init init_mac80211_hwsim(void)
IEEE80211_VHT_CAP_RXSTBC_2 | IEEE80211_VHT_CAP_RXSTBC_2 |
IEEE80211_VHT_CAP_RXSTBC_3 | IEEE80211_VHT_CAP_RXSTBC_3 |
IEEE80211_VHT_CAP_RXSTBC_4 | IEEE80211_VHT_CAP_RXSTBC_4 |
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT; IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
sband->vht_cap.vht_mcs.rx_mcs_map = sband->vht_cap.vht_mcs.rx_mcs_map =
cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 | cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 |
IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 |
......
...@@ -5090,7 +5090,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -5090,7 +5090,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_REPORTS_TX_ACK_STATUS; IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL;
/* /*
* Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
......
...@@ -392,10 +392,9 @@ void rt2x00lib_txdone(struct queue_entry *entry, ...@@ -392,10 +392,9 @@ void rt2x00lib_txdone(struct queue_entry *entry,
tx_info->flags |= IEEE80211_TX_STAT_AMPDU; tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
tx_info->status.ampdu_len = 1; tx_info->status.ampdu_len = 1;
tx_info->status.ampdu_ack_len = success ? 1 : 0; tx_info->status.ampdu_ack_len = success ? 1 : 0;
/*
* TODO: Need to tear down BA session here if (!success)
* if not successful. tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
*/
} }
if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
......
...@@ -1272,7 +1272,9 @@ struct ieee80211_vht_operation { ...@@ -1272,7 +1272,9 @@ struct ieee80211_vht_operation {
#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 #define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000
#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 #define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
#define IEEE80211_VHT_CAP_HTC_VHT 0x00400000 #define IEEE80211_VHT_CAP_HTC_VHT 0x00400000
#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT 0x00800000 #define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT 23
#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT)
#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000 #define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000
#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000 #define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000
#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000 #define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000
......
...@@ -1369,6 +1369,10 @@ struct ieee80211_tx_control { ...@@ -1369,6 +1369,10 @@ struct ieee80211_tx_control {
* @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any * @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any
* P2P Interface. This will be honoured even if more than one interface * P2P Interface. This will be honoured even if more than one interface
* is supported. * is supported.
*
* @IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL: On this hardware TX BA session
* should be tear down once BAR frame will not be acked.
*
*/ */
enum ieee80211_hw_flags { enum ieee80211_hw_flags {
IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
...@@ -1397,6 +1401,7 @@ enum ieee80211_hw_flags { ...@@ -1397,6 +1401,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23,
IEEE80211_HW_SCAN_WHILE_IDLE = 1<<24, IEEE80211_HW_SCAN_WHILE_IDLE = 1<<24,
IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25, IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25,
IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL = 1<<26,
}; };
/** /**
......
...@@ -445,7 +445,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, ...@@ -445,7 +445,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
trace_api_start_tx_ba_session(pubsta, 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; return -EINVAL;
if ((tid >= IEEE80211_NUM_TIDS) || if ((tid >= IEEE80211_NUM_TIDS) ||
......
...@@ -199,6 +199,22 @@ static ssize_t key_icverrors_read(struct file *file, char __user *userbuf, ...@@ -199,6 +199,22 @@ static ssize_t key_icverrors_read(struct file *file, char __user *userbuf,
} }
KEY_OPS(icverrors); 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, static ssize_t key_key_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
...@@ -260,6 +276,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key) ...@@ -260,6 +276,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
DEBUGFS_ADD(rx_spec); DEBUGFS_ADD(rx_spec);
DEBUGFS_ADD(replays); DEBUGFS_ADD(replays);
DEBUGFS_ADD(icverrors); DEBUGFS_ADD(icverrors);
DEBUGFS_ADD(mic_failures);
DEBUGFS_ADD(key); DEBUGFS_ADD(key);
DEBUGFS_ADD(ifindex); DEBUGFS_ADD(ifindex);
}; };
......
...@@ -201,6 +201,20 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -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_BASIC_RATES;
bss_change |= BSS_CHANGED_HT; bss_change |= BSS_CHANGED_HT;
bss_change |= BSS_CHANGED_IBSS; 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_joined = true;
sdata->vif.bss_conf.ibss_creator = creator; sdata->vif.bss_conf.ibss_creator = creator;
ieee80211_bss_info_change_notify(sdata, bss_change); ieee80211_bss_info_change_notify(sdata, bss_change);
......
...@@ -862,7 +862,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ...@@ -862,7 +862,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
rcu_assign_pointer(local->p2p_sdata, NULL); rcu_assign_pointer(local->p2p_sdata, NULL);
/* fall through */ /* fall through */
default: default:
flush_work(&sdata->work); cancel_work_sync(&sdata->work);
/* /*
* When we get here, the interface is marked down. * When we get here, the interface is marked down.
* Call rcu_barrier() to wait both for the RX path * Call rcu_barrier() to wait both for the RX path
......
...@@ -81,6 +81,9 @@ struct ieee80211_key { ...@@ -81,6 +81,9 @@ struct ieee80211_key {
/* last received RSC */ /* last received RSC */
struct tkip_ctx rx[IEEE80211_NUM_TIDS]; struct tkip_ctx rx[IEEE80211_NUM_TIDS];
/* number of mic failures */
u32 mic_failures;
} tkip; } tkip;
struct { struct {
atomic64_t tx_pn; atomic64_t tx_pn;
......
...@@ -2360,9 +2360,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, ...@@ -2360,9 +2360,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
return RX_MGMT_CFG80211_RX_ASSOC; return RX_MGMT_CFG80211_RX_ASSOC;
} }
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, struct ieee80211_mgmt *mgmt, size_t len,
size_t len,
struct ieee80211_rx_status *rx_status, struct ieee80211_rx_status *rx_status,
struct ieee802_11_elems *elems, struct ieee802_11_elems *elems,
bool beacon) bool beacon)
......
...@@ -154,6 +154,7 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, ...@@ -154,6 +154,7 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct minstrel_priv *mp = priv;
struct minstrel_sta_info *mi = priv_sta; struct minstrel_sta_info *mi = priv_sta;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *ar = info->status.rates; struct ieee80211_tx_rate *ar = info->status.rates;
...@@ -181,6 +182,10 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, ...@@ -181,6 +182,10 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
if (mi->sample_deferred > 0) if (mi->sample_deferred > 0)
mi->sample_deferred--; 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, ...@@ -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; 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; ndx = mi->max_tp_rate;
if (mrr) if (mrr)
......
...@@ -378,9 +378,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, ...@@ -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. * 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) if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
present_fcs_len = FCS_LEN; present_fcs_len = FCS_LEN;
...@@ -399,6 +396,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, ...@@ -399,6 +396,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
return remove_monitor_info(local, 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)) { if (should_drop_frame(origskb, present_fcs_len)) {
/* only need to expand headroom if necessary */ /* only need to expand headroom if necessary */
skb = origskb; skb = origskb;
...@@ -2333,7 +2333,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ...@@ -2333,7 +2333,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
if (len < IEEE80211_MIN_ACTION_SIZE) if (len < IEEE80211_MIN_ACTION_SIZE)
return RX_DROP_UNUSABLE; 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; return RX_DROP_UNUSABLE;
if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
......
...@@ -502,6 +502,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -502,6 +502,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
IEEE80211_BAR_CTRL_TID_INFO_MASK) >> IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
IEEE80211_BAR_CTRL_TID_INFO_SHIFT; IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
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); ieee80211_set_bar_pending(sta, tid, ssn);
} }
} }
......
...@@ -104,7 +104,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) ...@@ -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_STRIPPED | RX_FLAG_IV_STRIPPED)) {
if (status->flag & RX_FLAG_MMIC_ERROR) if (status->flag & RX_FLAG_MMIC_ERROR)
goto mic_fail; goto mic_fail_no_key;
if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key && if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key &&
rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP) rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)
...@@ -161,6 +161,9 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) ...@@ -161,6 +161,9 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
return RX_CONTINUE; return RX_CONTINUE;
mic_fail: 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 * 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 * a driver that supports HW encryption. Send up the key idx only if
......
...@@ -265,6 +265,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, ...@@ -265,6 +265,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
/* TODO: missing regulatory check on 80/160 bandwidth */ /* 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, if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1,
width, prohibited_flags)) width, prohibited_flags))
return false; return false;
......
...@@ -176,7 +176,7 @@ int cfg80211_wext_giwrange(struct net_device *dev, ...@@ -176,7 +176,7 @@ int cfg80211_wext_giwrange(struct net_device *dev,
case CFG80211_SIGNAL_TYPE_NONE: case CFG80211_SIGNAL_TYPE_NONE:
break; break;
case CFG80211_SIGNAL_TYPE_MBM: case CFG80211_SIGNAL_TYPE_MBM:
range->max_qual.level = -110; range->max_qual.level = (u8)-110;
range->max_qual.qual = 70; range->max_qual.qual = 70;
range->avg_qual.qual = 35; range->avg_qual.qual = 35;
range->max_qual.updated |= IW_QUAL_DBM; range->max_qual.updated |= IW_QUAL_DBM;
......
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