[RFC/RFT] driver_nl80211: automatically use concurrent P2P if possible
Johannes Berg
johannes
Wed Sep 7 12:50:43 PDT 2011
From: Johannes Berg <johannes.berg at intel.com>
Since the kernel can now advertise P2P concurrent
support by advertising interface combinations, we
can take advantage of that and automatically use
P2P_CONCURRENT / P2P_MGMT_AND_NON_P2P for drivers
that advertise support.
Keep driver_param=use_p2p_group_interface=1 for
anyone not advertising interface combinations in
their drivers yet.
Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
src/drivers/driver_nl80211.c | 75 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
--- a/src/drivers/driver_nl80211.c 2011-09-06 08:10:45.000000000 +0200
+++ b/src/drivers/driver_nl80211.c 2011-09-07 21:48:13.000000000 +0200
@@ -1636,6 +1636,7 @@ struct wiphy_info_data {
int max_scan_ssids;
int ap_supported;
int p2p_supported;
+ int p2p_concurrent;
int auth_supported;
int connect_supported;
int offchan_tx_supported;
@@ -1649,6 +1650,17 @@ static int wiphy_info_handler(struct nl_
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct wiphy_info_data *info = arg;
int p2p_go_supported = 0, p2p_client_supported = 0;
+ static struct nla_policy
+ iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
+ [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
+ [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
+ [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
+ [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
+ },
+ iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
+ [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
+ [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
+ };
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
@@ -1676,6 +1688,63 @@ static int wiphy_info_handler(struct nl_
}
}
+ if (tb[NL80211_ATTR_INTERFACE_COMBINATIONS]) {
+ struct nlattr *nl_combi;
+ int rem_combi;
+
+ nla_for_each_nested(nl_combi,
+ tb[NL80211_ATTR_INTERFACE_COMBINATIONS],
+ rem_combi) {
+ struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
+ struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
+ struct nlattr *nl_limit, *nl_mode;
+ int err, rem_limit, rem_mode;
+ int combination_has_p2p = 0, combination_has_mgd = 0;
+
+ err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
+ nl_combi,
+ iface_combination_policy);
+ if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
+ !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
+ !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
+ goto broken_combination;
+
+ nla_for_each_nested(nl_limit,
+ tb_comb[NL80211_IFACE_COMB_LIMITS],
+ rem_limit) {
+ err = nla_parse_nested(tb_limit,
+ MAX_NL80211_IFACE_LIMIT,
+ nl_limit,
+ iface_limit_policy);
+ if (err ||
+ !tb_limit[NL80211_IFACE_LIMIT_TYPES])
+ goto broken_combination;
+
+ nla_for_each_nested(nl_mode,
+ tb_limit[NL80211_IFACE_LIMIT_TYPES],
+ rem_mode) {
+ int ift = nla_type(nl_mode);
+ if (ift == NL80211_IFTYPE_P2P_GO ||
+ ift == NL80211_IFTYPE_P2P_CLIENT)
+ combination_has_p2p = 1;
+ if (ift == NL80211_IFTYPE_STATION)
+ combination_has_mgd = 1;
+ }
+ if (combination_has_p2p && combination_has_mgd)
+ break;
+ }
+
+ if (combination_has_p2p && combination_has_mgd) {
+ info->p2p_concurrent = 1;
+ break;
+ }
+
+broken_combination:
+ ;
+ }
+ }
+
+
info->p2p_supported = p2p_go_supported && p2p_client_supported;
if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
@@ -1772,6 +1841,12 @@ static int wpa_driver_nl80211_capa(struc
drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
if (info.p2p_supported)
drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
+ if (info.p2p_concurrent) {
+ wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
+ "interface (driver advertised support)");
+ drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
+ drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
+ }
drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
drv->capa.max_remain_on_chan = info.max_remain_on_chan;
More information about the Hostap
mailing list