All of lore.kernel.org
 help / color / mirror / Atom feed
* cfg80211: add set/get link loss profile
@ 2016-11-10 11:33 Lazar, Alexei Avshalom
  2016-11-10 13:55 ` Kalle Valo
  2016-11-28 14:52 ` Johannes Berg
  0 siblings, 2 replies; 13+ messages in thread
From: Lazar, Alexei Avshalom @ 2016-11-10 11:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

>From b739abb6f29dc43a86b8b2b60e893b4441f8aa1f Mon Sep 17 00:00:00 2001
From: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
Date: Sun, 6 Nov 2016 16:21:20 +0200
Subject: [PATCH] cfg80211: add set/get link loss profile

Introduce NL80211_CMD_SET_LINK_LOSS_PROFILE and
NL80211_CMD_GET_LINK_LOSS_PROFILE as it required by the user space
to configure the link loss profile.
The link loss profile represents the priority of maintaining link up
in different link quality environments.
Three types of behavior for link loss defined:
LINK_LOSS_PROFILE_RELAXED: prefer maintaining link up even in poor
link quality environment.
LINK_LOSS_PROFILE_DEFAULT: The default behavior for maintaining link
up vs link quality.
LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link up in poor link
quality environment.
New cfg80211 API also been added, set/get_link_loss_profile.

Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
---
 drivers/net/wireless/ath/wil6210/cfg80211.c | 18 ++++++++
 include/net/cfg80211.h                      | 13 ++++++
 include/uapi/linux/nl80211.h                | 32 +++++++++++++
 net/wireless/nl80211.c                      | 70 +++++++++++++++++++++++++++++
 net/wireless/rdev-ops.h                     | 28 ++++++++++++
 net/wireless/trace.h                        | 39 ++++++++++++++++
 6 files changed, 200 insertions(+)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index d117240..f8d576b 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1424,6 +1424,22 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
     mutex_unlock(&wil->mutex);
 }
 
+static int
+wil_cfg80211_set_link_loss_profile(struct wiphy *wiphy,
+                   struct wireless_dev *wdev,
+                   enum nl80211_link_loss_profile profile,
+                   const u8 *addr)
+{
+    return -ENOTSUPP;
+}
+
+static enum nl80211_link_loss_profile
+wil_cfg80211_get_link_loss_profile(struct wiphy *wiphy,
+                   struct wireless_dev *wdev, const u8 *addr)
+{
+    return -ENOTSUPP;
+}
+
 static struct cfg80211_ops wil_cfg80211_ops = {
     .add_virtual_intf = wil_cfg80211_add_iface,
     .del_virtual_intf = wil_cfg80211_del_iface,
@@ -1450,6 +1466,8 @@ static struct cfg80211_ops wil_cfg80211_ops = {
     /* P2P device */
     .start_p2p_device = wil_cfg80211_start_p2p_device,
     .stop_p2p_device = wil_cfg80211_stop_p2p_device,
+    .set_link_loss_profile = wil_cfg80211_set_link_loss_profile,
+    .get_link_loss_profile = wil_cfg80211_get_link_loss_profile,
 };
 
 static void wil_wiphy_init(struct wiphy *wiphy)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 41ae3f5..2d7a0af 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2744,6 +2744,10 @@ struct cfg80211_nan_func {
  *    All other parameters must be ignored.
  *
  * @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
+ *
+ * @set_link_loss_profile: Set link loss profile for specific connection.
+ * @get_link_loss_profile: Get the current link loss profile of specific
+ *    connection.
  */
 struct cfg80211_ops {
     int    (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3024,6 +3028,15 @@ struct cfg80211_ops {
     int    (*set_multicast_to_unicast)(struct wiphy *wiphy,
                         struct net_device *dev,
                         const bool enabled);
+
+    int    (*set_link_loss_profile)(struct wiphy *wiphy,
+                     struct wireless_dev *wdev,
+                     enum nl80211_link_loss_profile profile,
+                     const u8 *addr);
+    enum nl80211_link_loss_profile    (*get_link_loss_profile)(
+                     struct wiphy *wiphy,
+                     struct wireless_dev *wdev,
+                     const u8 *addr);
 };
 
 /*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e21d23d..b68fad2 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -888,6 +888,11 @@
  *    This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
  *    %NL80211_ATTR_COOKIE.
  *
+ * @NL80211_CMD_SET_LINK_LOSS_PROFILE: Set link loss profile (behavior) for
+ *    specific connection.
+ * @NL80211_CMD_GET_LINK_LOSS_PROFILE: Get current link loss profile of specific
+ *    connection.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1085,6 +1090,9 @@ enum nl80211_commands {
 
     NL80211_CMD_SET_MULTICAST_TO_UNICAST,
 
+    NL80211_CMD_SET_LINK_LOSS_PROFILE,
+    NL80211_CMD_GET_LINK_LOSS_PROFILE,
+
     /* add new commands above here */
 
     /* used to define NL80211_CMD_MAX below */
@@ -1969,6 +1977,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED: Indicates whether or not multicast
  *    packets should be send out as unicast to all stations (flag attribute).
  *
+ * @NL80211_ATTR_LINK_LOSS_PROFILE: attribute that indicate the link loss
+ *    behavior using &enum nl80211_link_loss_profile values.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2373,6 +2384,8 @@ enum nl80211_attrs {
 
     NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED,
 
+    NL80211_ATTR_LINK_LOSS_PROFILE,
+
     /* add attributes here, update the policy in nl80211.c */
 
     __NL80211_ATTR_AFTER_LAST,
@@ -5174,4 +5187,23 @@ enum nl80211_nan_match_attributes {
     NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
 };
 
+/**
+ * enum nl80211_link_loss_profile.
+ *
+ * Used by set_link_loss_profile() and get_link_loss_profile()
+ * to set/get link loss behavior.
+ *
+ * @NL80211_LINK_LOSS_PROFILE_RELAXED: prefer maintaining link
+ *    up even in poor link quality environment
+ * @NL80211_LINK_LOSS_PROFILE_DEFAULT: The default behavior for
+ *    maintaining link up vs link quality.
+ * @NL80211_LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link
+ *    up in poor link quality environment
+ */
+enum nl80211_link_loss_profile {
+    NL80211_LINK_LOSS_PROFILE_RELAXED,
+    NL80211_LINK_LOSS_PROFILE_DEFAULT,
+    NL80211_LINK_LOSS_PROFILE_AGGRESSIVE
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 46b2e8c..c8dc7e2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -418,6 +418,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
                     .len = FILS_MAX_KEK_LEN },
     [NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
     [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
+    [NL80211_ATTR_LINK_LOSS_PROFILE] = { .type = NLA_U8 },
 };
 
 /* policy for the key attributes */
@@ -11792,6 +11793,60 @@ static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
     return rdev_set_multicast_to_unicast(rdev, dev, enabled);
 }
 
+static int nl80211_set_link_loss_profile(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_link_loss_profile profile;
+    const u8 *addr;
+    int ret;
+
+    if (!info->attrs[NL80211_ATTR_LINK_LOSS_PROFILE] ||
+        !info->attrs[NL80211_ATTR_MAC])
+        return -EINVAL;
+
+    profile = nla_get_u8(info->attrs[NL80211_ATTR_LINK_LOSS_PROFILE]);
+    addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+    if (profile != NL80211_LINK_LOSS_PROFILE_RELAXED &&
+        profile != NL80211_LINK_LOSS_PROFILE_DEFAULT &&
+        profile != NL80211_LINK_LOSS_PROFILE_AGGRESSIVE)
+        return -EINVAL;
+
+    if (!rdev->ops->set_link_loss_profile)
+        return -EOPNOTSUPP;
+
+    wdev_lock(wdev);
+    ret = rdev_set_link_loss_profile(rdev, wdev, profile, addr);
+    wdev_unlock(wdev);
+
+    return ret;
+}
+
+static int nl80211_get_link_loss_profile(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];
+    const u8 *addr;
+    enum nl80211_link_loss_profile profile;
+
+    if (!info->attrs[NL80211_ATTR_MAC])
+        return -EINVAL;
+
+    addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+    if (!rdev->ops->get_link_loss_profile)
+        return -EOPNOTSUPP;
+
+    wdev_lock(wdev);
+    profile = rdev_get_link_loss_profile(rdev, wdev, addr);
+    wdev_unlock(wdev);
+
+    return profile;
+}
+
 #define NL80211_FLAG_NEED_WIPHY        0x01
 #define NL80211_FLAG_NEED_NETDEV    0x02
 #define NL80211_FLAG_NEED_RTNL        0x04
@@ -12659,6 +12714,21 @@ static const struct genl_ops nl80211_ops[] = {
         .internal_flags = NL80211_FLAG_NEED_NETDEV |
                   NL80211_FLAG_NEED_RTNL,
     },
+    {
+    .cmd = NL80211_CMD_SET_LINK_LOSS_PROFILE,
+        .doit = nl80211_set_link_loss_profile,
+        .policy = nl80211_policy,
+        .flags = GENL_ADMIN_PERM,
+        .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                  NL80211_FLAG_NEED_RTNL,
+    },
+    {
+    .cmd = NL80211_CMD_GET_LINK_LOSS_PROFILE,
+        .doit = nl80211_get_link_loss_profile,
+        .policy = nl80211_policy,
+        .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                  NL80211_FLAG_NEED_RTNL,
+    },
 };
 
 /* notification functions */
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index e9ecf23..9a377c8 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1141,4 +1141,32 @@ rdev_set_coalesce(struct cfg80211_registered_device *rdev,
     trace_rdev_return_int(&rdev->wiphy, ret);
     return ret;
 }
+
+static inline int
+rdev_set_link_loss_profile(struct cfg80211_registered_device *rdev,
+               struct wireless_dev *wdev,
+               enum nl80211_link_loss_profile profile,
+               const u8 *addr)
+{
+    int ret;
+
+    trace_rdev_set_link_loss_profile(&rdev->wiphy, wdev, profile, addr);
+    ret = rdev->ops->set_link_loss_profile(&rdev->wiphy, wdev, profile,
+                           addr);
+    trace_rdev_return_int(&rdev->wiphy, ret);
+    return ret;
+}
+
+static inline enum nl80211_link_loss_profile
+rdev_get_link_loss_profile(struct cfg80211_registered_device *rdev,
+               struct wireless_dev *wdev,
+               const u8 *addr)
+{
+    enum nl80211_link_loss_profile profile;
+
+    trace_rdev_get_link_loss_profile(&rdev->wiphy, wdev, addr);
+    profile = rdev->ops->get_link_loss_profile(&rdev->wiphy, wdev, addr);
+    trace_rdev_return_int(&rdev->wiphy, profile);
+    return profile;
+}
 #endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 25f8318..d93a4b1 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2212,6 +2212,45 @@ TRACE_EVENT(rdev_tdls_cancel_channel_switch,
           WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr))
 );
 
