Last set of updates:
* more minstrel work from Felix to reduce the probing overhead * QoS for nl80211 control port frames * STBC injection support * and a couple of small fixes -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAmAmiEwACgkQB8qZga/f l8TVAxAAgqJ2zeDPYchCVNGUqrsPqFG6h3rBB2oKHUCrgBy150uSWmAyhvG4eiwP S4gLA/k42hHjxsmoScFGdjyaVMHv6CqcLkrPDfYsKvjZp258kw7Jbprv94KbeFkR 6ckpO3dVsyCFrUe3VqTgEtqNatixX3jqlZ6JemiU2hHI5prUPa4Fkt9m9fvwIaDO FoLywLdDjNHrOqo8qWjWDRfktGAuuFSFi1g+y5vNjlGPs6vck8ORP1/Bi9rXVxXD TrawcgID9/Ngvblckkg0yW2oqdPl/QuMPhnJRCwOQJbVqTmxcLjuDybRKfGTcw+D zd8FBCtH2lhW2MAbo3hh5977cj6DsCeRYcNb+wDePtv7uSAgoYP9G7CJyyXL061Y AOXizfDqejQuhQEWhi4oirgtwMHosESPxgW5pSmZPnjbgxBxHZJWRXN5/52PBKRH yiPQuhaSjSh5HAs8va3U8gSIqER5mIXqGoIlOTkwcaoSf/wgxoYPxeJgk4KQuRhx 6Ssky2dx7/HlYUN/tNhUbR9GkZJk5V453VTAt0LHPVYtWrry/rpUNTYUL131fPcG gs6nv/FDaWC9l/EtFE2wFpknqh+jbzt9+Vh51h1Sf3fORP3oqF6/tDAj2pgOSSUV YzmukXRJJLHowr9Xtr227yoWR0GA8A9vKlZqmE7f08fPjXdUzoE= =PXD5 -----END PGP SIGNATURE----- Merge tag 'mac80211-next-for-net-next-2021-02-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== Last set of updates: * more minstrel work from Felix to reduce the probing overhead * QoS for nl80211 control port frames * STBC injection support * and a couple of small fixes ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
21cc70c75b
|
@ -2583,12 +2583,14 @@ struct cfg80211_auth_request {
|
|||
* authentication capability. Drivers can offload authentication to
|
||||
* userspace if this flag is set. Only applicable for cfg80211_connect()
|
||||
* request (connect callback).
|
||||
* @ASSOC_REQ_DISABLE_HE: Disable HE
|
||||
*/
|
||||
enum cfg80211_assoc_req_flags {
|
||||
ASSOC_REQ_DISABLE_HT = BIT(0),
|
||||
ASSOC_REQ_DISABLE_VHT = BIT(1),
|
||||
ASSOC_REQ_USE_RRM = BIT(2),
|
||||
CONNECT_REQ_EXTERNAL_AUTH_SUPPORT = BIT(3),
|
||||
ASSOC_REQ_DISABLE_HE = BIT(4),
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1963,8 +1963,15 @@ enum nl80211_commands {
|
|||
* @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire
|
||||
* probe-response frame. The DA field in the 802.11 header is zero-ed out,
|
||||
* to be filled by the FW.
|
||||
* @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
|
||||
* this feature. Currently, only supported in mac80211 drivers.
|
||||
* @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
|
||||
* this feature during association. This is a flag attribute.
|
||||
* Currently only supported in mac80211 drivers.
|
||||
* @NL80211_ATTR_DISABLE_VHT: Force VHT capable interfaces to disable
|
||||
* this feature during association. This is a flag attribute.
|
||||
* Currently only supported in mac80211 drivers.
|
||||
* @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable
|
||||
* this feature during association. This is a flag attribute.
|
||||
* Currently only supported in mac80211 drivers.
|
||||
* @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
|
||||
* ATTR_HT_CAPABILITY to which attention should be paid.
|
||||
* Currently, only mac80211 NICs support this feature.
|
||||
|
@ -3045,6 +3052,8 @@ enum nl80211_attrs {
|
|||
|
||||
NL80211_ATTR_SAR_SPEC,
|
||||
|
||||
NL80211_ATTR_DISABLE_HE,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
|
|
|
@ -356,7 +356,7 @@ u32 airtime_link_metric_get(struct ieee80211_local *local,
|
|||
*/
|
||||
tx_time = (device_constant + 10 * test_frame_len / rate);
|
||||
estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
|
||||
result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT);
|
||||
result = ((u64)tx_time * estimated_retx) >> (2 * ARITH_SHIFT);
|
||||
return (u32)result;
|
||||
}
|
||||
|
||||
|
|
|
@ -5754,6 +5754,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
if (req->flags & ASSOC_REQ_DISABLE_VHT)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
|
||||
if (req->flags & ASSOC_REQ_DISABLE_HE)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
|
||||
err = ieee80211_prep_connection(sdata, req->bss, true, override);
|
||||
if (err)
|
||||
goto err_clear;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -6,6 +6,8 @@
|
|||
#ifndef __RC_MINSTREL_HT_H
|
||||
#define __RC_MINSTREL_HT_H
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
/* number of highest throughput rates to consider*/
|
||||
#define MAX_THR_RATES 4
|
||||
#define SAMPLE_COLUMNS 10 /* number of columns in sample table */
|
||||
|
@ -57,10 +59,22 @@
|
|||
|
||||
#define MCS_GROUP_RATES 10
|
||||
|
||||
#define MI_RATE_IDX_MASK GENMASK(3, 0)
|
||||
#define MI_RATE_GROUP_MASK GENMASK(15, 4)
|
||||
|
||||
#define MI_RATE(_group, _idx) \
|
||||
(FIELD_PREP(MI_RATE_GROUP_MASK, _group) | \
|
||||
FIELD_PREP(MI_RATE_IDX_MASK, _idx))
|
||||
|
||||
#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate)
|
||||
#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate)
|
||||
|
||||
#define MINSTREL_SAMPLE_RATES 5 /* rates per sample type */
|
||||
#define MINSTREL_SAMPLE_INTERVAL (HZ / 50)
|
||||
|
||||
struct minstrel_priv {
|
||||
struct ieee80211_hw *hw;
|
||||
bool has_mrr;
|
||||
u32 sample_switch;
|
||||
unsigned int cw_min;
|
||||
unsigned int cw_max;
|
||||
unsigned int max_retry;
|
||||
|
@ -110,10 +124,16 @@ struct minstrel_rate_stats {
|
|||
u8 retry_count;
|
||||
u8 retry_count_rtscts;
|
||||
|
||||
u8 sample_skipped;
|
||||
bool retry_updated;
|
||||
};
|
||||
|
||||
enum minstrel_sample_type {
|
||||
MINSTREL_SAMPLE_TYPE_INC,
|
||||
MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
MINSTREL_SAMPLE_TYPE_SLOW,
|
||||
__MINSTREL_SAMPLE_TYPE_MAX
|
||||
};
|
||||
|
||||
struct minstrel_mcs_group_data {
|
||||
u8 index;
|
||||
u8 column;
|
||||
|
@ -126,10 +146,10 @@ struct minstrel_mcs_group_data {
|
|||
struct minstrel_rate_stats rates[MCS_GROUP_RATES];
|
||||
};
|
||||
|
||||
enum minstrel_sample_mode {
|
||||
MINSTREL_SAMPLE_IDLE,
|
||||
MINSTREL_SAMPLE_ACTIVE,
|
||||
MINSTREL_SAMPLE_PENDING,
|
||||
struct minstrel_sample_category {
|
||||
u8 sample_group;
|
||||
u16 sample_rates[MINSTREL_SAMPLE_RATES];
|
||||
u16 cur_sample_rates[MINSTREL_SAMPLE_RATES];
|
||||
};
|
||||
|
||||
struct minstrel_ht_sta {
|
||||
|
@ -155,26 +175,19 @@ struct minstrel_ht_sta {
|
|||
unsigned int overhead_legacy;
|
||||
unsigned int overhead_legacy_rtscts;
|
||||
|
||||
unsigned int total_packets_last;
|
||||
unsigned int total_packets_cur;
|
||||
unsigned int total_packets;
|
||||
unsigned int sample_packets;
|
||||
|
||||
/* tx flags to add for frames for this sta */
|
||||
u32 tx_flags;
|
||||
|
||||
u8 sample_wait;
|
||||
u8 sample_tries;
|
||||
u8 sample_count;
|
||||
u8 sample_slow;
|
||||
u8 band;
|
||||
|
||||
enum minstrel_sample_mode sample_mode;
|
||||
u8 sample_seq;
|
||||
u16 sample_rate;
|
||||
|
||||
/* current MCS group to be sampled */
|
||||
u8 sample_group;
|
||||
|
||||
u8 band;
|
||||
unsigned long sample_time;
|
||||
struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
|
||||
|
||||
/* Bitfield of supported MCS rates of all groups */
|
||||
u16 supported[MINSTREL_GROUPS_NB];
|
||||
|
|
|
@ -32,6 +32,18 @@ minstrel_stats_release(struct inode *inode, struct file *file)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
minstrel_ht_is_sample_rate(struct minstrel_ht_sta *mi, int idx)
|
||||
{
|
||||
int type, i;
|
||||
|
||||
for (type = 0; type < ARRAY_SIZE(mi->sample); type++)
|
||||
for (i = 0; i < MINSTREL_SAMPLE_RATES; i++)
|
||||
if (mi->sample[type].cur_sample_rates[i] == idx)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static char *
|
||||
minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
||||
{
|
||||
|
@ -56,7 +68,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
|||
|
||||
for (j = 0; j < MCS_GROUP_RATES; j++) {
|
||||
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
||||
int idx = i * MCS_GROUP_RATES + j;
|
||||
int idx = MI_RATE(i, j);
|
||||
unsigned int duration;
|
||||
|
||||
if (!(mi->supported[i] & BIT(j)))
|
||||
|
@ -84,6 +96,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
|||
*(p++) = (idx == mi->max_tp_rate[2]) ? 'C' : ' ';
|
||||
*(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' ';
|
||||
*(p++) = (idx == mi->max_prob_rate) ? 'P' : ' ';
|
||||
*(p++) = minstrel_ht_is_sample_rate(mi, idx) ? 'S' : ' ';
|
||||
|
||||
if (gflags & IEEE80211_TX_RC_MCS) {
|
||||
p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j);
|
||||
|
@ -145,9 +158,9 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
|
|||
|
||||
p += sprintf(p, "\n");
|
||||
p += sprintf(p,
|
||||
" best ____________rate__________ ____statistics___ _____last____ ______sum-of________\n");
|
||||
" best ____________rate__________ ____statistics___ _____last____ ______sum-of________\n");
|
||||
p += sprintf(p,
|
||||
"mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n");
|
||||
"mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n");
|
||||
|
||||
p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
|
||||
for (i = 0; i < MINSTREL_CCK_GROUP; i++)
|
||||
|
@ -201,7 +214,7 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
|||
|
||||
for (j = 0; j < MCS_GROUP_RATES; j++) {
|
||||
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
||||
int idx = i * MCS_GROUP_RATES + j;
|
||||
int idx = MI_RATE(i, j);
|
||||
unsigned int duration;
|
||||
|
||||
if (!(mi->supported[i] & BIT(j)))
|
||||
|
@ -228,6 +241,7 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
|||
p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[2]) ? "C" : ""));
|
||||
p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[3]) ? "D" : ""));
|
||||
p += sprintf(p, "%s" ,((idx == mi->max_prob_rate) ? "P" : ""));
|
||||
p += sprintf(p, "%s", (minstrel_ht_is_sample_rate(mi, idx) ? "S" : ""));
|
||||
|
||||
if (gflags & IEEE80211_TX_RC_MCS) {
|
||||
p += sprintf(p, ",MCS%-2u,", (mg->streams - 1) * 8 + j);
|
||||
|
|
|
@ -628,16 +628,12 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,
|
|||
u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
__be16 ethertype = 0;
|
||||
|
||||
if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3))
|
||||
skb_copy_bits(skb, 2 * ETH_ALEN, ðertype, ETH_TLEN);
|
||||
|
||||
rcu_read_lock();
|
||||
sdata = ieee80211_sdata_from_skb(local, skb);
|
||||
if (sdata) {
|
||||
if (ethertype == sdata->control_port_protocol ||
|
||||
ethertype == cpu_to_be16(ETH_P_PREAUTH))
|
||||
if (skb->protocol == sdata->control_port_protocol ||
|
||||
skb->protocol == cpu_to_be16(ETH_P_PREAUTH))
|
||||
cfg80211_control_port_tx_status(&sdata->wdev,
|
||||
cookie,
|
||||
skb->data,
|
||||
|
|
|
@ -1182,9 +1182,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
|
|||
tx->sta = rcu_dereference(sdata->u.vlan.sta);
|
||||
if (!tx->sta && sdata->wdev.use_4addr)
|
||||
return TX_DROP;
|
||||
} else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||
IEEE80211_TX_CTL_INJECTED) ||
|
||||
tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||
} else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
||||
}
|
||||
if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
|
||||
|
@ -2124,6 +2122,15 @@ bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
|
|||
if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FEC &&
|
||||
mcs_flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC)
|
||||
info->flags |= IEEE80211_TX_CTL_LDPC;
|
||||
|
||||
if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_STBC) {
|
||||
u8 stbc = u8_get_bits(mcs_flags,
|
||||
IEEE80211_RADIOTAP_MCS_STBC_MASK);
|
||||
|
||||
info->flags |=
|
||||
u32_encode_bits(stbc,
|
||||
IEEE80211_TX_CTL_STBC);
|
||||
}
|
||||
break;
|
||||
|
||||
case IEEE80211_RADIOTAP_VHT:
|
||||
|
@ -5404,6 +5411,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
|||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct sta_info *sta;
|
||||
struct sk_buff *skb;
|
||||
struct ethhdr *ehdr;
|
||||
u32 ctrl_flags = 0;
|
||||
|
@ -5426,8 +5434,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
|||
if (cookie)
|
||||
ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
|
||||
flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||
IEEE80211_TX_CTL_INJECTED;
|
||||
flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX;
|
||||
|
||||
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||
sizeof(struct ethhdr) + len);
|
||||
|
@ -5444,10 +5451,25 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
|||
ehdr->h_proto = proto;
|
||||
|
||||
skb->dev = dev;
|
||||
skb->protocol = htons(ETH_P_802_3);
|
||||
skb->protocol = proto;
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
/* update QoS header to prioritize control port frames if possible,
|
||||
* priorization also happens for control port frames send over
|
||||
* AF_PACKET
|
||||
*/
|
||||
rcu_read_lock();
|
||||
|
||||
if (ieee80211_lookup_ra_sta(sdata, skb, &sta) == 0 && !IS_ERR(sta)) {
|
||||
u16 queue = __ieee80211_select_queue(sdata, sta, skb);
|
||||
|
||||
skb_set_queue_mapping(skb, queue);
|
||||
skb_get_hash(skb);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
/* mutex lock is only needed for incrementing the cookie counter */
|
||||
mutex_lock(&local->mtx);
|
||||
|
||||
|
|
|
@ -752,6 +752,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
NL80211_SAE_PWE_BOTH),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
[NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
|
||||
[NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
|
@ -10019,6 +10020,9 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
|
|||
if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
|
||||
req.flags |= ASSOC_REQ_DISABLE_VHT;
|
||||
|
||||
if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HE]))
|
||||
req.flags |= ASSOC_REQ_DISABLE_HE;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
|
||||
memcpy(&req.vht_capa_mask,
|
||||
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
|
||||
|
@ -10802,6 +10806,9 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
|
|||
if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
|
||||
connect.flags |= ASSOC_REQ_DISABLE_VHT;
|
||||
|
||||
if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HE]))
|
||||
connect.flags |= ASSOC_REQ_DISABLE_HE;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
|
||||
memcpy(&connect.vht_capa_mask,
|
||||
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
|
||||
|
|
|
@ -1629,7 +1629,7 @@ __freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 min_bw)
|
|||
{
|
||||
const struct ieee80211_regdomain *regd = reg_get_regdomain(wiphy);
|
||||
static const u32 bws[] = {0, 1, 2, 4, 5, 8, 10, 16, 20};
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
const struct ieee80211_reg_rule *reg_rule = ERR_PTR(-ERANGE);
|
||||
int i = ARRAY_SIZE(bws) - 1;
|
||||
u32 bw;
|
||||
|
||||
|
|
|
@ -82,12 +82,6 @@ static void wiphy_dev_release(struct device *dev)
|
|||
cfg80211_dev_free(rdev);
|
||||
}
|
||||
|
||||
static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
/* TODO, we probably need stuff here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
|
@ -162,7 +156,6 @@ struct class ieee80211_class = {
|
|||
.owner = THIS_MODULE,
|
||||
.dev_release = wiphy_dev_release,
|
||||
.dev_groups = ieee80211_groups,
|
||||
.dev_uevent = wiphy_uevent,
|
||||
.pm = WIPHY_PM_OPS,
|
||||
.ns_type = &net_ns_type_operations,
|
||||
.namespace = wiphy_namespace,
|
||||
|
|
Загрузка…
Ссылка в новой задаче