From: Ben Greear <greearb@candelatech.com>
To: Arend van Spriel <arend@broadcom.com>
Cc: Johannes Berg <johannes@sipsolutions.net>,
linux-wireless <linux-wireless@vger.kernel.org>
Subject: Re: [RFC V4] cfg80211: introduce critical protocol indication from user-space
Date: Fri, 05 Apr 2013 07:03:43 -0700 [thread overview]
Message-ID: <515ED9BF.20203@candelatech.com> (raw)
In-Reply-To: <1365168312-14780-1-git-send-email-arend@broadcom.com>
On 04/05/2013 06:25 AM, Arend van Spriel wrote:
> Some protocols need a more reliable connection to complete
> successful in reasonable time. This patch adds a user-space
> API to indicate the wireless driver that a critical protocol
> is about to commence and when it is done, using nl80211 primitives
> NL80211_CMD_CRIT_PROTOCOL_START and NL80211_CRIT_PROTOCOL_STOP.
>
> There can be only on critical protocol session started per
> registered cfg80211 device. The driver can support this by
> implementing the cfg80211 callbacks .crit_proto_start() and
> .crit_proto_stop(). Examples of protocols that can benefit from
> this are DHCP, EAPOL, APIPA. Exactly how the link can/should be
> made more reliable is up to the driver. Things to consider are
> avoid scanning, no multi-channel operations, and alter coexistence
> schemes.
>
> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
> Signed-off-by: Arend van Spriel <arend@broadcom.com>
> ---
> +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;
> +
> + if (!rdev->ops->crit_proto_start)
> + return -EOPNOTSUPP;
> +
> + if (WARN_ON(!rdev->ops->crit_proto_stop))
> + return -EINVAL;
> +
> + if (rdev->crit_proto_started)
> + 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 >= NL80211_CRIT_PROTO_LAST)
> + 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]);
> +
> + duration = max_t(u16, duration, NL80211_MAX_CRIT_PROT_DURATION);
Maybe that should be min_t(....) ?
> +
> + return rdev_crit_proto_start(rdev, wdev, proto, duration);
> +}
> +
> +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;
> +
> + return rdev_crit_proto_stop(rdev, wdev);
> +}
> +
> #define NL80211_FLAG_NEED_WIPHY 0x01
> #define NL80211_FLAG_NEED_NETDEV 0x02
> #define NL80211_FLAG_NEED_RTNL 0x04
> @@ -8885,6 +8939,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 = {
> @@ -10630,6 +10700,16 @@ void cfg80211_ft_event(struct net_device *netdev,
> }
> EXPORT_SYMBOL(cfg80211_ft_event);
>
> +void cfg80211_crit_proto_stopped(struct wireless_dev *wdev)
> +{
> + struct cfg80211_registered_device *rdev;
> +
> + rdev = wiphy_to_dev(wdev->wiphy);
> + WARN_ON(!rdev->crit_proto_started);
> + rdev->crit_proto_started = false;
> +}
> +EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
> +
> /* initialisation/exit functions */
>
> int nl80211_init(void)
> diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
> index d77e1c1..a80a7c9 100644
> --- a/net/wireless/rdev-ops.h
> +++ b/net/wireless/rdev-ops.h
> @@ -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,
> @@ -901,4 +901,33 @@ 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);
> + rdev->crit_proto_started = !ret;
> + trace_rdev_return_int(&rdev->wiphy, ret);
> + return ret;
> +}
> +
> +static inline int rdev_crit_proto_stop(struct cfg80211_registered_device *rdev,
> + struct wireless_dev *wdev)
> +{
> + int ret = 0;
> +
> + trace_rdev_crit_proto_stop(&rdev->wiphy, wdev);
> + if (rdev->crit_proto_started) {
> + ret = rdev->ops->crit_proto_stop(&rdev->wiphy, wdev);
> + rdev->crit_proto_started = ret != 0;
Maybe: rdev->crit_proto_started = !ret;
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
next prev parent reply other threads:[~2013-04-05 14:03 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-05 13:25 [RFC V4] cfg80211: introduce critical protocol indication from user-space Arend van Spriel
2013-04-05 14:03 ` Ben Greear [this message]
2013-04-05 19:19 ` Arend van Spriel
2013-04-05 19:29 ` Ben Greear
2013-04-05 20:50 ` Arend van Spriel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=515ED9BF.20203@candelatech.com \
--to=greearb@candelatech.com \
--cc=arend@broadcom.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.