+TRACE_EVENT(rdev_set_link_loss_profile,
+    TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+         enum nl80211_link_loss_profile profile, const u8 *addr),
+    TP_ARGS(wiphy, wdev, profile, addr),
+    TP_STRUCT__entry(
+        WIPHY_ENTRY
+        WDEV_ENTRY
+        __field(enum nl80211_link_loss_profile, profile)
+        MAC_ENTRY(addr)
+    ),
+    TP_fast_assign(
+        WIPHY_ASSIGN;
+        WDEV_ASSIGN;
+        __entry->profile = profile;
+        MAC_ASSIGN(addr, addr);
+    ),
+    TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " MAC_PR_FMT ", PROFILE %d",
+          WIPHY_PR_ARG, WDEV_PR_ARG, MAC_PR_ARG(addr),
+          __entry->profile)
+);
+
+TRACE_EVENT(rdev_get_link_loss_profile,
+    TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+         const u8 *addr),
+    TP_ARGS(wiphy, wdev, addr),
+    TP_STRUCT__entry(
+        WIPHY_ENTRY
+        WDEV_ENTRY
+        MAC_ENTRY(addr)
+    ),
+    TP_fast_assign(
+        WIPHY_ASSIGN;
+        WDEV_ASSIGN;
+        MAC_ASSIGN(addr, addr);
+    ),
+    TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " MAC_PR_FMT, WIPHY_PR_ARG,
+          WDEV_PR_ARG, MAC_PR_ARG(addr))
+);
+
 /*************************************************************
  *         cfg80211 exported functions traces             *
  *************************************************************/
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: cfg80211: add set/get link loss profile
  2016-11-10 11:33 cfg80211: add set/get link loss profile Lazar, Alexei Avshalom
@ 2016-11-10 13:55 ` Kalle Valo
  2016-11-17 13:50   ` Lazar, Alexei Avshalom
  2016-11-28 14:52 ` Johannes Berg
  1 sibling, 1 reply; 13+ messages in thread
From: Kalle Valo @ 2016-11-10 13:55 UTC (permalink / raw)
  To: Lazar, Alexei Avshalom; +Cc: johannes, linux-wireless

"Lazar, Alexei Avshalom" <ailizaro@codeaurora.org> writes:

>>From b739abb6f29dc43a86b8b2b60e893b4441f8aa1f Mon Sep 17 00:00:00 2001
> From: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
> Date: Sun, 6 Nov 2016 16:21:20 +0200
> Subject: [PATCH] cfg80211: add set/get link loss profile
>
> Introduce NL80211_CMD_SET_LINK_LOSS_PROFILE and
> NL80211_CMD_GET_LINK_LOSS_PROFILE as it required by the user space
> to configure the link loss profile.
> The link loss profile represents the priority of maintaining link up
> in different link quality environments.
> Three types of behavior for link loss defined:
> LINK_LOSS_PROFILE_RELAXED: prefer maintaining link up even in poor
> link quality environment.
> LINK_LOSS_PROFILE_DEFAULT: The default behavior for maintaining link
> up vs link quality.
> LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link up in poor link
> quality environment.
> New cfg80211 API also been added, set/get_link_loss_profile.
>
> Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>

What does the term "link" mean in this context? A connection to the AP
or something else? The documentation doesn't give me any detailed
information nor any examples and lefts me guessing what this is supposed
to do.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: cfg80211: add set/get link loss profile
  2016-11-10 13:55 ` Kalle Valo
@ 2016-11-17 13:50   ` Lazar, Alexei Avshalom
  2016-11-18 11:05     ` Kalle Valo
  0 siblings, 1 reply; 13+ messages in thread
From: Lazar, Alexei Avshalom @ 2016-11-17 13:50 UTC (permalink / raw)
  To: Kalle Valo; +Cc: johannes, linux-wireless

Hi Kalle,

In this context the term "link" does mean connection to AP.
There are scenarios that require to lose connection faster once
reduced link quality detected in order maintain better user experience
(from both sides - AP and STA).
Example case is FST (Fast Session Transfer), where we have a fast 11ad
connection but close-range and a backup 11ac connection which is
"always on".
in such cases if we detect poor link quality in the active band we
prefer to disconnect and switch to the backup connection with the good
link quality.
This will be reached by setting "aggressive" profile that will cause
more rapid disconnect in such cases.

Alexei Lazar
Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc. 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum a Linux Foundation Collaborative Project


On 11/10/2016 3:55 PM, Kalle Valo wrote:
> "Lazar, Alexei Avshalom" <ailizaro@codeaurora.org> writes:
>
>> >From b739abb6f29dc43a86b8b2b60e893b4441f8aa1f Mon Sep 17 00:00:00 2001
>> From: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
>> Date: Sun, 6 Nov 2016 16:21:20 +0200
>> Subject: [PATCH] cfg80211: add set/get link loss profile
>>
>> Introduce NL80211_CMD_SET_LINK_LOSS_PROFILE and
>> NL80211_CMD_GET_LINK_LOSS_PROFILE as it required by the user space
>> to configure the link loss profile.
>> The link loss profile represents the priority of maintaining link up
>> in different link quality environments.
>> Three types of behavior for link loss defined:
>> LINK_LOSS_PROFILE_RELAXED: prefer maintaining link up even in poor
>> link quality environment.
>> LINK_LOSS_PROFILE_DEFAULT: The default behavior for maintaining link
>> up vs link quality.
>> LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link up in poor link
>> quality environment.
>> New cfg80211 API also been added, set/get_link_loss_profile.
>>
>> Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
> What does the term "link" mean in this context? A connection to the AP
> or something else? The documentation doesn't give me any detailed
> information nor any examples and lefts me guessing what this is supposed
> to do.
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: cfg80211: add set/get link loss profile
  2016-11-17 13:50   ` Lazar, Alexei Avshalom
@ 2016-11-18 11:05     ` Kalle Valo
  2016-12-19 10:58       ` Lazar, Alexei Avshalom
  2016-12-19 10:58       ` [PATCH v2] " Lazar, Alexei Avshalom
  0 siblings, 2 replies; 13+ messages in thread
