Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 369600
b: refs/heads/master
c: 5de1798
h: refs/heads/master
v: v3
  • Loading branch information
Arend van Spriel authored and Johannes Berg committed Apr 22, 2013
1 parent 960a7df commit a2cd9cb
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a36473621c871df14bbf2106ab0721b475aac8e0
refs/heads/master: 5de17984898c5758fc6ebe08eccea9f4b6548914
23 changes: 23 additions & 0 deletions trunk/include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2002,6 +2002,12 @@ struct cfg80211_update_ft_ies_params {
* @update_ft_ies: Provide updated Fast BSS Transition information to the
* driver. If the SME is in the driver/firmware, this information can be
* used in building Authentication and Reassociation Request frames.
*
* @crit_proto_start: Indicates a critical protocol needs more link reliability
* for a given duration (milliseconds). The protocol is provided so the
* driver can take the most appropriate actions.
* @crit_proto_stop: Indicates critical protocol no longer needs increased link
* reliability. This operation can not fail.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
Expand Down Expand Up @@ -2231,6 +2237,12 @@ struct cfg80211_ops {
struct cfg80211_chan_def *chandef);
int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_update_ft_ies_params *ftie);
int (*crit_proto_start)(struct wiphy *wiphy,
struct wireless_dev *wdev,
enum nl80211_crit_proto_id protocol,
u16 duration);
void (*crit_proto_stop)(struct wiphy *wiphy,
struct wireless_dev *wdev);
};

/*
Expand Down Expand Up @@ -4137,6 +4149,17 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
struct cfg80211_wowlan_wakeup *wakeup,
gfp_t gfp);

/**
* cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver.
*
* @wdev: the wireless device for which critical protocol is stopped.
*
* This function can be called by the driver to indicate it has reverted
* operation back to normal. One reason could be that the duration given
* by .crit_proto_start() has expired.
*/
void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp);

/* Logging, debugging and troubleshooting/diagnostic helpers. */

/* wiphy_printk helpers, similar to dev_printk */
Expand Down
39 changes: 39 additions & 0 deletions trunk/include/uapi/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,13 @@
* with the relevant Information Elements. This event is used to report
* received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE).
*
* @NL80211_CMD_CRIT_PROTOCOL_START: Indicates user-space will start running
* a critical protocol that needs more reliability in the connection to
* complete.
*
* @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
* return back to normal.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -798,6 +805,9 @@ enum nl80211_commands {
NL80211_CMD_UPDATE_FT_IES,
NL80211_CMD_FT_EVENT,

NL80211_CMD_CRIT_PROTOCOL_START,
NL80211_CMD_CRIT_PROTOCOL_STOP,

/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
Expand Down Expand Up @@ -1414,6 +1424,11 @@ enum nl80211_commands {
* @NL80211_ATTR_IE_RIC: Resource Information Container Information
* Element
*
* @NL80211_ATTR_CRIT_PROT_ID: critical protocol identifier requiring increased
* reliability, see &enum nl80211_crit_proto_id (u16).
* @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which
* the connection should have increased reliability (u16).
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -1709,6 +1724,9 @@ enum nl80211_attrs {
NL80211_ATTR_MDID,
NL80211_ATTR_IE_RIC,

NL80211_ATTR_CRIT_PROT_ID,
NL80211_ATTR_MAX_CRIT_PROT_DURATION,

/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
Expand Down Expand Up @@ -3682,4 +3700,25 @@ enum nl80211_protocol_features {
NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 1 << 0,
};

/**
* enum nl80211_crit_proto_id - nl80211 critical protocol identifiers
*
* @NL80211_CRIT_PROTO_UNSPEC: protocol unspecified.
* @NL80211_CRIT_PROTO_DHCP: BOOTP or DHCPv6 protocol.
* @NL80211_CRIT_PROTO_EAPOL: EAPOL protocol.
* @NL80211_CRIT_PROTO_APIPA: APIPA protocol.
* @NUM_NL80211_CRIT_PROTO: must be kept last.
*/
enum nl80211_crit_proto_id {
NL80211_CRIT_PROTO_UNSPEC,
NL80211_CRIT_PROTO_DHCP,
NL80211_CRIT_PROTO_EAPOL,
NL80211_CRIT_PROTO_APIPA,
/* add other protocols before this one */
NUM_NL80211_CRIT_PROTO
};

/* maximum duration for critical protocol measures */
#define NL80211_CRIT_PROTO_MAX_DURATION 5000 /* msec */

#endif /* __LINUX_NL80211_H */
3 changes: 3 additions & 0 deletions trunk/net/wireless/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ struct cfg80211_registered_device {

struct delayed_work dfs_update_channels_wk;

/* netlink port which started critical protocol (0 means not started) */
u32 crit_proto_nlportid;

/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __aligned(NETDEV_ALIGN);
Expand Down
5 changes: 5 additions & 0 deletions trunk/net/wireless/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,11 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)

spin_unlock_bh(&wdev->mgmt_registrations_lock);

if (nlportid && rdev->crit_proto_nlportid == nlportid) {
rdev->crit_proto_nlportid = 0;
rdev_crit_proto_stop(rdev, wdev);
}

if (nlportid == wdev->ap_unexpected_nlportid)
wdev->ap_unexpected_nlportid = 0;
}
Expand Down
117 changes: 117 additions & 0 deletions trunk/net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
}
CMD(start_p2p_device, START_P2P_DEVICE);
CMD(set_mcast_rate, SET_MCAST_RATE);
if (split) {
CMD(crit_proto_start, CRIT_PROTOCOL_START);
CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
}

#ifdef CONFIG_NL80211_TESTMODE
CMD(testmode_cmd, TESTMODE);
Expand Down Expand Up @@ -8216,6 +8220,64 @@ static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
return rdev_update_ft_ies(rdev, dev, &ft_params);
}

