cfg80211: Advertise extended capabilities per interface type to userspace

The driver extended capabilities may differ for different
interface types which the userspace needs to know (for
example the fine timing measurement initiator and responder
bits might differ for a station and AP). Add a new nl80211
attribute to provide extended capabilities per interface type
to userspace.

Signed-off-by: Vidyullatha Kanchanapally <vkanchan@qti.qualcomm.com>
Reviewed-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Git-commit: 019ae3a918811715192b22c400ac78d54acc26a9
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
CRs-fixed: 1030694
Change-Id: I816b21d8433aea9407a14a8c8a5098701ee53b8c
[pkushwah@codeaurora.org: backport to 4.4-This commit includes the
changes from following commits in include/uapi/linux/nl80211.h to compile
for msm-4.4.
38de03d2a28925b489c11546804e2f5418cc17a4 :
nl80211: add feature for BSS selection support.
17b942478643c5a90c06d978479bd326040bfa19 :
cfg80211: allow userspace to specify client P2P PS support.
9b95fe59b18bcc891a6c60ae11d725c9c679574b :
nl80211: add missing kerneldoc for new *_PAD attributes.
2dad624e6dd65c6048a9bbe0e16559fce182c87c :
wireless: use nla_put_u64_64bit().]
Signed-off-by: Purushottam Kushwaha <pkushwah@codeaurora.org>
This commit is contained in:
Kanchanapally, Vidyullatha 2016-05-16 10:41:04 +05:30 committed by Gerrit - the friendly Code Review server
parent 956d9b1ab3
commit 33ec44fb7e
4 changed files with 126 additions and 5 deletions

View file

@ -3041,6 +3041,24 @@ struct wiphy_vendor_command {
unsigned long *storage);
};
/**
* struct wiphy_iftype_ext_capab - extended capabilities per interface type
* @iftype: interface type
* @extended_capabilities: extended capabilities supported by the driver,
* additional capabilities might be supported by userspace; these are the
* 802.11 extended capabilities ("Extended Capabilities element") and are
* in the same format as in the information element. See IEEE Std
* 802.11-2012 8.4.2.29 for the defined fields.
* @extended_capabilities_mask: mask of the valid values
* @extended_capabilities_len: length of the extended capabilities
*/
struct wiphy_iftype_ext_capab {
enum nl80211_iftype iftype;
const u8 *extended_capabilities;
const u8 *extended_capabilities_mask;
u8 extended_capabilities_len;
};
/**
* struct wiphy - wireless hardware description
* @reg_notifier: the driver's regulatory notification callback,
@ -3158,9 +3176,14 @@ struct wiphy_vendor_command {
* additional capabilities might be supported by userspace; these are
* the 802.11 extended capabilities ("Extended Capabilities element")
* and are in the same format as in the information element. See
* 802.11-2012 8.4.2.29 for the defined fields.
* 802.11-2012 8.4.2.29 for the defined fields. These are the default
* extended capabilities to be used if the capabilities are not specified
* for a specific interface type in iftype_ext_capab.
* @extended_capabilities_mask: mask of the valid values
* @extended_capabilities_len: length of the extended capabilities
* @iftype_ext_capab: array of extended capabilities per interface type
* @num_iftype_ext_capab: number of interface types for which extended
* capabilities are specified separately.
* @coalesce: packet coalescing support information
*
* @vendor_commands: array of vendor commands supported by the hardware
@ -3257,6 +3280,9 @@ struct wiphy {
const u8 *extended_capabilities, *extended_capabilities_mask;
u8 extended_capabilities_len;
const struct wiphy_iftype_ext_capab *iftype_ext_capab;
unsigned int num_iftype_ext_capab;
/* If multiple wiphys are registered and you're handed e.g.
* a regular netdev with assigned ieee80211_ptr, you won't
* know whether it points to a wiphy your driver has registered

View file

@ -1764,8 +1764,9 @@ enum nl80211_commands {
* over all channels.
*
* @NL80211_ATTR_SCHED_SCAN_DELAY: delay before the first cycle of a
* scheduled scan (or a WoWLAN net-detect scan) is started, u32
* in seconds.
* scheduled scan is started. Or the delay before a WoWLAN
* net-detect scan is started, counting from the moment the
* system is suspended. This value is a u32, in seconds.
* @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
* is operating in an indoor environment.
@ -1782,11 +1783,26 @@ enum nl80211_commands {
* thus it must not specify the number of iterations, only the interval
* between scans. The scan plans are executed sequentially.
* Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan.
*
* @NL80211_ATTR_PBSS: flag attribute. If set it means operate
* in a PBSS. Specified in %NL80211_CMD_CONNECT to request
* connecting to a PCP, and in %NL80211_CMD_START_AP to start
* a PCP instead of AP. Relevant for DMG networks only.
* @NL80211_ATTR_BSS_SELECT: nested attribute for driver supporting the
* BSS selection feature. When used with %NL80211_CMD_GET_WIPHY it contains
* attributes according &enum nl80211_bss_select_attr to indicate what
* BSS selection behaviours are supported. When used with %NL80211_CMD_CONNECT
* it contains the behaviour-specific attribute containing the parameters for
* BSS selection to be done by driver and/or firmware.
*
* @NL80211_ATTR_STA_SUPPORT_P2P_PS: whether P2P PS mechanism supported
* or not. u8, one of the values of &enum nl80211_sta_p2p_ps_status
*
* @NL80211_ATTR_PAD: attribute used for padding for 64-bit alignment
*
* @NL80211_ATTR_IFTYPE_EXT_CAPA: Nested attribute of the following attributes:
* %NL80211_ATTR_IFTYPE, %NL80211_ATTR_EXT_CAPA,
* %NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per
* interface type.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
@ -2164,6 +2180,14 @@ enum nl80211_attrs {
NL80211_ATTR_PBSS,
NL80211_ATTR_BSS_SELECT,
NL80211_ATTR_STA_SUPPORT_P2P_PS,
NL80211_ATTR_PAD,
NL80211_ATTR_IFTYPE_EXT_CAPA,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,

View file

@ -730,6 +730,36 @@ int wiphy_register(struct wiphy *wiphy)
nl80211_send_reg_change_event(&request);
}
/* Check that nobody globally advertises any capabilities they do not
* advertise on all possible interface types.
*/
if (wiphy->extended_capabilities_len &&
wiphy->num_iftype_ext_capab &&
wiphy->iftype_ext_capab) {
u8 supported_on_all, j;
const struct wiphy_iftype_ext_capab *capab;
capab = wiphy->iftype_ext_capab;
for (j = 0; j < wiphy->extended_capabilities_len; j++) {
if (capab[0].extended_capabilities_len > j)
supported_on_all =
capab[0].extended_capabilities[j];
else
supported_on_all = 0x00;
for (i = 1; i < wiphy->num_iftype_ext_capab; i++) {
if (j >= capab[i].extended_capabilities_len) {
supported_on_all = 0x00;
break;
}
supported_on_all &=
capab[i].extended_capabilities[j];
}
if (WARN_ON(wiphy->extended_capabilities[j] &
~supported_on_all))
break;
}
}
rdev->wiphy.registered = true;
rtnl_unlock();

