mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
This time we have various things - all across the board:
* MU-MIMO sniffer support in mac80211 * a create_singlethread_workqueue() cleanup * interface dump filtering that was documented but not implemented * support for the new radiotap timestamp field * send delBA in two unexpected conditions (as required by the spec) * connect keys cleanups - allow only WEP with index 0-3 * per-station aggregation limit to work around broken APs * debugfs improvement for the integrated codel algorithm and various other small improvements and cleanups. -----BEGIN PGP SIGNATURE----- iQIcBAABCgAGBQJX2+umAAoJEGt7eEactAAdIMkP/jMmpbxkzD64L7nTkO4APGva r6RmMM1SmgVD/CtVkjlBLuvo5YOTWv/vWvy6KoUESOINAx/e6T3T7bmmCOXzbsOL e5/YYcS1AOqgn5SdhgIj1E5cpdYIhlUGRlNJ0qEjeLLrh4/TLUNbCcuPhOYybUMz fUrdPKgDeWb7x9EHLENhPsVtCXWwKnkDIS4qclPZCWgRj46XM4pNB4OlvCUzGY6k bOqGJfrtjYjgKFDmPFqfYA4JDA56980qqO41+eEKXeMvDKNs+pSiNco130Q+uU3E o7tk9DMnAnCy2GihpV1ZYVkLr6O+7o9xVuenj3NRlhyd1mn2gXxLcO4AkHcrZBkf Ei+2L+KgnWELyqiSOaGTJKlugsgS4DDoNnFEIVjSweQ9DIoBA/Gj/6+4uZeHXJ3M bEjtHnCLi5CuI067uBoevwXFoMi1poWra2KnZKOZzFS5OL3xHv4//x/Wmnn2/5Jz ffEwVyRmTY76sLWfnwXUDClrFWAYQrpNyTryc+k3cpYKzhnseiqt+z43cBuISm00 uh5B9PpPB8RhtUnXrL/SHRyf8YEluaidTsI2lc1LvwXOc0+Zbp73mTCgP+rzLs9p K2qVRiozpIXanW6hKmmaDwjKlcAKKLP0xN2v90MqwQt4YdLIKlXnll1AH2BawzuP OWB3n8D0I6y0PWH+Yo8o =s1MY -----END PGP SIGNATURE----- Merge tag 'mac80211-next-for-davem-2016-09-16' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== This time we have various things - all across the board: * MU-MIMO sniffer support in mac80211 * a create_singlethread_workqueue() cleanup * interface dump filtering that was documented but not implemented * support for the new radiotap timestamp field * send delBA in two unexpected conditions (as required by the spec) * connect keys cleanups - allow only WEP with index 0-3 * per-station aggregation limit to work around broken APs * debugfs improvement for the integrated codel algorithm and various other small improvements and cleanups. ==================== Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
commit
c13ed534b8
34 changed files with 484 additions and 277 deletions
|
|
@ -298,10 +298,13 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
|||
buf_size = IEEE80211_MAX_AMPDU_BUF;
|
||||
|
||||
/* make sure the size doesn't exceed the maximum supported by the hw */
|
||||
if (buf_size > local->hw.max_rx_aggregation_subframes)
|
||||
buf_size = local->hw.max_rx_aggregation_subframes;
|
||||
if (buf_size > sta->sta.max_rx_aggregation_subframes)
|
||||
buf_size = sta->sta.max_rx_aggregation_subframes;
|
||||
params.buf_size = buf_size;
|
||||
|
||||
ht_dbg(sta->sdata, "AddBA Req buf_size=%d for %pM\n",
|
||||
buf_size, sta->sta.addr);
|
||||
|
||||
/* examine state machine */
|
||||
mutex_lock(&sta->ampdu_mlme.mtx);
|
||||
|
||||
|
|
@ -406,8 +409,10 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
|||
}
|
||||
|
||||
end:
|
||||
if (status == WLAN_STATUS_SUCCESS)
|
||||
if (status == WLAN_STATUS_SUCCESS) {
|
||||
__set_bit(tid, sta->ampdu_mlme.agg_session_valid);
|
||||
__clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
|
||||
}
|
||||
mutex_unlock(&sta->ampdu_mlme.mtx);
|
||||
|
||||
end_no_lock:
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
|
|||
|
||||
if (type == NL80211_IFTYPE_MONITOR && flags) {
|
||||
sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
sdata->u.mntr_flags = *flags;
|
||||
sdata->u.mntr.flags = *flags;
|
||||
}
|
||||
|
||||
return wdev;
|
||||
|
|
@ -73,8 +73,29 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
|
|||
sdata->u.mgd.use_4addr = params->use_4addr;
|
||||
}
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_sub_if_data *monitor_sdata;
|
||||
u32 mu_mntr_cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
|
||||
|
||||
monitor_sdata = rtnl_dereference(local->monitor_sdata);
|
||||
if (monitor_sdata &&
|
||||
wiphy_ext_feature_isset(wiphy, mu_mntr_cap_flag)) {
|
||||
memcpy(monitor_sdata->vif.bss_conf.mu_group.membership,
|
||||
params->vht_mumimo_groups, WLAN_MEMBERSHIP_LEN);
|
||||
memcpy(monitor_sdata->vif.bss_conf.mu_group.position,
|
||||
params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN,
|
||||
WLAN_USER_POSITION_LEN);
|
||||
monitor_sdata->vif.mu_mimo_owner = true;
|
||||
ieee80211_bss_info_change_notify(monitor_sdata,
|
||||
BSS_CHANGED_MU_GROUPS);
|
||||
|
||||
ether_addr_copy(monitor_sdata->u.mntr.mu_follow_addr,
|
||||
params->macaddr);
|
||||
}
|
||||
|
||||
if (!flags)
|
||||
return 0;
|
||||
|
||||
if (ieee80211_sdata_running(sdata)) {
|
||||
u32 mask = MONITOR_FLAG_COOK_FRAMES |
|
||||
|
|
@ -89,11 +110,11 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
|
|||
* cooked_mntrs, monitor and all fif_* counters
|
||||
* reconfigure hardware
|
||||
*/
|
||||
if ((*flags & mask) != (sdata->u.mntr_flags & mask))
|
||||
if ((*flags & mask) != (sdata->u.mntr.flags & mask))
|
||||
return -EBUSY;
|
||||
|
||||
ieee80211_adjust_monitor_flags(sdata, -1);
|
||||
sdata->u.mntr_flags = *flags;
|
||||
sdata->u.mntr.flags = *flags;
|
||||
ieee80211_adjust_monitor_flags(sdata, 1);
|
||||
|
||||
ieee80211_configure_filter(local);
|
||||
|
|
@ -103,7 +124,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
|
|||
* and ieee80211_do_open take care of "everything"
|
||||
* mentioned in the comment above.
|
||||
*/
|
||||
sdata->u.mntr_flags = *flags;
|
||||
sdata->u.mntr.flags = *flags;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2940,10 +2961,6 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
|||
}
|
||||
|
||||
chanctx = container_of(conf, struct ieee80211_chanctx, conf);
|
||||
if (!chanctx) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ch_switch.timestamp = 0;
|
||||
ch_switch.device_timestamp = 0;
|
||||
|
|
|
|||
|
|
@ -71,138 +71,39 @@ DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
|
|||
DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
|
||||
local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
|
||||
|
||||
struct aqm_info {
|
||||
struct ieee80211_local *local;
|
||||
size_t size;
|
||||
size_t len;
|
||||
unsigned char buf[0];
|
||||
};
|
||||
|
||||
#define AQM_HDR_LEN 200
|
||||
#define AQM_HW_ENTRY_LEN 40
|
||||
#define AQM_TXQ_ENTRY_LEN 110
|
||||
|
||||
static int aqm_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct ieee80211_local *local = inode->i_private;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct sta_info *sta;
|
||||
struct txq_info *txqi;
|
||||
struct fq *fq = &local->fq;
|
||||
struct aqm_info *info = NULL;
|
||||
int len = 0;
|
||||
int i;
|
||||
|
||||
if (!local->ops->wake_tx_queue)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
len += AQM_HDR_LEN;
|
||||
len += 6 * AQM_HW_ENTRY_LEN;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list)
|
||||
len += AQM_TXQ_ENTRY_LEN;
|
||||
list_for_each_entry_rcu(sta, &local->sta_list, list)
|
||||
len += AQM_TXQ_ENTRY_LEN * ARRAY_SIZE(sta->sta.txq);
|
||||
rcu_read_unlock();
|
||||
|
||||
info = vmalloc(len);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&local->fq.lock);
|
||||
rcu_read_lock();
|
||||
|
||||
file->private_data = info;
|
||||
info->local = local;
|
||||
info->size = len;
|
||||
len = 0;
|
||||
|
||||
len += scnprintf(info->buf + len, info->size - len,
|
||||
"* hw\n"
|
||||
"access name value\n"
|
||||
"R fq_flows_cnt %u\n"
|
||||
"R fq_backlog %u\n"
|
||||
"R fq_overlimit %u\n"
|
||||
"R fq_collisions %u\n"
|
||||
"RW fq_limit %u\n"
|
||||
"RW fq_quantum %u\n",
|
||||
fq->flows_cnt,
|
||||
fq->backlog,
|
||||
fq->overlimit,
|
||||
fq->collisions,
|
||||
fq->limit,
|
||||
fq->quantum);
|
||||
|
||||
len += scnprintf(info->buf + len,
|
||||
info->size - len,
|
||||
"* vif\n"
|
||||
"ifname addr ac backlog-bytes backlog-packets flows overlimit collisions tx-bytes tx-packets\n");
|
||||
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
txqi = to_txq_info(sdata->vif.txq);
|
||||
len += scnprintf(info->buf + len, info->size - len,
|
||||
"%s %pM %u %u %u %u %u %u %u %u\n",
|
||||
sdata->name,
|
||||
sdata->vif.addr,
|
||||
txqi->txq.ac,
|
||||
txqi->tin.backlog_bytes,
|
||||
txqi->tin.backlog_packets,
|
||||
txqi->tin.flows,
|
||||
txqi->tin.overlimit,
|
||||
txqi->tin.collisions,
|
||||
txqi->tin.tx_bytes,
|
||||
txqi->tin.tx_packets);
|
||||
}
|
||||
|
||||
len += scnprintf(info->buf + len,
|
||||
info->size - len,
|
||||
"* sta\n"
|
||||
"ifname addr tid ac backlog-bytes backlog-packets flows overlimit collisions tx-bytes tx-packets\n");
|
||||
|
||||
list_for_each_entry_rcu(sta, &local->sta_list, list) {
|
||||
sdata = sta->sdata;
|
||||
for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
|
||||
txqi = to_txq_info(sta->sta.txq[i]);
|
||||
len += scnprintf(info->buf + len, info->size - len,
|
||||
"%s %pM %d %d %u %u %u %u %u %u %u\n",
|
||||
sdata->name,
|
||||
sta->sta.addr,
|
||||
txqi->txq.tid,
|
||||
txqi->txq.ac,
|
||||
txqi->tin.backlog_bytes,
|
||||
txqi->tin.backlog_packets,
|
||||
txqi->tin.flows,
|
||||
txqi->tin.overlimit,
|
||||
txqi->tin.collisions,
|
||||
txqi->tin.tx_bytes,
|
||||
txqi->tin.tx_packets);
|
||||
}
|
||||
}
|
||||
|
||||
info->len = len;
|
||||
|
||||
rcu_read_unlock();
|
||||
spin_unlock_bh(&local->fq.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aqm_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
vfree(file->private_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t aqm_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct aqm_info *info = file->private_data;
|
||||
struct ieee80211_local *local = file->private_data;
|
||||
struct fq *fq = &local->fq;
|
||||
char buf[200];
|
||||
int len = 0;
|
||||
|
||||
spin_lock_bh(&local->fq.lock);
|
||||
rcu_read_lock();
|
||||
|
||||
len = scnprintf(buf, sizeof(buf),
|
||||
"access name value\n"
|
||||
"R fq_flows_cnt %u\n"
|
||||
"R fq_backlog %u\n"
|
||||
"R fq_overlimit %u\n"
|
||||
"R fq_collisions %u\n"
|
||||
"RW fq_limit %u\n"
|
||||
"RW fq_quantum %u\n",
|
||||
fq->flows_cnt,
|
||||
fq->backlog,
|
||||
fq->overlimit,
|
||||
fq->collisions,
|
||||
fq->limit,
|
||||
fq->quantum);
|
||||
|
||||
rcu_read_unlock();
|
||||
spin_unlock_bh(&local->fq.lock);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos,
|
||||
info->buf, info->len);
|
||||
buf, len);
|
||||
}
|
||||
|
||||
static ssize_t aqm_write(struct file *file,
|
||||
|
|
@ -210,8 +111,7 @@ static ssize_t aqm_write(struct file *file,
|
|||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct aqm_info *info = file->private_data;
|
||||
struct ieee80211_local *local = info->local;
|
||||
struct ieee80211_local *local = file->private_data;
|
||||
char buf[100];
|
||||
size_t len;
|
||||
|
||||
|
|
@ -237,8 +137,7 @@ static ssize_t aqm_write(struct file *file,
|
|||
static const struct file_operations aqm_ops = {
|
||||
.write = aqm_write,
|
||||
.read = aqm_read,
|
||||
.open = aqm_open,
|
||||
.release = aqm_release,
|
||||
.open = simple_open,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
|
|
@ -302,6 +201,7 @@ static const char *hw_flag_names[] = {
|
|||
FLAG(USES_RSS),
|
||||
FLAG(TX_AMSDU),
|
||||
FLAG(TX_FRAG_LIST),
|
||||
FLAG(REPORTS_LOW_ACK),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
|
|
@ -428,7 +328,9 @@ void debugfs_hw_add(struct ieee80211_local *local)
|
|||
DEBUGFS_ADD(hwflags);
|
||||
DEBUGFS_ADD(user_power);
|
||||
DEBUGFS_ADD(power);
|
||||
DEBUGFS_ADD_MODE(aqm, 0600);
|
||||
|
||||
if (local->ops->wake_tx_queue)
|
||||
DEBUGFS_ADD_MODE(aqm, 0600);
|
||||
|
||||
statsd = debugfs_create_dir("statistics", phyd);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static ssize_t ieee80211_if_read(
|
|||
size_t count, loff_t *ppos,
|
||||
ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int))
|
||||
{
|
||||
char buf[70];
|
||||
char buf[200];
|
||||
ssize_t ret = -EINVAL;
|
||||
|
||||
read_lock(&dev_base_lock);
|
||||
|
|
@ -486,6 +486,38 @@ static ssize_t ieee80211_if_fmt_num_buffered_multicast(
|
|||
}
|
||||
IEEE80211_IF_FILE_R(num_buffered_multicast);
|
||||
|
||||
static ssize_t ieee80211_if_fmt_aqm(
|
||||
const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct txq_info *txqi = to_txq_info(sdata->vif.txq);
|
||||
int len;
|
||||
|
||||
spin_lock_bh(&local->fq.lock);
|
||||
rcu_read_lock();
|
||||
|
||||
len = scnprintf(buf,
|
||||
buflen,
|
||||
"ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets\n"
|
||||
"%u %u %u %u %u %u %u %u %u %u\n",
|
||||
txqi->txq.ac,
|
||||
txqi->tin.backlog_bytes,
|
||||
txqi->tin.backlog_packets,
|
||||
txqi->tin.flows,
|
||||
txqi->cstats.drop_count,
|
||||
txqi->cstats.ecn_mark,
|
||||
txqi->tin.overlimit,
|
||||
txqi->tin.collisions,
|
||||
txqi->tin.tx_bytes,
|
||||
txqi->tin.tx_packets);
|
||||
|
||||
rcu_read_unlock();
|
||||
spin_unlock_bh(&local->fq.lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
IEEE80211_IF_FILE_R(aqm);
|
||||
|
||||
/* IBSS attributes */
|
||||
static ssize_t ieee80211_if_fmt_tsf(
|
||||
const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
|
||||
|
|
@ -618,6 +650,9 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata)
|
|||
DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_2ghz);
|
||||
DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz);
|
||||
DEBUGFS_ADD(hw_queues);
|
||||
|
||||
if (sdata->local->ops->wake_tx_queue)
|
||||
DEBUGFS_ADD(aqm);
|
||||
}
|
||||
|
||||
static void add_sta_files(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
|
|||
|
|
@ -133,6 +133,55 @@ static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
|
|||
}
|
||||
STA_OPS(last_seq_ctrl);
|
||||
|
||||
#define AQM_TXQ_ENTRY_LEN 130
|
||||
|
||||
static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct sta_info *sta = file->private_data;
|
||||
struct ieee80211_local *local = sta->local;
|
||||
size_t bufsz = AQM_TXQ_ENTRY_LEN*(IEEE80211_NUM_TIDS+1);
|
||||
char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
|
||||
struct txq_info *txqi;
|
||||
ssize_t rv;
|
||||
int i;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&local->fq.lock);
|
||||
rcu_read_lock();
|
||||
|
||||
p += scnprintf(p,
|
||||
bufsz+buf-p,
|
||||
"tid ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets\n");
|
||||
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||
txqi = to_txq_info(sta->sta.txq[i]);
|
||||
p += scnprintf(p, bufsz+buf-p,
|
||||
"%d %d %u %u %u %u %u %u %u %u %u\n",
|
||||
txqi->txq.tid,
|
||||
txqi->txq.ac,
|
||||
txqi->tin.backlog_bytes,
|
||||
txqi->tin.backlog_packets,
|
||||
txqi->tin.flows,
|
||||
txqi->cstats.drop_count,
|
||||
txqi->cstats.ecn_mark,
|
||||
txqi->tin.overlimit,
|
||||
txqi->tin.collisions,
|
||||
txqi->tin.tx_bytes,
|
||||
txqi->tin.tx_packets);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
spin_unlock_bh(&local->fq.lock);
|
||||
|
||||
rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
|
||||
kfree(buf);
|
||||
return rv;
|
||||
}
|
||||
STA_OPS(aqm);
|
||||
|
||||
static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
|
@ -478,6 +527,9 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
|
|||
DEBUGFS_ADD_COUNTER(rx_fragments, rx_stats.fragments);
|
||||
DEBUGFS_ADD_COUNTER(tx_filtered, status_stats.filtered);
|
||||
|
||||
if (local->ops->wake_tx_queue)
|
||||
DEBUGFS_ADD(aqm);
|
||||
|
||||
if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
|
||||
debugfs_create_x32("driver_buffered_tids", 0400,
|
||||
sta->debugfs_dir,
|
||||
|
|
@ -492,10 +544,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
|
|||
|
||||
void ieee80211_sta_debugfs_remove(struct sta_info *sta)
|
||||
{
|
||||
struct ieee80211_local *local = sta->local;
|
||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||
|
||||
drv_sta_remove_debugfs(local, sdata, &sta->sta, sta->debugfs_dir);
|
||||
debugfs_remove_recursive(sta->debugfs_dir);
|
||||
sta->debugfs_dir = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ int drv_add_interface(struct ieee80211_local *local,
|
|||
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
||||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
|
||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
|
||||
!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))))
|
||||
return -EINVAL;
|
||||
|
||||
trace_drv_add_interface(local, sdata);
|
||||
|
|
|
|||
|
|
@ -162,7 +162,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
|
|||
return;
|
||||
|
||||
if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
|
||||
sdata->vif.type == NL80211_IFTYPE_MONITOR))
|
||||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!sdata->vif.mu_mimo_owner)))
|
||||
return;
|
||||
|
||||
if (!check_sdata_in_driver(sdata))
|
||||
|
|
@ -498,21 +499,6 @@ static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
|
|||
local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
|
||||
sta, dir);
|
||||
}
|
||||
|
||||
static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_sta *sta,
|
||||
struct dentry *dir)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
sdata = get_bss_sdata(sdata);
|
||||
check_sdata_in_driver(sdata);
|
||||
|
||||
if (local->ops->sta_remove_debugfs)
|
||||
local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
|
||||
sta, dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright 2005, Devicescape Software, Inc.
|
||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
|
@ -818,12 +818,18 @@ struct txq_info {
|
|||
struct fq_tin tin;
|
||||
struct fq_flow def_flow;
|
||||
struct codel_vars def_cvars;
|
||||
struct codel_stats cstats;
|
||||
unsigned long flags;
|
||||
|
||||
/* keep last! */
|
||||
struct ieee80211_txq txq;
|
||||
};
|
||||
|
||||
struct ieee80211_if_mntr {
|
||||
u32 flags;
|
||||
u8 mu_follow_addr[ETH_ALEN] __aligned(2);
|
||||
};
|
||||
|
||||
struct ieee80211_sub_if_data {
|
||||
struct list_head list;
|
||||
|
||||
|
|
@ -922,7 +928,7 @@ struct ieee80211_sub_if_data {
|
|||
struct ieee80211_if_ibss ibss;
|
||||
struct ieee80211_if_mesh mesh;
|
||||
struct ieee80211_if_ocb ocb;
|
||||
u32 mntr_flags;
|
||||
struct ieee80211_if_mntr mntr;
|
||||
} u;
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
|
|
@ -1112,7 +1118,6 @@ struct ieee80211_local {
|
|||
struct fq fq;
|
||||
struct codel_vars *cvars;
|
||||
struct codel_params cparams;
|
||||
struct codel_stats cstats;
|
||||
|
||||
const struct ieee80211_ops *ops;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
* by either the RTNL, the iflist_mtx or RCU.
|
||||
*/
|
||||
|
||||
static void ieee80211_iface_work(struct work_struct *work);
|
||||
|
||||
bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
|
|
@ -188,7 +190,7 @@ static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
|
|||
continue;
|
||||
|
||||
if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!(iter->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
!(iter->u.mntr.flags & MONITOR_FLAG_ACTIVE))
|
||||
continue;
|
||||
|
||||
m = iter->vif.addr;
|
||||
|
|
@ -217,7 +219,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
|
|||
return -EBUSY;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
|
||||
check_dup = false;
|
||||
|
||||
ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
|
||||
|
|
@ -357,7 +359,7 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
|
|||
const int offset)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
u32 flags = sdata->u.mntr_flags;
|
||||
u32 flags = sdata->u.mntr.flags;
|
||||
|
||||
#define ADJUST(_f, _s) do { \
|
||||
if (flags & MONITOR_FLAG_##_f) \
|
||||
|
|
@ -448,6 +450,9 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
|
|||
return ret;
|
||||
}
|
||||
|
||||
skb_queue_head_init(&sdata->skb_queue);
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -589,12 +594,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
|||
}
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
|
||||
if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
|
||||
local->cooked_mntrs++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
|
||||
if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
|
||||
res = drv_add_interface(local, sdata);
|
||||
if (res)
|
||||
goto err_stop;
|
||||
|
|
@ -926,7 +931,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
|||
/* no need to tell driver */
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
|
||||
if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
|
||||
local->cooked_mntrs--;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1012,7 +1017,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_recalc_idle(local);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
|
||||
break;
|
||||
|
||||
/* fall through */
|
||||
|
|
@ -1444,7 +1449,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
|
|||
case NL80211_IFTYPE_MONITOR:
|
||||
sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP;
|
||||
sdata->dev->netdev_ops = &ieee80211_monitorif_ops;
|
||||
sdata->u.mntr_flags = MONITOR_FLAG_CONTROL |
|
||||
sdata->u.mntr.flags = MONITOR_FLAG_CONTROL |
|
||||
MONITOR_FLAG_OTHER_BSS;
|
||||
break;
|
||||
case NL80211_IFTYPE_WDS:
|
||||
|
|
|
|||
|
|
@ -660,6 +660,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
|
|||
|
||||
ieee80211_roc_setup(local);
|
||||
|
||||
local->hw.radiotap_timestamp.units_pos = -1;
|
||||
local->hw.radiotap_timestamp.accuracy = -1;
|
||||
|
||||
return &local->hw;
|
||||
err_free:
|
||||
wiphy_free(wiphy);
|
||||
|
|
|
|||
|
|
@ -1672,11 +1672,15 @@ __ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata)
|
|||
non_acm_ac++)
|
||||
if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac)))
|
||||
break;
|
||||
/* The loop will result in using BK even if it requires
|
||||
* admission control, such configuration makes no sense
|
||||
* and we have to transmit somehow - the AC selection
|
||||
* does the same thing.
|
||||
/* Usually the loop will result in using BK even if it
|
||||
* requires admission control, but such a configuration
|
||||
* makes no sense and we have to transmit somehow - the
|
||||
* AC selection does the same thing.
|
||||
* If we started out trying to downgrade from BK, then
|
||||
* the extra condition here might be needed.
|
||||
*/
|
||||
if (non_acm_ac >= IEEE80211_NUM_ACS)
|
||||
non_acm_ac = IEEE80211_AC_BK;
|
||||
if (drv_conf_tx(local, sdata, ac,
|
||||
&sdata->tx_conf[non_acm_ac]))
|
||||
sdata_err(sdata,
|
||||
|
|
|
|||
|
|
@ -178,8 +178,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
|||
WARN_ON(!list_empty(&local->chanctx_list));
|
||||
|
||||
/* stop hardware - this must stop RX */
|
||||
if (local->open_count)
|
||||
ieee80211_stop_device(local);
|
||||
ieee80211_stop_device(local);
|
||||
|
||||
suspend:
|
||||
local->suspended = true;
|
||||
|
|
|
|||
|
|
@ -180,6 +180,11 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
|
|||
len += 12;
|
||||
}
|
||||
|
||||
if (local->hw.radiotap_timestamp.units_pos >= 0) {
|
||||
len = ALIGN(len, 8);
|
||||
len += 12;
|
||||
}
|
||||
|
||||
if (status->chains) {
|
||||
/* antenna and antenna signal fields */
|
||||
len += 2 * hweight8(status->chains);
|
||||
|
|
@ -447,6 +452,31 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|||
pos += 2;
|
||||
}
|
||||
|
||||
if (local->hw.radiotap_timestamp.units_pos >= 0) {
|
||||
u16 accuracy = 0;
|
||||
u8 flags = IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT;
|
||||
|
||||
rthdr->it_present |=
|
||||
cpu_to_le32(1 << IEEE80211_RADIOTAP_TIMESTAMP);
|
||||
|
||||
/* ensure 8 byte alignment */
|
||||
while ((pos - (u8 *)rthdr) & 7)
|
||||
pos++;
|
||||
|
||||
put_unaligned_le64(status->device_timestamp, pos);
|
||||
pos += sizeof(u64);
|
||||
|
||||
if (local->hw.radiotap_timestamp.accuracy >= 0) {
|
||||
accuracy = local->hw.radiotap_timestamp.accuracy;
|
||||
flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY;
|
||||
}
|
||||
put_unaligned_le16(accuracy, pos);
|
||||
pos += sizeof(u16);
|
||||
|
||||
*pos++ = local->hw.radiotap_timestamp.units_pos;
|
||||
*pos++ = flags;
|
||||
}
|
||||
|
||||
for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
|
||||
*pos++ = status->chain_signal[chain];
|
||||
*pos++ = chain;
|
||||
|
|
@ -485,6 +515,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
|||
struct net_device *prev_dev = NULL;
|
||||
int present_fcs_len = 0;
|
||||
unsigned int rtap_vendor_space = 0;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
struct ieee80211_sub_if_data *monitor_sdata =
|
||||
rcu_dereference(local->monitor_sdata);
|
||||
|
||||
if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) {
|
||||
struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data;
|
||||
|
|
@ -567,7 +600,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
|||
if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
|
||||
continue;
|
||||
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)
|
||||
if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
|
||||
continue;
|
||||
|
||||
if (!ieee80211_sdata_running(sdata))
|
||||
|
|
@ -585,6 +618,23 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
|||
ieee80211_rx_stats(sdata->dev, skb->len);
|
||||
}
|
||||
|
||||
mgmt = (void *)skb->data;
|
||||
if (monitor_sdata &&
|
||||
skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 + VHT_MUMIMO_GROUPS_DATA_LEN &&
|
||||
ieee80211_is_action(mgmt->frame_control) &&
|
||||
mgmt->u.action.category == WLAN_CATEGORY_VHT &&
|
||||
mgmt->u.action.u.vht_group_notif.action_code == WLAN_VHT_ACTION_GROUPID_MGMT &&
|
||||
is_valid_ether_addr(monitor_sdata->u.mntr.mu_follow_addr) &&
|
||||
ether_addr_equal(mgmt->da, monitor_sdata->u.mntr.mu_follow_addr)) {
|
||||
struct sk_buff *mu_skb = skb_copy(skb, GFP_ATOMIC);
|
||||
|
||||
if (mu_skb) {
|
||||
mu_skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
|
||||
skb_queue_tail(&monitor_sdata->skb_queue, mu_skb);
|
||||
ieee80211_queue_work(&local->hw, &monitor_sdata->work);
|
||||
}
|
||||
}
|
||||
|
||||
if (prev_dev) {
|
||||
skb->dev = prev_dev;
|
||||
netif_receive_skb(skb);
|
||||
|
|
@ -1072,8 +1122,15 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
|
|||
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
|
||||
|
||||
tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
|
||||
if (!tid_agg_rx)
|
||||
if (!tid_agg_rx) {
|
||||
if (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK &&
|
||||
!test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) &&
|
||||
!test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg))
|
||||
ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid,
|
||||
WLAN_BACK_RECIPIENT,
|
||||
WLAN_REASON_QSTA_REQUIRE_SETUP);
|
||||
goto dont_reorder;
|
||||
}
|
||||
|
||||
/* qos null data frames are excluded */
|
||||
if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
|
||||
|
|
@ -2535,6 +2592,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
|
|||
|
||||
tid = le16_to_cpu(bar_data.control) >> 12;
|
||||
|
||||
if (!test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) &&
|
||||
!test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg))
|
||||
ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid,
|
||||
WLAN_BACK_RECIPIENT,
|
||||
WLAN_REASON_QSTA_REQUIRE_SETUP);
|
||||
|
||||
tid_agg_rx = rcu_dereference(rx->sta->ampdu_mlme.tid_rx[tid]);
|
||||
if (!tid_agg_rx)
|
||||
return RX_DROP_MONITOR;
|
||||
|
|
@ -3147,7 +3210,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
|
|||
continue;
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_MONITOR ||
|
||||
!(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
|
||||
!(sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES))
|
||||
continue;
|
||||
|
||||
if (prev_dev) {
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw,
|
|||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
||||
trace_api_scan_completed(local, info);
|
||||
trace_api_scan_completed(local, info->aborted);
|
||||
|
||||
set_bit(SCAN_COMPLETED, &local->scanning);
|
||||
if (info->aborted)
|
||||
|
|
|
|||
|
|
@ -340,6 +340,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
memcpy(sta->addr, addr, ETH_ALEN);
|
||||
memcpy(sta->sta.addr, addr, ETH_ALEN);
|
||||
sta->sta.max_rx_aggregation_subframes =
|
||||
local->hw.max_rx_aggregation_subframes;
|
||||
|
||||
sta->local = local;
|
||||
sta->sdata = sdata;
|
||||
sta->rx_stats.last_rx = jiffies;
|
||||
|
|
@ -687,7 +690,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
|
|||
}
|
||||
|
||||
/* No need to do anything if the driver does all */
|
||||
if (ieee80211_hw_check(&local->hw, AP_LINK_PS))
|
||||
if (!local->ops->set_tim)
|
||||
return;
|
||||
|
||||
if (sta->dead)
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ struct tid_ampdu_rx {
|
|||
* @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the
|
||||
* driver requested to close until the work for it runs
|
||||
* @agg_session_valid: bitmap indicating which TID has a rx BA session open on
|
||||
* @unexpected_agg: bitmap indicating which TID already sent a delBA due to
|
||||
* unexpected aggregation related frames outside a session
|
||||
* @work: work struct for starting/stopping aggregation
|
||||
* @tid_tx: aggregation info for Tx per TID
|
||||
* @tid_start_tx: sessions where start was requested
|
||||
|
|
@ -244,6 +246,7 @@ struct sta_ampdu_mlme {
|
|||
unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
|
||||
unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
|
||||
unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
|
||||
unsigned long unexpected_agg[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
|
||||
/* tx */
|
||||
struct work_struct work;
|
||||
struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS];
|
||||
|
|
|
|||
|
|
@ -557,6 +557,12 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
|
|||
static void ieee80211_lost_packet(struct sta_info *sta,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
/* If driver relies on its own algorithm for station kickout, skip
|
||||
* mac80211 packet loss mechanism.
|
||||
*/
|
||||
if (ieee80211_hw_check(&sta->local->hw, REPORTS_LOW_ACK))
|
||||
return;
|
||||
|
||||
/* This packet was aggregated but doesn't carry status info */
|
||||
if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
|
||||
!(info->flags & IEEE80211_TX_STAT_AMPDU))
|
||||
|
|
@ -709,7 +715,7 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
|
|||
if (!ieee80211_sdata_running(sdata))
|
||||
continue;
|
||||
|
||||
if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
|
||||
if ((sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) &&
|
||||
!send_to_cooked)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -1343,7 +1343,7 @@ static struct sk_buff *fq_tin_dequeue_func(struct fq *fq,
|
|||
local = container_of(fq, struct ieee80211_local, fq);
|
||||
txqi = container_of(tin, struct txq_info, tin);
|
||||
cparams = &local->cparams;
|
||||
cstats = &local->cstats;
|
||||
cstats = &txqi->cstats;
|
||||
|
||||
if (flow == &txqi->def_flow)
|
||||
cvars = &txqi->def_cvars;
|
||||
|
|
@ -1403,6 +1403,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
|
|||
fq_tin_init(&txqi->tin);
|
||||
fq_flow_init(&txqi->def_flow);
|
||||
codel_vars_init(&txqi->def_cvars);
|
||||
codel_stats_init(&txqi->cstats);
|
||||
|
||||
txqi->txq.vif = &sdata->vif;
|
||||
|
||||
|
|
@ -1441,7 +1442,6 @@ int ieee80211_txq_setup_flows(struct ieee80211_local *local)
|
|||
return ret;
|
||||
|
||||
codel_params_init(&local->cparams);
|
||||
codel_stats_init(&local->cstats);
|
||||
local->cparams.interval = MS2TIME(100);
|
||||
local->cparams.target = MS2TIME(20);
|
||||
local->cparams.ecn = true;
|
||||
|
|
@ -1643,7 +1643,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
|
|||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
|
||||
if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
|
||||
vif = &sdata->vif;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2263,15 +2263,9 @@ static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
|
|||
case NL80211_IFTYPE_STATION:
|
||||
if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
|
||||
sta = sta_info_get(sdata, skb->data);
|
||||
if (sta) {
|
||||
bool tdls_peer, tdls_auth;
|
||||
|
||||
tdls_peer = test_sta_flag(sta,
|
||||
WLAN_STA_TDLS_PEER);
|
||||
tdls_auth = test_sta_flag(sta,
|
||||
WLAN_STA_TDLS_PEER_AUTH);
|
||||
|
||||
if (tdls_peer && tdls_auth) {
|
||||
if (sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
|
||||
if (test_sta_flag(sta,
|
||||
WLAN_STA_TDLS_PEER_AUTH)) {
|
||||
*sta_out = sta;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2283,8 +2277,7 @@ static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
|
|||
* after a TDLS sta is removed due to being
|
||||
* unreachable.
|
||||
*/
|
||||
if (tdls_peer && !tdls_auth &&
|
||||
!ieee80211_is_tdls_setup(skb))
|
||||
if (!ieee80211_is_tdls_setup(skb))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -598,7 +598,7 @@ static void __iterate_interfaces(struct ieee80211_local *local,
|
|||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
|
||||
continue;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
|
|
@ -2555,7 +2555,6 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
if (need_basic && basic_rates & BIT(i))
|
||||
basic = 0x80;
|
||||
rate = sband->bitrates[i].bitrate;
|
||||
rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
|
||||
5 * (1 << shift));
|
||||
*pos++ = basic | (u8) rate;
|
||||
|
|
|
|||
Loading…
Reference in a new issue