static int nl80211_crit_protocol_start(struct sk_buff *skb,
struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1];
enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
u16 duration;
int ret;

if (!rdev->ops->crit_proto_start)
return -EOPNOTSUPP;

if (WARN_ON(!rdev->ops->crit_proto_stop))
return -EINVAL;

if (rdev->crit_proto_nlportid)
return -EBUSY;

/* determine protocol if provided */
if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);

if (proto >= NUM_NL80211_CRIT_PROTO)
return -EINVAL;

/* timeout must be provided */
if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
return -EINVAL;

duration =
nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);

if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
return -ERANGE;

ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
if (!ret)
rdev->crit_proto_nlportid = info->snd_portid;

return ret;
}

static int nl80211_crit_protocol_stop(struct sk_buff *skb,
struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1];

if (!rdev->ops->crit_proto_stop)
return -EOPNOTSUPP;

if (rdev->crit_proto_nlportid) {
rdev->crit_proto_nlportid = 0;
rdev_crit_proto_stop(rdev, wdev);
}
return 0;
}

#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
Expand Down Expand Up @@ -8905,6 +8967,22 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_CRIT_PROTOCOL_START,
.doit = nl80211_crit_protocol_start,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
.doit = nl80211_crit_protocol_stop,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_NEED_RTNL,
}
};

static struct genl_multicast_group nl80211_mlme_mcgrp = {
Expand Down Expand Up @@ -10650,6 +10728,45 @@ void cfg80211_ft_event(struct net_device *netdev,
}
EXPORT_SYMBOL(cfg80211_ft_event);

void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
{
struct cfg80211_registered_device *rdev;
struct sk_buff *msg;
void *hdr;
u32 nlportid;

rdev = wiphy_to_dev(wdev->wiphy);
if (!rdev->crit_proto_nlportid)
return;

nlportid = rdev->crit_proto_nlportid;
rdev->crit_proto_nlportid = 0;

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
if (!msg)
return;

hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
if (!hdr)
goto nla_put_failure;

if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
goto nla_put_failure;

genlmsg_end(msg, hdr);

genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
return;

nla_put_failure:
if (hdr)
genlmsg_cancel(msg, hdr);
nlmsg_free(msg);

}
EXPORT_SYMBOL(cfg80211_crit_proto_stopped);

/* initialisation/exit functions */

int nl80211_init(void)
Expand Down
24 changes: 23 additions & 1 deletion trunk/net/wireless/rdev-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev,
trace_rdev_stop_p2p_device(&rdev->wiphy, wdev);
rdev->ops->stop_p2p_device(&rdev->wiphy, wdev);
trace_rdev_return_void(&rdev->wiphy);
}
}

static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev,
struct net_device *dev,
Expand All @@ -901,4 +901,26 @@ static inline int rdev_update_ft_ies(struct cfg80211_registered_device *rdev,
return ret;
}

static inline int rdev_crit_proto_start(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
enum nl80211_crit_proto_id protocol,
u16 duration)
{
int ret;

trace_rdev_crit_proto_start(&rdev->wiphy, wdev, protocol, duration);
ret = rdev->ops->crit_proto_start(&rdev->wiphy, wdev,
protocol, duration);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}

static inline void rdev_crit_proto_stop(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev)
{
trace_rdev_crit_proto_stop(&rdev->wiphy, wdev);
rdev->ops->crit_proto_stop(&rdev->wiphy, wdev);
trace_rdev_return_void(&rdev->wiphy);
}

#endif /* __CFG80211_RDEV_OPS */
35 changes: 35 additions & 0 deletions trunk/net/wireless/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -1806,6 +1806,41 @@ TRACE_EVENT(rdev_update_ft_ies,
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->md)
);

TRACE_EVENT(rdev_crit_proto_start,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_crit_proto_id protocol, u16 duration),
TP_ARGS(wiphy, wdev, protocol, duration),
TP_STRUCT__entry(
WIPHY_ENTRY
WDEV_ENTRY
__field(u16, proto)
__field(u16, duration)
),
TP_fast_assign(
WIPHY_ASSIGN;
WDEV_ASSIGN;
__entry->proto = protocol;
__entry->duration = duration;
),
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", proto=%x, duration=%u",
WIPHY_PR_ARG, WDEV_PR_ARG, __entry->proto, __entry->duration)
);

TRACE_EVENT(rdev_crit_proto_stop,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
TP_ARGS(wiphy, wdev),
TP_STRUCT__entry(
WIPHY_ENTRY
WDEV_ENTRY
),
TP_fast_assign(
WIPHY_ASSIGN;
WDEV_ASSIGN;
),
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT,
WIPHY_PR_ARG, WDEV_PR_ARG)
);

/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/
Expand Down

0 comments on commit a2cd9cb

Please sign in to comment.