View file

@ -1253,7 +1253,7 @@ nl80211_send_mgmt_stypes(struct sk_buff *msg,
struct nl80211_dump_wiphy_state {
s64 filter_wiphy;
long start;
long split_start, band_start, chan_start;
long split_start, band_start, chan_start, capa_start;
bool split;
};
@ -1731,6 +1731,47 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
rdev->wiphy.ext_features))
goto nla_put_failure;
state->split_start++;
break;
case 13:
if (rdev->wiphy.num_iftype_ext_capab &&
rdev->wiphy.iftype_ext_capab) {
struct nlattr *nested_ext_capab, *nested;
nested = nla_nest_start(msg,
NL80211_ATTR_IFTYPE_EXT_CAPA);
if (!nested)
goto nla_put_failure;
for (i = state->capa_start;
i < rdev->wiphy.num_iftype_ext_capab; i++) {
const struct wiphy_iftype_ext_capab *capab;
capab = &rdev->wiphy.iftype_ext_capab[i];
nested_ext_capab = nla_nest_start(msg, i);
if (!nested_ext_capab ||
nla_put_u32(msg, NL80211_ATTR_IFTYPE,
capab->iftype) ||
nla_put(msg, NL80211_ATTR_EXT_CAPA,
capab->extended_capabilities_len,
capab->extended_capabilities) ||
nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
capab->extended_capabilities_len,
capab->extended_capabilities_mask))
goto nla_put_failure;
nla_nest_end(msg, nested_ext_capab);
if (state->split)
break;
}
nla_nest_end(msg, nested);
if (i < rdev->wiphy.num_iftype_ext_capab) {
state->capa_start = i + 1;
break;
}
}
/* done */
state->split_start = 0;
break;