From: Kalle Valo @ 2016-11-18 11:05 UTC (permalink / raw)
  To: Lazar, Alexei Avshalom; +Cc: johannes, linux-wireless

Hi Alexei,

"Lazar, Alexei Avshalom" <ailizaro@codeaurora.org> writes:

> In this context the term "link" does mean connection to AP. There are
> scenarios that require to lose connection faster once reduced link
> quality detected in order maintain better user experience (from both
> sides - AP and STA). Example case is FST (Fast Session Transfer),
> where we have a fast 11ad connection but close-range and a backup 11ac
> connection which is "always on". in such cases if we detect poor link
> quality in the active band we prefer to disconnect and switch to the
> backup connection with the good link quality. This will be reached by
> setting "aggressive" profile that will cause more rapid disconnect in
> such cases.

The documentation should clearly document what this command is supposed,
currently it only tells me "maintain/lose link" and does not specify in
detail what this is supposed to do. Also there's no mention in what
modes this can be used. (STA, P2P?)

Also please refrain from top posting in public mailing lists, the
preferred way is to edit quotes and bottom post. It's much more natural
way to have long detailed discussions.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: cfg80211: add set/get link loss profile
  2016-11-10 11:33 cfg80211: add set/get link loss profile Lazar, Alexei Avshalom
  2016-11-10 13:55 ` Kalle Valo
@ 2016-11-28 14:52 ` Johannes Berg
  2016-12-19 10:58   ` Lazar, Alexei Avshalom
  1 sibling, 1 reply; 13+ messages in thread
From: Johannes Berg @ 2016-11-28 14:52 UTC (permalink / raw)
  To: Lazar, Alexei Avshalom; +Cc: linux-wireless


> Introduce NL80211_CMD_SET_LINK_LOSS_PROFILE and
> NL80211_CMD_GET_LINK_LOSS_PROFILE as it required by the user space
> to configure the link loss profile.

I'm not convinced.

> The link loss profile represents the priority of maintaining link up
> in different link quality environments.
> Three types of behavior for link loss defined:
> LINK_LOSS_PROFILE_RELAXED: prefer maintaining link up even in poor
> link quality environment.
> LINK_LOSS_PROFILE_DEFAULT: The default behavior for maintaining link
> up vs link quality.
> LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link up in poor link
> quality environment.

What you're doing here is *extremely* vague. No definitions of what
this means, no description of how it's intended to be implemented, no
note even on whether or not this is for full-MAC chips or not, etc.

At least for mac80211, we can define signals to userspace regarding
"link quality" and make decisions in wpa_s then?


> --- a/drivers/net/wireless/ath/wil6210/cfg80211.c

Those changes obviously don't belong into this patch anyway.

johannes

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: cfg80211: add set/get link loss profile
  2016-11-28 14:52 ` Johannes Berg
@ 2016-12-19 10:58   ` Lazar, Alexei Avshalom
  2017-01-02 10:45     ` Johannes Berg
  0 siblings, 1 reply; 13+ messages in thread
From: Lazar, Alexei Avshalom @ 2016-12-19 10:58 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, wil6210

On 11/28/2016 4:52 PM, Johannes Berg wrote:
> 
>> Introduce NL80211_CMD_SET_LINK_LOSS_PROFILE and
>> NL80211_CMD_GET_LINK_LOSS_PROFILE as it required by the user space
>> to configure the link loss profile.
> 
> I'm not convinced.
> 
>> The link loss profile represents the priority of maintaining link up
>> in different link quality environments.
>> Three types of behavior for link loss defined:
>> LINK_LOSS_PROFILE_RELAXED: prefer maintaining link up even in poor
>> link quality environment.
>> LINK_LOSS_PROFILE_DEFAULT: The default behavior for maintaining link
>> up vs link quality.
>> LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link up in poor link
>> quality environment.
> 
> What you're doing here is *extremely* vague. No definitions of what
> this means, no description of how it's intended to be implemented, no
> note even on whether or not this is for full-MAC chips or not, etc.
> 

The patch is intended for full-MAC chips and I will update the commit
message to include more details.

> At least for mac80211, we can define signals to userspace regarding
> "link quality" and make decisions in wpa_s then?
> 

The policy is offloaded today to the FW and the decision being made by the FW.
We are only modifying the behavior and not making the decision.

> 
>> --- a/drivers/net/wireless/ath/wil6210/cfg80211.c
> 
> Those changes obviously don't belong into this patch anyway.
> 
> johannes
> 


