linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).