Back from a long absence, so we have a number of things:
* a remain-on-channel fix from Avi * hwsim TX power fix from Beni * null-PTR dereference with iTXQ in some rare configurations (Chunho) * 40 MHz custom regdomain fixes (Emmanuel) * look at right place in HT/VHT capability parsing (Igor) * complete A-MPDU teardown properly (Ilan) * Mesh ID Element ordering fix (Liad) * avoid tracing warning in ht_dbg() (Sharon) * fix print of assoc/reassoc (Simon) * fix encrypted VLAN with iTXQ (myself) * fix calling context of TX queue wake (myself) * fix a deadlock with ath10k aggregation (myself) -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEExu3sM/nZ1eRSfR9Ha3t4Rpy0AB0FAlmw78wACgkQa3t4Rpy0 AB1viw/+K2xrwzsKqrNoNM1sV4bPItUTjay64dPVD5CjJ/pAwou6HCu0gCJCh4kt mXhLWHds7Q4sBY+DlN9eIagQLJUaw897FWV+tHHirDGKMsE4tBaIct7PLBpM7r5O H03T5qT9+nDGRAJq6ucLG8v91cTAlBNfEIV73Au9Oi5B0Rq4cs+Tz8xS24EHjfTB zRcLMaE8qoQjIfrwQsYNQBdvYHY5G+Ui5sbPh3HPLDPzAfKAsc75nbikI2QE//s0 cMv5ro39vy0DGyQmdTqNzzzuWWzYvhUD7EiIr7Dfm9ilhljCiVqZg6y7ZVMB/QNq +HRD7ShbTnNMx1fx8w5WO6gKGVSeo0Ga6KKEauTGiWJQTfZQLuIBLylSMVclfvBN 4zOv3vC9EUP5qqPt0cby7VV2D+1Z4Lw2GYZZKHF5numMkgHAoDJ+tJHbBFmz1CEX co/79RFhGLKvZE+8lN40hqvPoYA5NOUO6jyOq384ZbnC190nVqOXvIxi9jmFKBHp rGBE/8e0VPYlc48m6NUFwAvc0HOeN3/ZVaUnoo6SY8fCbru3yhRYzC3pmcepTEbA OVBHirgYtntI2mk4FWd2dkTC6aOfP1o11dwm3deaaEtkwaiKlxI2xfnkbsGaMaOh RW787Y10g0k785ABD/GxynOeqfiXnIxIjMKZiQliR33zxdv4cAI= =QYS4 -----END PGP SIGNATURE----- Merge tag 'mac80211-for-davem-2017-09-07' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 Johannes Berg says: ==================== Back from a long absence, so we have a number of things: * a remain-on-channel fix from Avi * hwsim TX power fix from Beni * null-PTR dereference with iTXQ in some rare configurations (Chunho) * 40 MHz custom regdomain fixes (Emmanuel) * look at right place in HT/VHT capability parsing (Igor) * complete A-MPDU teardown properly (Ilan) * Mesh ID Element ordering fix (Liad) * avoid tracing warning in ht_dbg() (Sharon) * fix print of assoc/reassoc (Simon) * fix encrypted VLAN with iTXQ (myself) * fix calling context of TX queue wake (myself) * fix a deadlock with ath10k aggregation (myself) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
0f2be423f1
|
@ -1362,8 +1362,6 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
|
||||||
txi->control.rates,
|
txi->control.rates,
|
||||||
ARRAY_SIZE(txi->control.rates));
|
ARRAY_SIZE(txi->control.rates));
|
||||||
|
|
||||||
txi->rate_driver_data[0] = channel;
|
|
||||||
|
|
||||||
if (skb->len >= 24 + 8 &&
|
if (skb->len >= 24 + 8 &&
|
||||||
ieee80211_is_probe_resp(hdr->frame_control)) {
|
ieee80211_is_probe_resp(hdr->frame_control)) {
|
||||||
/* fake header transmission time */
|
/* fake header transmission time */
|
||||||
|
|
|
@ -918,22 +918,11 @@ struct ieee80211_tx_info {
|
||||||
/* only needed before rate control */
|
/* only needed before rate control */
|
||||||
unsigned long jiffies;
|
unsigned long jiffies;
|
||||||
};
|
};
|
||||||
/* NB: vif can be NULL for injected frames */
|
|
||||||
union {
|
|
||||||
/* NB: vif can be NULL for injected frames */
|
/* NB: vif can be NULL for injected frames */
|
||||||
struct ieee80211_vif *vif;
|
struct ieee80211_vif *vif;
|
||||||
|
|
||||||
/* When packets are enqueued on txq it's easy
|
|
||||||
* to re-construct the vif pointer. There's no
|
|
||||||
* more space in tx_info so it can be used to
|
|
||||||
* store the necessary enqueue time for packet
|
|
||||||
* sojourn time computation.
|
|
||||||
*/
|
|
||||||
codel_time_t enqueue_time;
|
|
||||||
};
|
|
||||||
struct ieee80211_key_conf *hw_key;
|
struct ieee80211_key_conf *hw_key;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
/* 4 bytes free */
|
codel_time_t enqueue_time;
|
||||||
} control;
|
} control;
|
||||||
struct {
|
struct {
|
||||||
u64 cookie;
|
u64 cookie;
|
||||||
|
|
|
@ -245,7 +245,7 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
|
||||||
ieee80211_tx_skb(sdata, skb);
|
ieee80211_tx_skb(sdata, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||||
u8 dialog_token, u16 timeout,
|
u8 dialog_token, u16 timeout,
|
||||||
u16 start_seq_num, u16 ba_policy, u16 tid,
|
u16 start_seq_num, u16 ba_policy, u16 tid,
|
||||||
u16 buf_size, bool tx, bool auto_seq)
|
u16 buf_size, bool tx, bool auto_seq)
|
||||||
|
@ -267,7 +267,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||||
ht_dbg(sta->sdata,
|
ht_dbg(sta->sdata,
|
||||||
"STA %pM requests BA session on unsupported tid %d\n",
|
"STA %pM requests BA session on unsupported tid %d\n",
|
||||||
sta->sta.addr, tid);
|
sta->sta.addr, tid);
|
||||||
goto end_no_lock;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sta->sta.ht_cap.ht_supported) {
|
if (!sta->sta.ht_cap.ht_supported) {
|
||||||
|
@ -275,14 +275,14 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||||
"STA %pM erroneously requests BA session on tid %d w/o QoS\n",
|
"STA %pM erroneously requests BA session on tid %d w/o QoS\n",
|
||||||
sta->sta.addr, tid);
|
sta->sta.addr, tid);
|
||||||
/* send a response anyway, it's an error case if we get here */
|
/* send a response anyway, it's an error case if we get here */
|
||||||
goto end_no_lock;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
|
if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
|
||||||
ht_dbg(sta->sdata,
|
ht_dbg(sta->sdata,
|
||||||
"Suspend in progress - Denying ADDBA request (%pM tid %d)\n",
|
"Suspend in progress - Denying ADDBA request (%pM tid %d)\n",
|
||||||
sta->sta.addr, tid);
|
sta->sta.addr, tid);
|
||||||
goto end_no_lock;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sanity check for incoming parameters:
|
/* sanity check for incoming parameters:
|
||||||
|
@ -296,7 +296,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||||
ht_dbg_ratelimited(sta->sdata,
|
ht_dbg_ratelimited(sta->sdata,
|
||||||
"AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n",
|
"AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n",
|
||||||
sta->sta.addr, tid, ba_policy, buf_size);
|
sta->sta.addr, tid, ba_policy, buf_size);
|
||||||
goto end_no_lock;
|
goto end;
|
||||||
}
|
}
|
||||||
/* determine default buffer size */
|
/* determine default buffer size */
|
||||||
if (buf_size == 0)
|
if (buf_size == 0)
|
||||||
|
@ -311,7 +311,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||||
buf_size, sta->sta.addr);
|
buf_size, sta->sta.addr);
|
||||||
|
|
||||||
/* examine state machine */
|
/* examine state machine */
|
||||||
mutex_lock(&sta->ampdu_mlme.mtx);
|
lockdep_assert_held(&sta->ampdu_mlme.mtx);
|
||||||
|
|
||||||
if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
|
if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
|
||||||
if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) {
|
if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) {
|
||||||
|
@ -415,15 +415,25 @@ end:
|
||||||
__clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
|
__clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
|
||||||
sta->ampdu_mlme.tid_rx_token[tid] = dialog_token;
|
sta->ampdu_mlme.tid_rx_token[tid] = dialog_token;
|
||||||
}
|
}
|
||||||
mutex_unlock(&sta->ampdu_mlme.mtx);
|
|
||||||
|
|
||||||
end_no_lock:
|
|
||||||
if (tx)
|
if (tx)
|
||||||
ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
|
ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
|
||||||
dialog_token, status, 1, buf_size,
|
dialog_token, status, 1, buf_size,
|
||||||
timeout);
|
timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||||
|
u8 dialog_token, u16 timeout,
|
||||||
|
u16 start_seq_num, u16 ba_policy, u16 tid,
|
||||||
|
u16 buf_size, bool tx, bool auto_seq)
|
||||||
|
{
|
||||||
|
mutex_lock(&sta->ampdu_mlme.mtx);
|
||||||
|
___ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
|
||||||
|
start_seq_num, ba_policy, tid,
|
||||||
|
buf_size, tx, auto_seq);
|
||||||
|
mutex_unlock(&sta->ampdu_mlme.mtx);
|
||||||
|
}
|
||||||
|
|
||||||
void ieee80211_process_addba_request(struct ieee80211_local *local,
|
void ieee80211_process_addba_request(struct ieee80211_local *local,
|
||||||
struct sta_info *sta,
|
struct sta_info *sta,
|
||||||
struct ieee80211_mgmt *mgmt,
|
struct ieee80211_mgmt *mgmt,
|
||||||
|
|
|
@ -226,7 +226,11 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable)
|
||||||
clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags);
|
clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags);
|
||||||
|
|
||||||
clear_bit(IEEE80211_TXQ_STOP, &txqi->flags);
|
clear_bit(IEEE80211_TXQ_STOP, &txqi->flags);
|
||||||
|
local_bh_disable();
|
||||||
|
rcu_read_lock();
|
||||||
drv_wake_tx_queue(sta->sdata->local, txqi);
|
drv_wake_tx_queue(sta->sdata->local, txqi);
|
||||||
|
rcu_read_unlock();
|
||||||
|
local_bh_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -436,7 +440,7 @@ static void sta_addba_resp_timer_expired(unsigned long data)
|
||||||
test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) {
|
test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) {
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
ht_dbg(sta->sdata,
|
ht_dbg(sta->sdata,
|
||||||
"timer expired on %pM tid %d but we are not (or no longer) expecting addBA response there\n",
|
"timer expired on %pM tid %d not expecting addBA response\n",
|
||||||
sta->sta.addr, tid);
|
sta->sta.addr, tid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -639,7 +643,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
|
||||||
time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] +
|
time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] +
|
||||||
HT_AGG_RETRIES_PERIOD)) {
|
HT_AGG_RETRIES_PERIOD)) {
|
||||||
ht_dbg(sdata,
|
ht_dbg(sdata,
|
||||||
"BA request denied - waiting a grace period after %d failed requests on %pM tid %u\n",
|
"BA request denied - %d failed requests on %pM tid %u\n",
|
||||||
sta->ampdu_mlme.addba_req_num[tid], sta->sta.addr, tid);
|
sta->ampdu_mlme.addba_req_num[tid], sta->sta.addr, tid);
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto err_unlock_sta;
|
goto err_unlock_sta;
|
||||||
|
|
|
@ -300,6 +300,24 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
|
||||||
|
|
||||||
/* stopping might queue the work again - so cancel only afterwards */
|
/* stopping might queue the work again - so cancel only afterwards */
|
||||||
cancel_work_sync(&sta->ampdu_mlme.work);
|
cancel_work_sync(&sta->ampdu_mlme.work);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case the tear down is part of a reconfigure due to HW restart
|
||||||
|
* request, it is possible that the low level driver requested to stop
|
||||||
|
* the BA session, so handle it to properly clean tid_tx data.
|
||||||
|
*/
|
||||||
|
mutex_lock(&sta->ampdu_mlme.mtx);
|
||||||
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||||
|
struct tid_ampdu_tx *tid_tx =
|
||||||
|
rcu_dereference_protected_tid_tx(sta, i);
|
||||||
|
|
||||||
|
if (!tid_tx)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (test_and_clear_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state))
|
||||||
|
ieee80211_stop_tx_ba_cb(sta, i, tid_tx);
|
||||||
|
}
|
||||||
|
mutex_unlock(&sta->ampdu_mlme.mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_ba_session_work(struct work_struct *work)
|
void ieee80211_ba_session_work(struct work_struct *work)
|
||||||
|
@ -333,7 +351,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
|
||||||
|
|
||||||
if (test_and_clear_bit(tid,
|
if (test_and_clear_bit(tid,
|
||||||
sta->ampdu_mlme.tid_rx_manage_offl))
|
sta->ampdu_mlme.tid_rx_manage_offl))
|
||||||
__ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
|
___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
|
||||||
IEEE80211_MAX_AMPDU_BUF,
|
IEEE80211_MAX_AMPDU_BUF,
|
||||||
false, true);
|
false, true);
|
||||||
|
|
||||||
|
|
|
@ -1760,6 +1760,10 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||||
u8 dialog_token, u16 timeout,
|
u8 dialog_token, u16 timeout,
|
||||||
u16 start_seq_num, u16 ba_policy, u16 tid,
|
u16 start_seq_num, u16 ba_policy, u16 tid,
|
||||||
u16 buf_size, bool tx, bool auto_seq);
|
u16 buf_size, bool tx, bool auto_seq);
|
||||||
|
void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||||
|
u8 dialog_token, u16 timeout,
|
||||||
|
u16 start_seq_num, u16 ba_policy, u16 tid,
|
||||||
|
u16 buf_size, bool tx, bool auto_seq);
|
||||||
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
|
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
|
||||||
enum ieee80211_agg_stop_reason reason);
|
enum ieee80211_agg_stop_reason reason);
|
||||||
void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
|
@ -731,6 +731,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
||||||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
||||||
local->ops->wake_tx_queue) {
|
local->ops->wake_tx_queue) {
|
||||||
/* XXX: for AP_VLAN, actually track AP queues */
|
/* XXX: for AP_VLAN, actually track AP queues */
|
||||||
|
if (dev)
|
||||||
netif_tx_start_all_queues(dev);
|
netif_tx_start_all_queues(dev);
|
||||||
} else if (dev) {
|
} else if (dev) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -792,6 +793,7 @@ static int ieee80211_open(struct net_device *dev)
|
||||||
static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
||||||
bool going_down)
|
bool going_down)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_sub_if_data *txq_sdata = sdata;
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
struct fq *fq = &local->fq;
|
struct fq *fq = &local->fq;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -937,6 +939,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
||||||
switch (sdata->vif.type) {
|
switch (sdata->vif.type) {
|
||||||
case NL80211_IFTYPE_AP_VLAN:
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
txq_sdata = container_of(sdata->bss,
|
||||||
|
struct ieee80211_sub_if_data, u.ap);
|
||||||
|
|
||||||
mutex_lock(&local->mtx);
|
mutex_lock(&local->mtx);
|
||||||
list_del(&sdata->u.vlan.list);
|
list_del(&sdata->u.vlan.list);
|
||||||
mutex_unlock(&local->mtx);
|
mutex_unlock(&local->mtx);
|
||||||
|
@ -1007,8 +1012,17 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||||
|
|
||||||
if (sdata->vif.txq) {
|
if (txq_sdata->vif.txq) {
|
||||||
struct txq_info *txqi = to_txq_info(sdata->vif.txq);
|
struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME FIXME
|
||||||
|
*
|
||||||
|
* We really shouldn't purge the *entire* txqi since that
|
||||||
|
* contains frames for the other AP_VLANs (and possibly
|
||||||
|
* the AP itself) as well, but there's no API in FQ now
|
||||||
|
* to be able to filter.
|
||||||
|
*/
|
||||||
|
|
||||||
spin_lock_bh(&fq->lock);
|
spin_lock_bh(&fq->lock);
|
||||||
ieee80211_txq_purge(local, txqi);
|
ieee80211_txq_purge(local, txqi);
|
||||||
|
|
|
@ -3155,7 +3155,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
||||||
if (len < 24 + 6)
|
if (len < 24 + 6)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
|
reassoc = ieee80211_is_reassoc_resp(mgmt->frame_control);
|
||||||
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
|
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
|
||||||
status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
|
status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
|
||||||
aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
|
aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
|
||||||
|
|
|
@ -707,6 +707,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
||||||
if (!cookie)
|
if (!cookie)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
|
flush_work(&local->hw_roc_start);
|
||||||
|
|
||||||
mutex_lock(&local->mtx);
|
mutex_lock(&local->mtx);
|
||||||
list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
|
list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
|
||||||
if (!mgmt_tx && roc->cookie != cookie)
|
if (!mgmt_tx && roc->cookie != cookie)
|
||||||
|
|
|
@ -1276,11 +1276,6 @@ static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb)
|
||||||
IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
|
IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ieee80211_set_skb_vif(struct sk_buff *skb, struct txq_info *txqi)
|
|
||||||
{
|
|
||||||
IEEE80211_SKB_CB(skb)->control.vif = txqi->txq.vif;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 codel_skb_len_func(const struct sk_buff *skb)
|
static u32 codel_skb_len_func(const struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return skb->len;
|
return skb->len;
|
||||||
|
@ -3414,6 +3409,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_tx_info *info;
|
struct ieee80211_tx_info *info;
|
||||||
struct ieee80211_tx_data tx;
|
struct ieee80211_tx_data tx;
|
||||||
ieee80211_tx_result r;
|
ieee80211_tx_result r;
|
||||||
|
struct ieee80211_vif *vif;
|
||||||
|
|
||||||
spin_lock_bh(&fq->lock);
|
spin_lock_bh(&fq->lock);
|
||||||
|
|
||||||
|
@ -3430,8 +3426,6 @@ begin:
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ieee80211_set_skb_vif(skb, txqi);
|
|
||||||
|
|
||||||
hdr = (struct ieee80211_hdr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
info = IEEE80211_SKB_CB(skb);
|
info = IEEE80211_SKB_CB(skb);
|
||||||
|
|
||||||
|
@ -3488,6 +3482,34 @@ begin:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (tx.sdata->vif.type) {
|
||||||
|
case NL80211_IFTYPE_MONITOR:
|
||||||
|
if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
|
||||||
|
vif = &tx.sdata->vif;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tx.sdata = rcu_dereference(local->monitor_sdata);
|
||||||
|
if (tx.sdata) {
|
||||||
|
vif = &tx.sdata->vif;
|
||||||
|
info->hw_queue =
|
||||||
|
vif->hw_queue[skb_get_queue_mapping(skb)];
|
||||||
|
} else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
|
||||||
|
ieee80211_free_txskb(&local->hw, skb);
|
||||||
|
goto begin;
|
||||||
|
} else {
|
||||||
|
vif = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
tx.sdata = container_of(tx.sdata->bss,
|
||||||
|
struct ieee80211_sub_if_data, u.ap);
|
||||||
|
/* fall through */
|
||||||
|
default:
|
||||||
|
vif = &tx.sdata->vif;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEEE80211_SKB_CB(skb)->control.vif = vif;
|
||||||
out:
|
out:
|
||||||
spin_unlock_bh(&fq->lock);
|
spin_unlock_bh(&fq->lock);
|
||||||
|
|
||||||
|
|
|
@ -1436,7 +1436,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
|
||||||
WLAN_EID_SSID_LIST,
|
WLAN_EID_SSID_LIST,
|
||||||
WLAN_EID_CHANNEL_USAGE,
|
WLAN_EID_CHANNEL_USAGE,
|
||||||
WLAN_EID_INTERWORKING,
|
WLAN_EID_INTERWORKING,
|
||||||
/* mesh ID can't happen here */
|
WLAN_EID_MESH_ID,
|
||||||
/* 60 GHz can't happen here right now */
|
/* 60 GHz can't happen here right now */
|
||||||
};
|
};
|
||||||
noffset = ieee80211_ie_split(ie, ie_len,
|
noffset = ieee80211_ie_split(ie, ie_len,
|
||||||
|
|
|
@ -3791,8 +3791,8 @@ static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
|
||||||
static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
|
static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
|
||||||
{
|
{
|
||||||
const struct cfg80211_beacon_data *bcn = ¶ms->beacon;
|
const struct cfg80211_beacon_data *bcn = ¶ms->beacon;
|
||||||
size_t ies_len = bcn->beacon_ies_len;
|
size_t ies_len = bcn->tail_len;
|
||||||
const u8 *ies = bcn->beacon_ies;
|
const u8 *ies = bcn->tail;
|
||||||
const u8 *rates;
|
const u8 *rates;
|
||||||
const u8 *cap;
|
const u8 *cap;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
||||||
* Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
|
* Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
|
||||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||||
|
* Copyright 2017 Intel Deutschland GmbH
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -1483,7 +1484,9 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
|
||||||
{
|
{
|
||||||
struct ieee80211_supported_band *sband = wiphy->bands[channel->band];
|
struct ieee80211_supported_band *sband = wiphy->bands[channel->band];
|
||||||
struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
|
struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
|
||||||
|
const struct ieee80211_regdomain *regd;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
if (!is_ht40_allowed(channel)) {
|
if (!is_ht40_allowed(channel)) {
|
||||||
channel->flags |= IEEE80211_CHAN_NO_HT40;
|
channel->flags |= IEEE80211_CHAN_NO_HT40;
|
||||||
|
@ -1503,17 +1506,30 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
|
||||||
channel_after = c;
|
channel_after = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
regd = get_wiphy_regdom(wiphy);
|
||||||
|
if (regd) {
|
||||||
|
const struct ieee80211_reg_rule *reg_rule =
|
||||||
|
freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq),
|
||||||
|
regd, MHZ_TO_KHZ(20));
|
||||||
|
|
||||||
|
if (!IS_ERR(reg_rule))
|
||||||
|
flags = reg_rule->flags;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Please note that this assumes target bandwidth is 20 MHz,
|
* Please note that this assumes target bandwidth is 20 MHz,
|
||||||
* if that ever changes we also need to change the below logic
|
* if that ever changes we also need to change the below logic
|
||||||
* to include that as well.
|
* to include that as well.
|
||||||
*/
|
*/
|
||||||
if (!is_ht40_allowed(channel_before))
|
if (!is_ht40_allowed(channel_before) ||
|
||||||
|
flags & NL80211_RRF_NO_HT40MINUS)
|
||||||
channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
|
channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
|
||||||
else
|
else
|
||||||
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
|
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
|
||||||
|
|
||||||
if (!is_ht40_allowed(channel_after))
|
if (!is_ht40_allowed(channel_after) ||
|
||||||
|
flags & NL80211_RRF_NO_HT40PLUS)
|
||||||
channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
|
channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
|
||||||
else
|
else
|
||||||
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
|
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
|
||||||
|
|
Loading…
Reference in New Issue