-- 
Alexei Lazar
Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc. 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: cfg80211: add set/get link loss profile
  2016-11-18 11:05     ` Kalle Valo
@ 2016-12-19 10:58       ` Lazar, Alexei Avshalom
  2016-12-19 10:58       ` [PATCH v2] " Lazar, Alexei Avshalom
  1 sibling, 0 replies; 13+ messages in thread
From: Lazar, Alexei Avshalom @ 2016-12-19 10:58 UTC (permalink / raw)
  To: Kalle Valo; +Cc: johannes, linux-wireless, wil6210

On 11/18/2016 1:05 PM, Kalle Valo wrote:
> Hi Alexei,
> 
> "Lazar, Alexei Avshalom" <ailizaro@codeaurora.org> writes:
> 
>> In this context the term "link" does mean connection to AP. There are
>> scenarios that require to lose connection faster once reduced link
>> quality detected in order maintain better user experience (from both
>> sides - AP and STA). Example case is FST (Fast Session Transfer),
>> where we have a fast 11ad connection but close-range and a backup 11ac
>> connection which is "always on". in such cases if we detect poor link
>> quality in the active band we prefer to disconnect and switch to the
>> backup connection with the good link quality. This will be reached by
>> setting "aggressive" profile that will cause more rapid disconnect in
>> such cases.
> 
> The documentation should clearly document what this command is supposed,
> currently it only tells me "maintain/lose link" and does not specify in
> detail what this is supposed to do. Also there's no mention in what
> modes this can be used. (STA, P2P?)
> 

Ok I will send a new patch with updated description.

> Also please refrain from top posting in public mailing lists, the
> preferred way is to edit quotes and bottom post. It's much more natural
> way to have long detailed discussions.
> 

Sorry for that, I will refrain from top posting.

-- 
Alexei Lazar
Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc. 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2] cfg80211: add set/get link loss profile
  2016-11-18 11:05     ` Kalle Valo
  2016-12-19 10:58       ` Lazar, Alexei Avshalom
@ 2016-12-19 10:58       ` Lazar, Alexei Avshalom
  2016-12-20 17:00         ` Dan Williams
  1 sibling, 1 reply; 13+ messages in thread
From: Lazar, Alexei Avshalom @ 2016-12-19 10:58 UTC (permalink / raw)
  To: Kalle Valo; +Cc: johannes, linux-wireless, wil6210

>From 7e41d45179a8762a7d2e1653db35751c19c8c747 Mon Sep 17 00:00:00 2001
From: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
Date: Sun, 18 Dec 2016 15:06:38 +0200
Subject: [PATCH] cfg80211: add set/get link loss profile

Introduce NL80211_CMD_SET_LINK_LOSS_PROFILE and
NL80211_CMD_GET_LINK_LOSS_PROFILE needed by user space to configure the
link loss profile.
The link loss profile represents the priority of maintaining link up
(connection to AP) in different link quality environments.
This is intended for full mac80211 drivers. Typically link loss detection
is offloaded to firmware, since it requires close monitoring of the RF.
The firmware will disconnect when link quality drops.
There are scenarios that require to lose connection faster once reduced
link quality is detected in order to maintain better user experience.
This can be used in AP and station mode.
Example use case is FST (Fast Session Transfer), where we have a fast
11ad connection but close-range and a backup 11ac connection which is
"always on". In such cases if we detect poor link quality in the active
11ad band we prefer to disconnect and switch to the backup 11ac connection
with the good link quality. This will be reached by setting "aggressive"
profile that will cause more rapid disconnect in such cases.
Three types of behavior for link loss are defined:
LINK_LOSS_PROFILE_RELAXED: prefer maintaining link up even in a poor
link quality environment.
LINK_LOSS_PROFILE_DEFAULT: The default behavior for maintaining link
up vs link quality.
LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link up in a poor link
quality environment.
New cfg80211 API also been added, set/get_link_loss_profile.

Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
---
 drivers/net/wireless/ath/wil6210/cfg80211.c | 18 ++++++++
 include/net/cfg80211.h                      | 13 ++++++
 include/uapi/linux/nl80211.h                | 32 +++++++++++++
 net/wireless/nl80211.c                      | 70 +++++++++++++++++++++++++++++
 net/wireless/rdev-ops.h                     | 28 ++++++++++++
 net/wireless/trace.h                        | 39 ++++++++++++++++
 6 files changed, 200 insertions(+)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 6aa3ff4..681b792 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1499,6 +1499,22 @@ static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
 	return rc;
 }
 
+static int
+wil_cfg80211_set_link_loss_profile(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   enum nl80211_link_loss_profile profile,
+				   const u8 *addr)
+{
+	return -ENOTSUPP;
+}
+
+static enum nl80211_link_loss_profile
+wil_cfg80211_get_link_loss_profile(struct wiphy *wiphy,
+				   struct wireless_dev *wdev, const u8 *addr)
+{
+	return -ENOTSUPP;
+}
+
 static struct cfg80211_ops wil_cfg80211_ops = {
 	.add_virtual_intf = wil_cfg80211_add_iface,
 	.del_virtual_intf = wil_cfg80211_del_iface,
@@ -1528,6 +1544,8 @@ static struct cfg80211_ops wil_cfg80211_ops = {
 	.start_p2p_device = wil_cfg80211_start_p2p_device,
 	.stop_p2p_device = wil_cfg80211_stop_p2p_device,
 	.set_power_mgmt = wil_cfg80211_set_power_mgmt,
+	.set_link_loss_profile = wil_cfg80211_set_link_loss_profile,
+	.get_link_loss_profile = wil_cfg80211_get_link_loss_profile,
 };
 
 static void wil_wiphy_init(struct wiphy *wiphy)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ca2ac1c..7c2e420 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2764,6 +2764,10 @@ struct cfg80211_nan_func {
  *	All other parameters must be ignored.
  *
  * @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
+ *
+ * @set_link_loss_profile: Set link loss profile for specific connection.
+ * @get_link_loss_profile: Get the current link loss profile of specific
+ *	connection.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3048,6 +3052,15 @@ struct cfg80211_ops {
 	int	(*set_multicast_to_unicast)(struct wiphy *wiphy,
 					    struct net_device *dev,
 					    const bool enabled);
+
+	int	(*set_link_loss_profile)(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 enum nl80211_link_loss_profile profile,
+					 const u8 *addr);
+	enum nl80211_link_loss_profile	(*get_link_loss_profile)(
+					 struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const u8 *addr);
 };
 
 /*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index d74e10b..7723294 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -894,6 +894,11 @@
  *	does not result in a change for the current association. Currently,
  *	only the %NL80211_ATTR_IE data is used and updated with this command.
  *
+ * @NL80211_CMD_SET_LINK_LOSS_PROFILE: Set link loss profile (behavior) for
+ *	specific connection.
+ * @NL80211_CMD_GET_LINK_LOSS_PROFILE: Get current link loss profile of specific
+ *	connection.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1093,6 +1098,9 @@ enum nl80211_commands {
 
 	NL80211_CMD_UPDATE_CONNECT_PARAMS,
 
+	NL80211_CMD_SET_LINK_LOSS_PROFILE,
+	NL80211_CMD_GET_LINK_LOSS_PROFILE,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1980,6 +1988,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is also
  *	used in various commands/events for specifying the BSSID.
  *
+ * @NL80211_ATTR_LINK_LOSS_PROFILE: attribute that indicate the link loss
+ *	behavior using &enum nl80211_link_loss_profile values.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2386,6 +2397,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_BSSID,
 
+	NL80211_ATTR_LINK_LOSS_PROFILE,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -5188,4 +5201,23 @@ enum nl80211_nan_match_attributes {
 	NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
 };
 
+/**
+ * enum nl80211_link_loss_profile.
+ *
+ * Used by set_link_loss_profile() and get_link_loss_profile()
+ * to set/get link loss behavior.
+ *
+ * @NL80211_LINK_LOSS_PROFILE_RELAXED: prefer maintaining link
+ *	up even in poor link quality environment
+ * @NL80211_LINK_LOSS_PROFILE_DEFAULT: The default behavior for
+ *	maintaining link up vs link quality.
+ * @NL80211_LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link
+ *	up in poor link quality environment
+ */
+enum nl80211_link_loss_profile {
+	NL80211_LINK_LOSS_PROFILE_RELAXED,
+	NL80211_LINK_LOSS_PROFILE_DEFAULT,
+	NL80211_LINK_LOSS_PROFILE_AGGRESSIVE
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2369265..e160630 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -405,6 +405,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
 	[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
 	[NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
+	[NL80211_ATTR_LINK_LOSS_PROFILE] = { .type = NLA_U8 },
 };
 
 /* policy for the key attributes */
@@ -11817,6 +11818,60 @@ static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
 	return rdev_set_multicast_to_unicast(rdev, dev, enabled);
 }
 
+static int nl80211_set_link_loss_profile(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_link_loss_profile profile;
+	const u8 *addr;
+	int ret;
+
+	if (!info->attrs[NL80211_ATTR_LINK_LOSS_PROFILE] ||
+	    !info->attrs[NL80211_ATTR_MAC])
+		return -EINVAL;
+
+	profile = nla_get_u8(info->attrs[NL80211_ATTR_LINK_LOSS_PROFILE]);
+	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+	if (profile != NL80211_LINK_LOSS_PROFILE_RELAXED &&
+	    profile != NL80211_LINK_LOSS_PROFILE_DEFAULT &&
+	    profile != NL80211_LINK_LOSS_PROFILE_AGGRESSIVE)
+		return -EINVAL;
+
+	if (!rdev->ops->set_link_loss_profile)
+		return -EOPNOTSUPP;
+
+	wdev_lock(wdev);
+	ret = rdev_set_link_loss_profile(rdev, wdev, profile, addr);
+	wdev_unlock(wdev);
+
+	return ret;
+}
+
+static int nl80211_get_link_loss_profile(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];
+	const u8 *addr;
+	enum nl80211_link_loss_profile profile;
+
+	if (!info->attrs[NL80211_ATTR_MAC])
+		return -EINVAL;
+
+	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+	if (!rdev->ops->get_link_loss_profile)
+		return -EOPNOTSUPP;
+
+	wdev_lock(wdev);
+	profile = rdev_get_link_loss_profile(rdev, wdev, addr);
+	wdev_unlock(wdev);
+
+	return profile;
+}
+
 #define NL80211_FLAG_NEED_WIPHY		0x01
 #define NL80211_FLAG_NEED_NETDEV	0x02
 #define NL80211_FLAG_NEED_RTNL		0x04
@@ -12692,6 +12747,21 @@ static const struct genl_ops nl80211_ops[] = {
 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
 				  NL80211_FLAG_NEED_RTNL,
 	},
+	{
+	.cmd = NL80211_CMD_SET_LINK_LOSS_PROFILE,
+		.doit = nl80211_set_link_loss_profile,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
+	.cmd = NL80211_CMD_GET_LINK_LOSS_PROFILE,
+		.doit = nl80211_get_link_loss_profile,
+		.policy = nl80211_policy,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 2f42507..caf0127 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1153,4 +1153,32 @@ rdev_set_coalesce(struct cfg80211_registered_device *rdev,
 	trace_rdev_return_int(&rdev->wiphy, ret);
 	return ret;
 }
+
+static inline int
+rdev_set_link_loss_profile(struct cfg80211_registered_device *rdev,
+			   struct wireless_dev *wdev,
+			   enum nl80211_link_loss_profile profile,
+			   const u8 *addr)
+{
+	int ret;
+
+	trace_rdev_set_link_loss_profile(&rdev->wiphy, wdev, profile, addr);
+	ret = rdev->ops->set_link_loss_profile(&rdev->wiphy, wdev, profile,
+					       addr);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
+static inline enum nl80211_link_loss_profile
+rdev_get_link_loss_profile(struct cfg80211_registered_device *rdev,
+			   struct wireless_dev *wdev,
+			   const u8 *addr)
+{
+	enum nl80211_link_loss_profile profile;
+
+	trace_rdev_get_link_loss_profile(&rdev->wiphy, wdev, addr);
+	profile = rdev->ops->get_link_loss_profile(&rdev->wiphy, wdev, addr);
+	trace_rdev_return_int(&rdev->wiphy, profile);
+	return profile;
+}
 #endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ea1b47e..3af813b 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2230,6 +2230,45 @@ TRACE_EVENT(rdev_tdls_cancel_channel_switch,
 		  WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr))
 );
 
+TRACE_EVENT(rdev_set_link_loss_profile,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 enum nl80211_link_loss_profile profile, const u8 *addr),
+	TP_ARGS(wiphy, wdev, profile, addr),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		__field(enum nl80211_link_loss_profile, profile)
+		MAC_ENTRY(addr)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		__entry->profile = profile;
+		MAC_ASSIGN(addr, addr);
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " MAC_PR_FMT ", PROFILE %d",
+		  WIPHY_PR_ARG, WDEV_PR_ARG, MAC_PR_ARG(addr),
+		  __entry->profile)
+);
+
+TRACE_EVENT(rdev_get_link_loss_profile,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 const u8 *addr),
+	TP_ARGS(wiphy, wdev, addr),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		MAC_ENTRY(addr)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		MAC_ASSIGN(addr, addr);
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " MAC_PR_FMT, WIPHY_PR_ARG,
+		  WDEV_PR_ARG, MAC_PR_ARG(addr))
+);
+
 /*************************************************************
  *	     cfg80211 exported functions traces		     *
  *************************************************************/
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] cfg80211: add set/get link loss profile
  2016-12-19 10:58       ` [PATCH v2] " Lazar, Alexei Avshalom
