@@ -2368,6 +2368,8 @@ enum cfg80211_connect_params_changed {
* @WIPHY_PARAM_TXQ_LIMIT: TXQ packet limit has been changed
* @WIPHY_PARAM_TXQ_MEMORY_LIMIT: TXQ memory limit has been changed
* @WIPHY_PARAM_TXQ_QUANTUM: TXQ scheduler quantum
+ * @WIPHY_PARAM_AMPDU_ENABLED: wiphy->ampdu_enabled has changed
+ * @WIPHY_PARAM_AMSDU_ENABLED: wiphy->amsdu_enabled has changed
*/
enum wiphy_params_flags {
WIPHY_PARAM_RETRY_SHORT = 1 << 0,
@@ -2379,6 +2381,8 @@ enum wiphy_params_flags {
WIPHY_PARAM_TXQ_LIMIT = 1 << 6,
WIPHY_PARAM_TXQ_MEMORY_LIMIT = 1 << 7,
WIPHY_PARAM_TXQ_QUANTUM = 1 << 8,
+ WIPHY_PARAM_AMPDU_ENABLED = 1 << 9,
+ WIPHY_PARAM_AMSDU_ENABLED = 1 << 10,
};
/**
@@ -4163,6 +4167,9 @@ struct wiphy {
u32 txq_memory_limit;
u32 txq_quantum;
+ u8 ampdu_enabled;
+ u8 amsdu_enabled;
+
char priv[0] __aligned(NETDEV_ALIGN);
};
@@ -2254,6 +2254,9 @@ enum nl80211_commands {
* @NL80211_ATTR_FTM_RESPONDER_STATS: Nested attribute with FTM responder
* statistics, see &enum nl80211_ftm_responder_stats.
*
+ * @NL80211_ATTR_WIPHY_AMPDU_ENABLED: enable/disable AMPDU aggregation.
+ * @NL80211_ATTR_WIPHY_AMSDU_ENABLED: enable/disable AMSDU aggregation.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2699,6 +2702,9 @@ enum nl80211_attrs {
NL80211_ATTR_FTM_RESPONDER_STATS,
+ NL80211_ATTR_WIPHY_AMPDU_ENABLED,
+ NL80211_ATTR_WIPHY_AMSDU_ENABLED,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -524,6 +524,9 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
rdev->wiphy.max_sched_scan_plans = 1;
rdev->wiphy.max_sched_scan_plan_interval = U32_MAX;
+ rdev->wiphy.ampdu_enabled = 1;
+ rdev->wiphy.amsdu_enabled = 1;
+
return &rdev->wiphy;
}
EXPORT_SYMBOL(wiphy_new_nm);
@@ -497,6 +497,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
.type = NLA_NESTED,
.validation_data = nl80211_ftm_responder_policy,
},
+
+ [NL80211_ATTR_WIPHY_AMPDU_ENABLED] = { .type = NLA_U8 },
+ [NL80211_ATTR_WIPHY_AMSDU_ENABLED] = { .type = NLA_U8 },
};
/* policy for the key attributes */
@@ -2118,6 +2121,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
goto nla_put_failure;
}
+ if (nla_put_u8(msg, NL80211_ATTR_WIPHY_AMPDU_ENABLED,
+ rdev->wiphy.ampdu_enabled))
+ goto nla_put_failure;
+
+ if (nla_put_u8(msg, NL80211_ATTR_WIPHY_AMSDU_ENABLED,
+ rdev->wiphy.amsdu_enabled))
+ goto nla_put_failure;
+
/* done */
state->split_start = 0;
break;
@@ -2514,6 +2525,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
u32 frag_threshold = 0, rts_threshold = 0;
u8 coverage_class = 0;
u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
+ u8 amsdu = 0, ampdu = 0;
ASSERT_RTNL();
@@ -2743,11 +2755,22 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
changed |= WIPHY_PARAM_TXQ_QUANTUM;
}
+ if (info->attrs[NL80211_ATTR_WIPHY_AMPDU_ENABLED]) {
+ ampdu = nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_AMPDU_ENABLED]);
+ changed |= WIPHY_PARAM_AMPDU_ENABLED;
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_AMSDU_ENABLED]) {
+ amsdu = nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_AMSDU_ENABLED]);
+ changed |= WIPHY_PARAM_AMSDU_ENABLED;
+ }
+
if (changed) {
u8 old_retry_short, old_retry_long;
u32 old_frag_threshold, old_rts_threshold;
u8 old_coverage_class;
u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
+ u8 old_amsdu, old_ampdu;
if (!rdev->ops->set_wiphy_params)
return -EOPNOTSUPP;
@@ -2760,6 +2783,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
old_txq_limit = rdev->wiphy.txq_limit;
old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
old_txq_quantum = rdev->wiphy.txq_quantum;
+ old_ampdu = rdev->wiphy.ampdu_enabled;
+ old_amsdu = rdev->wiphy.amsdu_enabled;
if (changed & WIPHY_PARAM_RETRY_SHORT)
rdev->wiphy.retry_short = retry_short;
@@ -2777,6 +2802,10 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
rdev->wiphy.txq_memory_limit = txq_memory_limit;
if (changed & WIPHY_PARAM_TXQ_QUANTUM)
rdev->wiphy.txq_quantum = txq_quantum;
+ if (changed & WIPHY_PARAM_AMPDU_ENABLED)
+ rdev->wiphy.ampdu_enabled = ampdu;
+ if (changed & WIPHY_PARAM_AMSDU_ENABLED)
+ rdev->wiphy.amsdu_enabled = amsdu;
result = rdev_set_wiphy_params(rdev, changed);
if (result) {
@@ -2788,6 +2817,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
rdev->wiphy.txq_limit = old_txq_limit;
rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
rdev->wiphy.txq_quantum = old_txq_quantum;
+ rdev->wiphy.ampdu_enabled = old_ampdu;
+ rdev->wiphy.amsdu_enabled = old_amsdu;
return result;
}
}
Add two top-level switches to wiphy structure to control AMSDU and AMPDU aggregation. Enable read/update of AMSDU and AMPDU aggregation from the userspace using set_wiphy/get_wiphy commands. Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> --- include/net/cfg80211.h | 7 +++++++ include/uapi/linux/nl80211.h | 6 ++++++ net/wireless/core.c | 3 +++ net/wireless/nl80211.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+)