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@xxxxxxxxxxxxx> --- 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(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1fa41b7a1be3..fbf01d156069 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -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); }; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 6d610bae30a9..a9f8fa814ecd 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -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, diff --git a/net/wireless/core.c b/net/wireless/core.c index 5bd01058b9e6..182f8f04166d 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -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); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 744b5851bbf9..5c04b6996e64 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -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; } } -- 2.11.0