@ 2016-12-20 17:00         ` Dan Williams
  2017-03-06 13:54           ` [PATCH v3] " Lazar, Alexei Avshalom
  0 siblings, 1 reply; 13+ messages in thread
From: Dan Williams @ 2016-12-20 17:00 UTC (permalink / raw)
  To: Lazar, Alexei Avshalom, Kalle Valo; +Cc: johannes, linux-wireless, wil6210

On Mon, 2016-12-19 at 12:58 +0200, Lazar, Alexei Avshalom wrote:
> From 7e41d45179a8762a7d2e1653db35751c19c8c747 Mon Sep 17 00:00:00
> 2001
> From: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
> Date: Sun, 18 Dec 2016 15:06:38 +0200
> Subject: [PATCH] cfg80211: add set/get link loss profile
> 
> Introduce NL80211_CMD_SET_LINK_LOSS_PROFILE and
> NL80211_CMD_GET_LINK_LOSS_PROFILE needed by user space to configure
> the
> link loss profile.
> The link loss profile represents the priority of maintaining link up
> (connection to AP) in different link quality environments.
> This is intended for full mac80211 drivers. Typically link loss
> detection
> is offloaded to firmware, since it requires close monitoring of the
> RF.
> The firmware will disconnect when link quality drops.
> There are scenarios that require to lose connection faster once
> reduced
> link quality is detected in order to maintain better user experience.
> This can be used in AP and station mode.
> Example use case is FST (Fast Session Transfer), where we have a fast
> 11ad connection but close-range and a backup 11ac connection which is
> "always on". In such cases if we detect poor link quality in the
> active
> 11ad band we prefer to disconnect and switch to the backup 11ac
> connection
> with the good link quality. This will be reached by setting
> "aggressive"
> profile that will cause more rapid disconnect in such cases.
> Three types of behavior for link loss are defined:
> LINK_LOSS_PROFILE_RELAXED: prefer maintaining link up even in a poor
> link quality environment.
> LINK_LOSS_PROFILE_DEFAULT: The default behavior for maintaining link
> up vs link quality.
> LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link up in a poor link
> quality environment.
> New cfg80211 API also been added, set/get_link_loss_profile.

Still need to address Kalle's comments requesting more detailed
explanation of these.  What do each of these actually mean?  What does
"poor link quality" mean?  Is it based on dBm, noise floor, SNR, etc?
 Is it a windowed average or something?  There's way too many details
left out here for userspace to reliably use this API, especially with
different drivers.

Also need to address Kalle's comment about what modes these are
relevant in, and what differences there are here between modes.

Dan

> Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
> ---
>  drivers/net/wireless/ath/wil6210/cfg80211.c | 18 ++++++++
>  include/net/cfg80211.h                      | 13 ++++++
>  include/uapi/linux/nl80211.h                | 32 +++++++++++++
>  net/wireless/nl80211.c                      | 70
> +++++++++++++++++++++++++++++
>  net/wireless/rdev-ops.h                     | 28 ++++++++++++
>  net/wireless/trace.h                        | 39 ++++++++++++++++
>  6 files changed, 200 insertions(+)
> 
> diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c
> b/drivers/net/wireless/ath/wil6210/cfg80211.c
> index 6aa3ff4..681b792 100644
> --- a/drivers/net/wireless/ath/wil6210/cfg80211.c
> +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
> @@ -1499,6 +1499,22 @@ static int wil_cfg80211_set_power_mgmt(struct
> wiphy *wiphy,
>  	return rc;
>  }
>  
> +static int
> +wil_cfg80211_set_link_loss_profile(struct wiphy *wiphy,
> +				   struct wireless_dev *wdev,
> +				   enum nl80211_link_loss_profile
> profile,
> +				   const u8 *addr)
> +{
> +	return -ENOTSUPP;
> +}
> +
> +static enum nl80211_link_loss_profile
> +wil_cfg80211_get_link_loss_profile(struct wiphy *wiphy,
> +				   struct wireless_dev *wdev, const
> u8 *addr)
> +{
> +	return -ENOTSUPP;
> +}
> +
>  static struct cfg80211_ops wil_cfg80211_ops = {
>  	.add_virtual_intf = wil_cfg80211_add_iface,
>  	.del_virtual_intf = wil_cfg80211_del_iface,
> @@ -1528,6 +1544,8 @@ static struct cfg80211_ops wil_cfg80211_ops = {
>  	.start_p2p_device = wil_cfg80211_start_p2p_device,
>  	.stop_p2p_device = wil_cfg80211_stop_p2p_device,
>  	.set_power_mgmt = wil_cfg80211_set_power_mgmt,
> +	.set_link_loss_profile = wil_cfg80211_set_link_loss_profile,
> +	.get_link_loss_profile = wil_cfg80211_get_link_loss_profile,
>  };
>  
>  static void wil_wiphy_init(struct wiphy *wiphy)
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index ca2ac1c..7c2e420 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -2764,6 +2764,10 @@ struct cfg80211_nan_func {
>   *	All other parameters must be ignored.
>   *
>   * @set_multicast_to_unicast: configure multicast to unicast
> conversion for BSS
> + *
> + * @set_link_loss_profile: Set link loss profile for specific
> connection.
> + * @get_link_loss_profile: Get the current link loss profile of
> specific
> + *	connection.
>   */
>  struct cfg80211_ops {
>  	int	(*suspend)(struct wiphy *wiphy, struct
> cfg80211_wowlan *wow);
> @@ -3048,6 +3052,15 @@ struct cfg80211_ops {
>  	int	(*set_multicast_to_unicast)(struct wiphy *wiphy,
>  					    struct net_device *dev,
>  					    const bool enabled);
> +
> +	int	(*set_link_loss_profile)(struct wiphy *wiphy,
> +					 struct wireless_dev *wdev,
> +					 enum
> nl80211_link_loss_profile profile,
> +					 const u8 *addr);
> +	enum nl80211_link_loss_profile	(*get_link_loss_profil
> e)(
> +					 struct wiphy *wiphy,
> +					 struct wireless_dev *wdev,
> +					 const u8 *addr);
>  };
>  
>  /*
> diff --git a/include/uapi/linux/nl80211.h
> b/include/uapi/linux/nl80211.h
> index d74e10b..7723294 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -894,6 +894,11 @@
>   *	does not result in a change for the current association.
> Currently,
>   *	only the %NL80211_ATTR_IE data is used and updated with
> this command.
>   *
> + * @NL80211_CMD_SET_LINK_LOSS_PROFILE: Set link loss profile
> (behavior) for
> + *	specific connection.
> + * @NL80211_CMD_GET_LINK_LOSS_PROFILE: Get current link loss profile
> of specific
> + *	connection.
> + *
>   * @NL80211_CMD_MAX: highest used command number
>   * @__NL80211_CMD_AFTER_LAST: internal use
>   */
> @@ -1093,6 +1098,9 @@ enum nl80211_commands {
>  
>  	NL80211_CMD_UPDATE_CONNECT_PARAMS,
>  
> +	NL80211_CMD_SET_LINK_LOSS_PROFILE,
> +	NL80211_CMD_GET_LINK_LOSS_PROFILE,
> +
>  	/* add new commands above here */
>  
>  	/* used to define NL80211_CMD_MAX below */
> @@ -1980,6 +1988,9 @@ enum nl80211_commands {
>   * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that
> %NL80211_ATTR_MAC is also
>   *	used in various commands/events for specifying the BSSID.
>   *
> + * @NL80211_ATTR_LINK_LOSS_PROFILE: attribute that indicate the link
> loss
> + *	behavior using &enum nl80211_link_loss_profile values.
> + *
>   * @NUM_NL80211_ATTR: total number of nl80211_attrs available
>   * @NL80211_ATTR_MAX: highest attribute number currently defined
>   * @__NL80211_ATTR_AFTER_LAST: internal use
> @@ -2386,6 +2397,8 @@ enum nl80211_attrs {
>  
>  	NL80211_ATTR_BSSID,
>  
> +	NL80211_ATTR_LINK_LOSS_PROFILE,
> +
>  	/* add attributes here, update the policy in nl80211.c */
>  
>  	__NL80211_ATTR_AFTER_LAST,
> @@ -5188,4 +5201,23 @@ enum nl80211_nan_match_attributes {
>  	NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
>  };
>  
> +/**
> + * enum nl80211_link_loss_profile.
> + *
> + * Used by set_link_loss_profile() and get_link_loss_profile()
> + * to set/get link loss behavior.
> + *
> + * @NL80211_LINK_LOSS_PROFILE_RELAXED: prefer maintaining link
> + *	up even in poor link quality environment
> + * @NL80211_LINK_LOSS_PROFILE_DEFAULT: The default behavior for
> + *	maintaining link up vs link quality.
> + * @NL80211_LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link
> + *	up in poor link quality environment
> + */
> +enum nl80211_link_loss_profile {
> +	NL80211_LINK_LOSS_PROFILE_RELAXED,
> +	NL80211_LINK_LOSS_PROFILE_DEFAULT,
> +	NL80211_LINK_LOSS_PROFILE_AGGRESSIVE
> +};
> +
>  #endif /* __LINUX_NL80211_H */
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 2369265..e160630 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -405,6 +405,7 @@ static const struct nla_policy
> nl80211_policy[NUM_NL80211_ATTR] = {
>  	[NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
>  	[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type =
> NLA_FLAG, },
>  	[NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
> +	[NL80211_ATTR_LINK_LOSS_PROFILE] = { .type = NLA_U8 },
>  };
>  
>  /* policy for the key attributes */
> @@ -11817,6 +11818,60 @@ static int
> nl80211_set_multicast_to_unicast(struct sk_buff *skb,
>  	return rdev_set_multicast_to_unicast(rdev, dev, enabled);
>  }
>  
> +static int nl80211_set_link_loss_profile(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_link_loss_profile profile;
> +	const u8 *addr;
> +	int ret;
> +
> +	if (!info->attrs[NL80211_ATTR_LINK_LOSS_PROFILE] ||
> +	    !info->attrs[NL80211_ATTR_MAC])
> +		return -EINVAL;
> +
> +	profile = nla_get_u8(info-
> >attrs[NL80211_ATTR_LINK_LOSS_PROFILE]);
> +	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
> +
> +	if (profile != NL80211_LINK_LOSS_PROFILE_RELAXED &&
> +	    profile != NL80211_LINK_LOSS_PROFILE_DEFAULT &&
> +	    profile != NL80211_LINK_LOSS_PROFILE_AGGRESSIVE)
> +		return -EINVAL;
> +
> +	if (!rdev->ops->set_link_loss_profile)
> +		return -EOPNOTSUPP;
> +
> +	wdev_lock(wdev);
> +	ret = rdev_set_link_loss_profile(rdev, wdev, profile, addr);
> +	wdev_unlock(wdev);
> +
> +	return ret;
> +}
> +
> +static int nl80211_get_link_loss_profile(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];
> +	const u8 *addr;
> +	enum nl80211_link_loss_profile profile;
> +
> +	if (!info->attrs[NL80211_ATTR_MAC])
> +		return -EINVAL;
> +
> +	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
> +
> +	if (!rdev->ops->get_link_loss_profile)
> +		return -EOPNOTSUPP;
> +
> +	wdev_lock(wdev);
> +	profile = rdev_get_link_loss_profile(rdev, wdev, addr);
> +	wdev_unlock(wdev);
> +
> +	return profile;
> +}
> +
>  #define NL80211_FLAG_NEED_WIPHY		0x01
>  #define NL80211_FLAG_NEED_NETDEV	0x02
>  #define NL80211_FLAG_NEED_RTNL		0x04
> @@ -12692,6 +12747,21 @@ static const struct genl_ops nl80211_ops[] =
> {
>  		.internal_flags = NL80211_FLAG_NEED_NETDEV |
>  				  NL80211_FLAG_NEED_RTNL,
>  	},
> +	{
> +	.cmd = NL80211_CMD_SET_LINK_LOSS_PROFILE,
> +		.doit = nl80211_set_link_loss_profile,
> +		.policy = nl80211_policy,
> +		.flags = GENL_ADMIN_PERM,
> +		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
> +				  NL80211_FLAG_NEED_RTNL,
> +	},
> +	{
> +	.cmd = NL80211_CMD_GET_LINK_LOSS_PROFILE,
> +		.doit = nl80211_get_link_loss_profile,
> +		.policy = nl80211_policy,
> +		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
> +				  NL80211_FLAG_NEED_RTNL,
> +	},
>  };
>  
>  static struct genl_family nl80211_fam __ro_after_init = {
> diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
> index 2f42507..caf0127 100644
> --- a/net/wireless/rdev-ops.h
> +++ b/net/wireless/rdev-ops.h
> @@ -1153,4 +1153,32 @@ rdev_set_coalesce(struct
> cfg80211_registered_device *rdev,
>  	trace_rdev_return_int(&rdev->wiphy, ret);
>  	return ret;
>  }
> +
> +static inline int
> +rdev_set_link_loss_profile(struct cfg80211_registered_device *rdev,
> +			   struct wireless_dev *wdev,
> +			   enum nl80211_link_loss_profile profile,
> +			   const u8 *addr)
> +{
> +	int ret;
> +
> +	trace_rdev_set_link_loss_profile(&rdev->wiphy, wdev,
> profile, addr);
> +	ret = rdev->ops->set_link_loss_profile(&rdev->wiphy, wdev,
> profile,
> +					       addr);
> +	trace_rdev_return_int(&rdev->wiphy, ret);
> +	return ret;
> +}
> +
> +static inline enum nl80211_link_loss_profile
> +rdev_get_link_loss_profile(struct cfg80211_registered_device *rdev,
> +			   struct wireless_dev *wdev,
> +			   const u8 *addr)
> +{
> +	enum nl80211_link_loss_profile profile;
> +
> +	trace_rdev_get_link_loss_profile(&rdev->wiphy, wdev, addr);
> +	profile = rdev->ops->get_link_loss_profile(&rdev->wiphy,
> wdev, addr);
> +	trace_rdev_return_int(&rdev->wiphy, profile);
> +	return profile;
> +}
>  #endif /* __CFG80211_RDEV_OPS */
> diff --git a/net/wireless/trace.h b/net/wireless/trace.h
> index ea1b47e..3af813b 100644
> --- a/net/wireless/trace.h
> +++ b/net/wireless/trace.h
> @@ -2230,6 +2230,45 @@ TRACE_EVENT(rdev_tdls_cancel_channel_switch,
>  		  WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr))
>  );
>  
> +TRACE_EVENT(rdev_set_link_loss_profile,
> +	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
> +		 enum nl80211_link_loss_profile profile, const u8
> *addr),
> +	TP_ARGS(wiphy, wdev, profile, addr),
> +	TP_STRUCT__entry(
> +		WIPHY_ENTRY
> +		WDEV_ENTRY
> +		__field(enum nl80211_link_loss_profile, profile)
> +		MAC_ENTRY(addr)
> +	),
> +	TP_fast_assign(
> +		WIPHY_ASSIGN;
> +		WDEV_ASSIGN;
> +		__entry->profile = profile;
> +		MAC_ASSIGN(addr, addr);
> +	),
> +	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " MAC_PR_FMT ",
> PROFILE %d",
> +		  WIPHY_PR_ARG, WDEV_PR_ARG, MAC_PR_ARG(addr),
> +		  __entry->profile)
> +);
> +
> +TRACE_EVENT(rdev_get_link_loss_profile,
> +	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
> +		 const u8 *addr),
> +	TP_ARGS(wiphy, wdev, addr),
> +	TP_STRUCT__entry(
> +		WIPHY_ENTRY
> +		WDEV_ENTRY
> +		MAC_ENTRY(addr)
> +	),
> +	TP_fast_assign(
> +		WIPHY_ASSIGN;
> +		WDEV_ASSIGN;
> +		MAC_ASSIGN(addr, addr);
> +	),
> +	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " MAC_PR_FMT,
> WIPHY_PR_ARG,
> +		  WDEV_PR_ARG, MAC_PR_ARG(addr))
> +);
> +
>  /*************************************************************
>   *	     cfg80211 exported functions traces		   
>   *
>   *************************************************************/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: cfg80211: add set/get link loss profile
  2016-12-19 10:58   ` Lazar, Alexei Avshalom
@ 2017-01-02 10:45     ` Johannes Berg
  2017-03-06 13:54       ` Lazar, Alexei Avshalom
  0 siblings, 1 reply; 13+ messages in thread
From: Johannes Berg @ 2017-01-02 10:45 UTC (permalink / raw)
  To: Lazar, Alexei Avshalom; +Cc: linux-wireless, wil6210

On Mon, 2016-12-19 at 12:58 +0200, Lazar, Alexei Avshalom wrote:

> > What you're doing here is *extremely* vague. No definitions of what
> > this means, no description of how it's intended to be implemented,
> > no note even on whether or not this is for full-MAC chips or not,
> > etc.
> > 
> 
> The patch is intended for full-MAC chips and I will update the commit
> message to include more details.
> 
> > At least for mac80211, we can define signals to userspace regarding
> > "link quality" and make decisions in wpa_s then?
> > 
> 
> The policy is offloaded today to the FW and the decision being made
> by the FW.
> We are only modifying the behavior and not making the decision.

Fair enough, but I stand by saying that it's extremely vague - how
could userspace possibly know what "level" to pick, if you don't give
it any information about what the levels really mean?

johannes

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: cfg80211: add set/get link loss profile
  2017-01-02 10:45     ` Johannes Berg
@ 2017-03-06 13:54       ` Lazar, Alexei Avshalom
  0 siblings, 0 replies; 13+ messages in thread
From: Lazar, Alexei Avshalom @ 2017-03-06 13:54 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, wil6210

On 1/2/2017 12:45 PM, Johannes Berg wrote:
> On Mon, 2016-12-19 at 12:58 +0200, Lazar, Alexei Avshalom wrote:
> 
>>> What you're doing here is *extremely* vague. No definitions of what
>>> this means, no description of how it's intended to be implemented,
>>> no note even on whether or not this is for full-MAC chips or not,
>>> etc.
>>>
>>
>> The patch is intended for full-MAC chips and I will update the commit
>> message to include more details.
>>
>>> At least for mac80211, we can define signals to userspace regarding
>>> "link quality" and make decisions in wpa_s then?
>>>
>>
>> The policy is offloaded today to the FW and the decision being made
>> by the FW.
>> We are only modifying the behavior and not making the decision.
> 
> Fair enough, but I stand by saying that it's extremely vague - how
> could userspace possibly know what "level" to pick, if you don't give
> it any information about what the levels really mean?
> 
> johannes
> 

I have updated the commit message for clarifying what the levels really mean.

-- 
Alexei Lazar
Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc. 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v3] cfg80211: add set/get link loss profile
  2016-12-20 17:00         ` Dan Williams
@ 2017-03-06 13:54           ` Lazar, Alexei Avshalom
  2017-03-29  9:01             ` Johannes Berg
  0 siblings, 1 reply; 13+ messages in thread
From: Lazar, Alexei Avshalom @ 2017-03-06 13:54 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo; +Cc: Dan Williams, linux-wireless, wil6210

>From ca61946032a47c8daf1b9013de9f4c72c6e7aaaf Mon Sep 17 00:00:00 2001
From: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
Date: Mon, 6 Mar 2017 15:47:08 +0200
Subject: [PATCH] cfg80211: add set/get link loss profile

Introduce NL80211_CMD_SET_LINK_LOSS_PROFILE and
NL80211_CMD_GET_LINK_LOSS_PROFILE needed by user space to configure the
link loss profile.
Link loss detection involves close monitoring of the RF link and can
consider dozens of factors like keep alive packets, missing ACKs and
beacons, SNR and so on.
This is why it is usually offloaded to firmware.
This API is intended as a hint to the firmware to decide when to
actually disconnect when potential link loss is detected.
The supported values are:
AGGRESSIVE: disconnect as soon as possible when potential link loss
is detected, even for a very short time (tens of milliseconds).
Choose this when you have a backup connection and you can automatically
switch to the other connection when link is disconnected, like FST
(fast session transfer).
This will keep the connection alive and prevent even short interruptions.
DEFAULT: the default behavior, can be different in each driver but
usually link is maintained for average amounts of time, typically few
seconds of potential link loss before actual disconnection.
User space can monitor the link using CQM notifications or other methods
and disconnect manually if needed.
RELAXED: maintain the link for a long time (typically one minute or more)
even if potential link loss is detected. Choose this if you want user
space to make the decision on when to disconnect

Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
---
 include/net/cfg80211.h       | 12 ++++++++
 include/uapi/linux/nl80211.h | 33 +++++++++++++++++++++
 net/wireless/nl80211.c       | 70 ++++++++++++++++++++++++++++++++++++++++++++
 net/wireless/rdev-ops.h      | 28 ++++++++++++++++++
 net/wireless/trace.h         | 39 ++++++++++++++++++++++++
 5 files changed, 182 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ffc0868..6b3bc33 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2821,6 +2821,10 @@ struct cfg80211_nan_func {
  *	All other parameters must be ignored.
  *
  * @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
+ *
+ * @set_link_loss_profile: Set link loss profile for specific connection.
+ * @get_link_loss_profile: Get the current link loss profile of specific
+ *	connection.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3109,6 +3113,14 @@ struct cfg80211_ops {
 	int	(*set_multicast_to_unicast)(struct wiphy *wiphy,
 					    struct net_device *dev,
 					    const bool enabled);
+	int	(*set_link_loss_profile)(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 enum nl80211_link_loss_profile profile,
+					 const u8 *addr);
+	enum nl80211_link_loss_profile	(*get_link_loss_profile)(
+					 struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const u8 *addr);
 };
 
 /*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9a499b1..485d670 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -901,6 +901,11 @@
  *	does not result in a change for the current association. Currently,
  *	only the %NL80211_ATTR_IE data is used and updated with this command.
  *
+ * @NL80211_CMD_SET_LINK_LOSS_PROFILE: Set link loss profile (behavior) for
+ *	specific connection.
+ * @NL80211_CMD_GET_LINK_LOSS_PROFILE: Get current link loss profile of specific
+ *	connection.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1100,6 +1105,9 @@ enum nl80211_commands {
 
 	NL80211_CMD_UPDATE_CONNECT_PARAMS,
 
+	NL80211_CMD_SET_LINK_LOSS_PROFILE,
+	NL80211_CMD_GET_LINK_LOSS_PROFILE,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -2013,6 +2021,10 @@ enum nl80211_commands {
  *	e.g., with %NL80211_CMD_CONNECT event.
  *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
+ *
+ * @NL80211_ATTR_LINK_LOSS_PROFILE: attribute that indicate the link loss
+ *	behavior using &enum nl80211_link_loss_profile values.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -2423,6 +2435,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_TIMEOUT_REASON,
 
+	NL80211_ATTR_LINK_LOSS_PROFILE,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -5254,4 +5268,23 @@ enum nl80211_nan_match_attributes {
 	NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
 };
 
+/**
+ * enum nl80211_link_loss_profile.
+ *
+ * Used by set_link_loss_profile() and get_link_loss_profile()
+ * to set/get link loss behavior.
+ *
+ * @NL80211_LINK_LOSS_PROFILE_RELAXED: prefer maintaining link
+ *	up even in poor link quality environment
+ * @NL80211_LINK_LOSS_PROFILE_DEFAULT: The default behavior for
+ *	maintaining link up vs link quality.
+ * @NL80211_LINK_LOSS_PROFILE_AGGRESSIVE: prefer losing link
+ *	up in poor link quality environment
+ */
+enum nl80211_link_loss_profile {
+	NL80211_LINK_LOSS_PROFILE_RELAXED,
+	NL80211_LINK_LOSS_PROFILE_DEFAULT,
+	NL80211_LINK_LOSS_PROFILE_AGGRESSIVE
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d516527..1ff90def 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -410,6 +410,7 @@ enum nl80211_multicast_groups {
 		.len = sizeof(struct nl80211_bss_select_rssi_adjust)
 	},
 	[NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
+	[NL80211_ATTR_LINK_LOSS_PROFILE] = { .type = NLA_U8 },
 };
 
 /* policy for the key attributes */
@@ -12067,6 +12068,60 @@ static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
 	return rdev_set_multicast_to_unicast(rdev, dev, enabled);
 }
 
+static int nl80211_set_link_loss_profile(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_link_loss_profile profile;
+	const u8 *addr;
+	int ret;
+
+	if (!info->attrs[NL80211_ATTR_LINK_LOSS_PROFILE] ||
+	    !info->attrs[NL80211_ATTR_MAC])
+		return -EINVAL;
+
+	profile = nla_get_u8(info->attrs[NL80211_ATTR_LINK_LOSS_PROFILE]);
+	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+	if (profile != NL80211_LINK_LOSS_PROFILE_RELAXED &&
+	    profile != NL80211_LINK_LOSS_PROFILE_DEFAULT &&
+	    profile != NL80211_LINK_LOSS_PROFILE_AGGRESSIVE)
+		return -EINVAL;
+
+	if (!rdev->ops->set_link_loss_profile)
+		return -EOPNOTSUPP;
+
+	wdev_lock(wdev);
+	ret = rdev_set_link_loss_profile(rdev, wdev, profile, addr);
+	wdev_unlock(wdev);
+
+	return ret;
+}
+
+static int nl80211_get_link_loss_profile(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];
+	const u8 *addr;
+	enum nl80211_link_loss_profile profile;
+
+	if (!info->attrs[NL80211_ATTR_MAC])
+		return -EINVAL;
+
+	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+	if (!rdev->ops->get_link_loss_profile)
+		return -EOPNOTSUPP;
+
+	wdev_lock(wdev);
+	profile = rdev_get_link_loss_profile(rdev, wdev, addr);
+	wdev_unlock(wdev);
+
+	return profile;
+}
+
 #define NL80211_FLAG_NEED_WIPHY		0x01
 #define NL80211_FLAG_NEED_NETDEV	0x02
 #define NL80211_FLAG_NEED_RTNL		0x04
@@ -12942,6 +12997,21 @@ static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
 				  NL80211_FLAG_NEED_RTNL,
 	},
