Merge remote-tracking branch 'net-next/master' into mac80211-next
Merge back net-next to get wireless driver changes (from Kalle) to be able to create the API change across all trees properly. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -2498,51 +2498,22 @@ static bool ieee80211_coalesce_started_roc(struct ieee80211_local *local,
|
||||
struct ieee80211_roc_work *new_roc,
|
||||
struct ieee80211_roc_work *cur_roc)
|
||||
{
|
||||
unsigned long j = jiffies;
|
||||
unsigned long cur_roc_end = cur_roc->hw_start_time +
|
||||
msecs_to_jiffies(cur_roc->duration);
|
||||
struct ieee80211_roc_work *next_roc;
|
||||
int new_dur;
|
||||
unsigned long now = jiffies;
|
||||
unsigned long remaining = cur_roc->hw_start_time +
|
||||
msecs_to_jiffies(cur_roc->duration) -
|
||||
now;
|
||||
|
||||
if (WARN_ON(!cur_roc->started || !cur_roc->hw_begun))
|
||||
return false;
|
||||
|
||||
if (time_after(j + IEEE80211_ROC_MIN_LEFT, cur_roc_end))
|
||||
/* if it doesn't fit entirely, schedule a new one */
|
||||
if (new_roc->duration > jiffies_to_msecs(remaining))
|
||||
return false;
|
||||
|
||||
ieee80211_handle_roc_started(new_roc);
|
||||
|
||||
new_dur = new_roc->duration - jiffies_to_msecs(cur_roc_end - j);
|
||||
|
||||
/* cur_roc is long enough - add new_roc to the dependents list. */
|
||||
if (new_dur <= 0) {
|
||||
list_add_tail(&new_roc->list, &cur_roc->dependents);
|
||||
return true;
|
||||
}
|
||||
|
||||
new_roc->duration = new_dur;
|
||||
|
||||
/*
|
||||
* if cur_roc was already coalesced before, we might
|
||||
* want to extend the next roc instead of adding
|
||||
* a new one.
|
||||
*/
|
||||
next_roc = list_entry(cur_roc->list.next,
|
||||
struct ieee80211_roc_work, list);
|
||||
if (&next_roc->list != &local->roc_list &&
|
||||
next_roc->chan == new_roc->chan &&
|
||||
next_roc->sdata == new_roc->sdata &&
|
||||
!WARN_ON(next_roc->started)) {
|
||||
list_add_tail(&new_roc->list, &next_roc->dependents);
|
||||
next_roc->duration = max(next_roc->duration,
|
||||
new_roc->duration);
|
||||
next_roc->type = max(next_roc->type, new_roc->type);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* add right after cur_roc */
|
||||
list_add(&new_roc->list, &cur_roc->list);
|
||||
|
||||
/* add to dependents so we send the expired event properly */
|
||||
list_add_tail(&new_roc->list, &cur_roc->dependents);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2660,17 +2631,9 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
||||
* In the offloaded ROC case, if it hasn't begun, add
|
||||
* this new one to the dependent list to be handled
|
||||
* when the master one begins. If it has begun,
|
||||
* check that there's still a minimum time left and
|
||||
* if so, start this one, transmitting the frame, but
|
||||
* add it to the list directly after this one with
|
||||
* a reduced time so we'll ask the driver to execute
|
||||
* it right after finishing the previous one, in the
|
||||
* hope that it'll also be executed right afterwards,
|
||||
* effectively extending the old one.
|
||||
* If there's no minimum time left, just add it to the
|
||||
* normal list.
|
||||
* TODO: the ROC type is ignored here, assuming that it
|
||||
* is better to immediately use the current ROC.
|
||||
* check if it fits entirely within the existing one,
|
||||
* in which case it will just be dependent as well.
|
||||
* Otherwise, schedule it by itself.
|
||||
*/
|
||||
if (!tmp->hw_begun) {
|
||||
list_add_tail(&roc->list, &tmp->dependents);
|
||||
|
@@ -202,6 +202,8 @@ enum ieee80211_packet_rx_flags {
|
||||
* @IEEE80211_RX_CMNTR: received on cooked monitor already
|
||||
* @IEEE80211_RX_BEACON_REPORTED: This frame was already reported
|
||||
* to cfg80211_report_obss_beacon().
|
||||
* @IEEE80211_RX_REORDER_TIMER: this frame is released by the
|
||||
* reorder buffer timeout timer, not the normal RX path
|
||||
*
|
||||
* These flags are used across handling multiple interfaces
|
||||
* for a single frame.
|
||||
@@ -209,6 +211,7 @@ enum ieee80211_packet_rx_flags {
|
||||
enum ieee80211_rx_flags {
|
||||
IEEE80211_RX_CMNTR = BIT(0),
|
||||
IEEE80211_RX_BEACON_REPORTED = BIT(1),
|
||||
IEEE80211_RX_REORDER_TIMER = BIT(2),
|
||||
};
|
||||
|
||||
struct ieee80211_rx_data {
|
||||
@@ -322,12 +325,6 @@ struct mesh_preq_queue {
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
#if HZ/100 == 0
|
||||
#define IEEE80211_ROC_MIN_LEFT 1
|
||||
#else
|
||||
#define IEEE80211_ROC_MIN_LEFT (HZ/100)
|
||||
#endif
|
||||
|
||||
struct ieee80211_roc_work {
|
||||
struct list_head list;
|
||||
struct list_head dependents;
|
||||
|
@@ -522,6 +522,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
||||
memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
|
||||
sizeof(sdata->vif.hw_queue));
|
||||
sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef;
|
||||
|
||||
mutex_lock(&local->key_mtx);
|
||||
sdata->crypto_tx_tailroom_needed_cnt +=
|
||||
master->crypto_tx_tailroom_needed_cnt;
|
||||
mutex_unlock(&local->key_mtx);
|
||||
|
||||
break;
|
||||
}
|
||||
case NL80211_IFTYPE_AP:
|
||||
@@ -816,13 +822,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
||||
* (because if we remove a STA after ops->remove_interface()
|
||||
* the driver will have removed the vif info already!)
|
||||
*
|
||||
* This is relevant only in WDS mode, in all other modes we've
|
||||
* already removed all stations when disconnecting or similar,
|
||||
* so warn otherwise.
|
||||
* In WDS mode a station must exist here and be flushed, for
|
||||
* AP_VLANs stations may exist since there's nothing else that
|
||||
* would have removed them, but in other modes there shouldn't
|
||||
* be any stations.
|
||||
*/
|
||||
flushed = sta_info_flush(sdata);
|
||||
WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
|
||||
(sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1));
|
||||
WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
|
||||
((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
|
||||
(sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)));
|
||||
|
||||
/* don't count this interface for allmulti while it is down */
|
||||
if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
|
||||
|
@@ -58,6 +58,22 @@ static void assert_key_lock(struct ieee80211_local *local)
|
||||
lockdep_assert_held(&local->key_mtx);
|
||||
}
|
||||
|
||||
static void
|
||||
update_vlan_tailroom_need_count(struct ieee80211_sub_if_data *sdata, int delta)
|
||||
{
|
||||
struct ieee80211_sub_if_data *vlan;
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_AP)
|
||||
return;
|
||||
|
||||
mutex_lock(&sdata->local->mtx);
|
||||
|
||||
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
||||
vlan->crypto_tx_tailroom_needed_cnt += delta;
|
||||
|
||||
mutex_unlock(&sdata->local->mtx);
|
||||
}
|
||||
|
||||
static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
/*
|
||||
@@ -79,6 +95,8 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
|
||||
* http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net
|
||||
*/
|
||||
|
||||
update_vlan_tailroom_need_count(sdata, 1);
|
||||
|
||||
if (!sdata->crypto_tx_tailroom_needed_cnt++) {
|
||||
/*
|
||||
* Flush all XMIT packets currently using HW encryption or no
|
||||
@@ -88,6 +106,15 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void decrease_tailroom_need_count(struct ieee80211_sub_if_data *sdata,
|
||||
int delta)
|
||||
{
|
||||
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt < delta);
|
||||
|
||||
update_vlan_tailroom_need_count(sdata, -delta);
|
||||
sdata->crypto_tx_tailroom_needed_cnt -= delta;
|
||||
}
|
||||
|
||||
static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
@@ -144,7 +171,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
||||
|
||||
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
||||
(key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM)))
|
||||
sdata->crypto_tx_tailroom_needed_cnt--;
|
||||
decrease_tailroom_need_count(sdata, 1);
|
||||
|
||||
WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
|
||||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));
|
||||
@@ -545,7 +572,7 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
|
||||
schedule_delayed_work(&sdata->dec_tailroom_needed_wk,
|
||||
HZ/2);
|
||||
} else {
|
||||
sdata->crypto_tx_tailroom_needed_cnt--;
|
||||
decrease_tailroom_need_count(sdata, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,6 +662,7 @@ void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
|
||||
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_key *key;
|
||||
struct ieee80211_sub_if_data *vlan;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
@@ -643,7 +671,14 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
||||
|
||||
mutex_lock(&sdata->local->key_mtx);
|
||||
|
||||
sdata->crypto_tx_tailroom_needed_cnt = 0;
|
||||
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
|
||||
sdata->crypto_tx_tailroom_pending_dec);
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
||||
WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt ||
|
||||
vlan->crypto_tx_tailroom_pending_dec);
|
||||
}
|
||||
|
||||
list_for_each_entry(key, &sdata->key_list, list) {
|
||||
increment_tailroom_need_count(sdata);
|
||||
@@ -653,6 +688,22 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
||||
mutex_unlock(&sdata->local->key_mtx);
|
||||
}
|
||||
|
||||
void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_sub_if_data *vlan;
|
||||
|
||||
mutex_lock(&sdata->local->key_mtx);
|
||||
|
||||
sdata->crypto_tx_tailroom_needed_cnt = 0;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
||||
vlan->crypto_tx_tailroom_needed_cnt = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&sdata->local->key_mtx);
|
||||
}
|
||||
|
||||
void ieee80211_iter_keys(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
@@ -692,8 +743,8 @@ static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata,
|
||||
{
|
||||
struct ieee80211_key *key, *tmp;
|
||||
|
||||
sdata->crypto_tx_tailroom_needed_cnt -=
|
||||
sdata->crypto_tx_tailroom_pending_dec;
|
||||
decrease_tailroom_need_count(sdata,
|
||||
sdata->crypto_tx_tailroom_pending_dec);
|
||||
sdata->crypto_tx_tailroom_pending_dec = 0;
|
||||
|
||||
ieee80211_debugfs_key_remove_mgmt_default(sdata);
|
||||
@@ -713,6 +764,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_sub_if_data *vlan;
|
||||
struct ieee80211_sub_if_data *master;
|
||||
struct ieee80211_key *key, *tmp;
|
||||
LIST_HEAD(keys);
|
||||
|
||||
@@ -732,8 +784,20 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
|
||||
list_for_each_entry_safe(key, tmp, &keys, list)
|
||||
__ieee80211_key_destroy(key, false);
|
||||
|
||||
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
|
||||
sdata->crypto_tx_tailroom_pending_dec);
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
||||
if (sdata->bss) {
|
||||
master = container_of(sdata->bss,
|
||||
struct ieee80211_sub_if_data,
|
||||
u.ap);
|
||||
|
||||
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt !=
|
||||
master->crypto_tx_tailroom_needed_cnt);
|
||||
}
|
||||
} else {
|
||||
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
|
||||
sdata->crypto_tx_tailroom_pending_dec);
|
||||
}
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
||||
WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt ||
|
||||
@@ -797,8 +861,8 @@ void ieee80211_delayed_tailroom_dec(struct work_struct *wk)
|
||||
*/
|
||||
|
||||
mutex_lock(&sdata->local->key_mtx);
|
||||
sdata->crypto_tx_tailroom_needed_cnt -=
|
||||
sdata->crypto_tx_tailroom_pending_dec;
|
||||
decrease_tailroom_need_count(sdata,
|
||||
sdata->crypto_tx_tailroom_pending_dec);
|
||||
sdata->crypto_tx_tailroom_pending_dec = 0;
|
||||
mutex_unlock(&sdata->local->key_mtx);
|
||||
}
|
||||
|
@@ -156,6 +156,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
|
||||
void ieee80211_free_sta_keys(struct ieee80211_local *local,
|
||||
struct sta_info *sta);
|
||||
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata);
|
||||
|
||||
#define key_mtx_dereference(local, ref) \
|
||||
rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx)))
|
||||
|
@@ -2108,7 +2108,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
|
||||
/* deliver to local stack */
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
memset(skb->cb, 0, sizeof(skb->cb));
|
||||
if (rx->local->napi)
|
||||
if (!(rx->flags & IEEE80211_RX_REORDER_TIMER) &&
|
||||
rx->local->napi)
|
||||
napi_gro_receive(rx->local->napi, skb);
|
||||
else
|
||||
netif_receive_skb(skb);
|
||||
@@ -3215,7 +3216,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
|
||||
/* This is OK -- must be QoS data frame */
|
||||
.security_idx = tid,
|
||||
.seqno_idx = tid,
|
||||
.flags = 0,
|
||||
.flags = IEEE80211_RX_REORDER_TIMER,
|
||||
};
|
||||
struct tid_ampdu_rx *tid_agg_rx;
|
||||
|
||||
|
@@ -66,6 +66,7 @@
|
||||
|
||||
static const struct rhashtable_params sta_rht_params = {
|
||||
.nelem_hint = 3, /* start small */
|
||||
.automatic_shrinking = true,
|
||||
.head_offset = offsetof(struct sta_info, hash_node),
|
||||
.key_offset = offsetof(struct sta_info, sta.addr),
|
||||
.key_len = ETH_ALEN,
|
||||
@@ -158,8 +159,24 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
|
||||
const u8 *addr)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct sta_info *sta;
|
||||
struct rhash_head *tmp;
|
||||
const struct bucket_table *tbl;
|
||||
|
||||
return rhashtable_lookup_fast(&local->sta_hash, addr, sta_rht_params);
|
||||
rcu_read_lock();
|
||||
tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
|
||||
|
||||
for_each_sta_info(local, tbl, addr, sta, tmp) {
|
||||
if (sta->sdata == sdata) {
|
||||
rcu_read_unlock();
|
||||
/* this is safe as the caller must already hold
|
||||
* another rcu read section or the mutex
|
||||
*/
|
||||
return sta;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -2022,6 +2022,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
|
||||
/* add back keys */
|
||||
list_for_each_entry(sdata, &local->interfaces, list)
|
||||
ieee80211_reset_crypto_tx_tailroom(sdata);
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list)
|
||||
if (ieee80211_sdata_running(sdata))
|
||||
ieee80211_enable_keys(sdata);
|
||||
|
@@ -98,8 +98,7 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
|
||||
|
||||
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
|
||||
if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN ||
|
||||
skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
|
||||
if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
|
||||
return NULL;
|
||||
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
@@ -167,6 +166,9 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
|
||||
size_t len;
|
||||
u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
|
||||
|
||||
if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN))
|
||||
return -1;
|
||||
|
||||
iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx);
|
||||
if (!iv)
|
||||
return -1;
|
||||
|
Reference in New Issue
Block a user