+	{
+	.cmd = NL80211_CMD_SET_LINK_LOSS_PROFILE,
+		.doit = nl80211_set_link_loss_profile,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
+	.cmd = NL80211_CMD_GET_LINK_LOSS_PROFILE,
+		.doit = nl80211_get_link_loss_profile,
+		.policy = nl80211_policy,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index f2baf59..0caa9e4 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1165,4 +1165,32 @@ static inline int rdev_set_qos_map(struct cfg80211_registered_device *rdev,
 	trace_rdev_return_int(&rdev->wiphy, ret);
 	return ret;
 }
+
+static inline int
+rdev_set_link_loss_profile(struct cfg80211_registered_device *rdev,
+			   struct wireless_dev *wdev,
+			   enum nl80211_link_loss_profile profile,
+			   const u8 *addr)
+{
+	int ret;
+
+	trace_rdev_set_link_loss_profile(&rdev->wiphy, wdev, profile, addr);
+	ret = rdev->ops->set_link_loss_profile(&rdev->wiphy, wdev, profile,
+					       addr);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
+static inline enum nl80211_link_loss_profile
+rdev_get_link_loss_profile(struct cfg80211_registered_device *rdev,
+			   struct wireless_dev *wdev,
+			   const u8 *addr)
+{
+	enum nl80211_link_loss_profile profile;
+
+	trace_rdev_get_link_loss_profile(&rdev->wiphy, wdev, addr);
+	profile = rdev->ops->get_link_loss_profile(&rdev->wiphy, wdev, addr);
+	trace_rdev_return_int(&rdev->wiphy, profile);
+	return profile;
+}
 #endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index fd55786..a4635e4 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2252,6 +2252,45 @@
 		  WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr))
 );
 
+TRACE_EVENT(rdev_set_link_loss_profile,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 enum nl80211_link_loss_profile profile, const u8 *addr),
+	TP_ARGS(wiphy, wdev, profile, addr),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		__field(enum nl80211_link_loss_profile, profile)
+		MAC_ENTRY(addr)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		__entry->profile = profile;
+		MAC_ASSIGN(addr, addr);
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " MAC_PR_FMT ", PROFILE %d",
+		  WIPHY_PR_ARG, WDEV_PR_ARG, MAC_PR_ARG(addr),
+		  __entry->profile)
+);
+
+TRACE_EVENT(rdev_get_link_loss_profile,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 const u8 *addr),
+	TP_ARGS(wiphy, wdev, addr),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		MAC_ENTRY(addr)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		MAC_ASSIGN(addr, addr);
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " MAC_PR_FMT, WIPHY_PR_ARG,
+		  WDEV_PR_ARG, MAC_PR_ARG(addr))
+);
+
 /*************************************************************
  *	     cfg80211 exported functions traces		     *
  *************************************************************/
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v3] cfg80211: add set/get link loss profile
  2017-03-06 13:54           ` [PATCH v3] " Lazar, Alexei Avshalom
@ 2017-03-29  9:01             ` Johannes Berg
  0 siblings, 0 replies; 13+ messages in thread
From: Johannes Berg @ 2017-03-29  9:01 UTC (permalink / raw)
  To: Lazar, Alexei Avshalom, Kalle Valo; +Cc: Dan Williams, linux-wireless, wil6210

On Mon, 2017-03-06 at 15:54 +0200, Lazar, Alexei Avshalom wrote:
> 
> The supported values are:
[...]

Regardless of the documentation, I think this is a bit fishy. Why
bother with this to start with?

We once had two patches (that we ultimately gave up on) doing something
similar but simply letting userspace decide. This was centered on
mac80211's beacon loss "link loss detection", but could easily be
generalized a little bit more:

https://p.sipsolutions.net/3a594dead519b4b2.txt
https://p.sipsolutions.net/100ce7df53692daa.txt

Perhaps with some adjustments such an approach would be workable for
you?

johannes

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-03-29  9:01 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-10 11:33 cfg80211: add set/get link loss profile Lazar, Alexei Avshalom
2016-11-10 13:55 ` Kalle Valo
2016-11-17 13:50   ` Lazar, Alexei Avshalom
2016-11-18 11:05     ` Kalle Valo
2016-12-19 10:58       ` Lazar, Alexei Avshalom
2016-12-19 10:58       ` [PATCH v2] " Lazar, Alexei Avshalom
2016-12-20 17:00         ` Dan Williams
2017-03-06 13:54           ` [PATCH v3] " Lazar, Alexei Avshalom
2017-03-29  9:01             ` Johannes Berg
2016-11-28 14:52 ` Johannes Berg
2016-12-19 10:58   ` Lazar, Alexei Avshalom
2017-01-02 10:45     ` Johannes Berg
2017-03-06 13:54       ` Lazar, Alexei Avshalom

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.