This patchsets introduced new NL command and api to support
configuring txrate threshold for the connected stations and api to
notify userspace application upon crossing the configured txrate threshold.
This will be useful for the application which requires
station's current capability change information.
Tamizh chelvam (4):
cfg80211: Add support to configure station specific txrate threshold
mac80211: Add api to configure low and high txrate threshold
cfg80211: Add support to notify station's txrate crossing event
mac80211: Implement functionality to monitor txrate cross event for a
station
Note:
* This patchset rebased on top of below patchset
[PATCH 0/7] cfg80211/mac80211: Add support to configure and monitor rssi threshold
include/net/cfg80211.h | 26 ++++++++++++++
include/net/mac80211.h | 5 +++
include/uapi/linux/nl80211.h | 34 ++++++++++++++++++
net/mac80211/cfg.c | 36 +++++++++++++++++++
net/mac80211/sta_info.h | 17 +++++++++
net/mac80211/status.c | 40 +++++++++++++++++++++-
net/wireless/nl80211.c | 78 ++++++++++++++++++++++++++++++++++++++++++
net/wireless/rdev-ops.h | 17 +++++++++
net/wireless/trace.h | 50 +++++++++++++++++++++++++++
9 files changed, 302 insertions(+), 1 deletion(-)
--
1.7.9.5
Tamizh chelvam <[email protected]> writes:
> This patchsets introduced new NL command and api to support
> configuring txrate threshold for the connected stations and api to
> notify userspace application upon crossing the configured txrate threshold.
> This will be useful for the application which requires
> station's current capability change information.
What is the intended use case? Asking mostly out of curiosity :)
-Toke
Add support to configure station specific txrate threshold
to monitor variation in the txrate for a station. Configuration
is passed using NL80211_ATTR_STA_MON_LOW_TXRATE_THOLD and
NL80211_ATTR_STA_MON_HIGH_TXRATE_THOLD in NL80211_CMD_SET_STA_MON
command and the configuration will be represented in 100kbps.
This will be useful for the application like steering which requires
station's current capability.
Driver supporting this configuration feature should advertise
NL80211_EXT_FEATURE_STA_MON_TXRATE_CONFIG.
Signed-off-by: Tamizh chelvam <[email protected]>
---
include/net/cfg80211.h | 9 +++++++++
include/uapi/linux/nl80211.h | 34 ++++++++++++++++++++++++++++++++++
net/wireless/nl80211.c | 40 ++++++++++++++++++++++++++++++++++++++++
net/wireless/rdev-ops.h | 17 +++++++++++++++++
net/wireless/trace.h | 25 +++++++++++++++++++++++++
5 files changed, 125 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4c49cc5..5bf0000 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3035,6 +3035,10 @@ struct cfg80211_external_auth_params {
* The driver should advertise %NL80211_EXT_FEATURE_STA_MON_RSSI_LIST if
* this method is implemented. If it is provided then there's no point
* providing @set_sta_mon_rssi_config
+ * @set_sta_mon_txrate_config: Configure low and high TXRATE threshold in 100kbs
+ * for a connected station. The driver should(soon) send an event
+ * indicating the current attempted frame txrate level is above/below the
+ * configured threshold
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3348,6 +3352,11 @@ struct cfg80211_ops {
struct net_device *dev,
const u8 *addr,
s32 rssi_low, s32 rssi_high);
+ int (*set_sta_mon_txrate_config)(struct wiphy *wiphy,
+ struct net_device *dev,
+ const u8 *addr,
+ u32 low_txrate_thold,
+ u32 high_txrate_thold);
};
/*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 8e2a84b..c7ce475 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4301,6 +4301,15 @@ enum nl80211_ps_state {
* @NL80211_ATTR_STA_MON_RSSI_THRESHOLD_EVENT: RSSI threshold event
* @NL80211_ATTR_STA_MON_RSSI_LEVEL: the RSSI value in dBm that triggered the
* RSSI threshold event.
+ * @NL80211_ATTR_STA_MON_LOW_TXRATE_THOLD: TX_RATE threshold in 100kbps. This
+ * u32 attribute specifies the low txrate threshold. Event will be sent
+ * if the txrate for a station goes lesser than this threshold.
+ * @NL80211_ATTR_STA_MON_HIGH_TXRATE_THOLD: TX_RATE threshold in 100kbps. This
+ * u32 attribute specifies the upper txrate threshold. Event will be sent
+ * if the txrate for a station goes greater than this threshold.
+ * @NL80211_ATTR_STA_MON_TXRATE_THRESHOLD_EVENT: TX_RATE threshold cross event
+ * @NL80211_ATTR_STA_MON_TXRATE_LEVEL: TXRATE for a station in 100kbps that
+ * triggered the TX_RATE threshold cross event.
*/
enum nl80211_attr_sta_mon {
__NL80211_ATTR_STA_MON_INVALID,
@@ -4308,6 +4317,10 @@ enum nl80211_attr_sta_mon {
NL80211_ATTR_STA_MON_RSSI_HYST,
NL80211_ATTR_STA_MON_RSSI_THRESHOLD_EVENT,
NL80211_ATTR_STA_MON_RSSI_LEVEL,
+ NL80211_ATTR_STA_MON_LOW_TXRATE_THOLD,
+ NL80211_ATTR_STA_MON_HIGH_TXRATE_THOLD,
+ NL80211_ATTR_STA_MON_TXRATE_THRESHOLD_EVENT,
+ NL80211_ATTR_STA_MON_TXRATE_LEVEL,
/* keep last */
__NL80211_ATTR_STA_MON_AFTER_LAST,
@@ -4327,6 +4340,21 @@ enum nl80211_sta_mon_rssi_threshold_event {
};
/**
+ * enum nl80211_sta_mon_txrate_threshold_event - TX_RATE threshold event
+ * @NL80211_STA_MON_TXRATE_THRESHOLD_IN_RANGE: The TX_RATE level is in between
+ * low and high threshold
+ * @NL80211_STA_MON_TXRATE_THRESHOLD_EVENT_LOW: The TX_RATE level is lower than
+ * the configured threshold
+ * @NL80211_STA_MON_TXRATE_THRESHOLD_EVENT_HIGH: The TX_RATE is higher than the
+ * configured threshold
+ */
+enum nl80211_sta_mon_txrate_threshold_event {
+ NL80211_STA_MON_TXRATE_THRESHOLD_IN_RANGE,
+ NL80211_STA_MON_TXRATE_THRESHOLD_EVENT_LOW,
+ NL80211_STA_MON_TXRATE_THRESHOLD_EVENT_HIGH,
+};
+
+/**
* enum nl80211_attr_cqm - connection quality monitor attributes
* @__NL80211_ATTR_CQM_INVALID: invalid
* @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies
@@ -5191,6 +5219,11 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_STA_MON_RSSI_LIST: With this driver the
* %NL80211_ATTR_STA_MON_RSSI_THOLD attribute accepts a list of zero or
* more RSSI threshold values to monitor rather than exactly one threshold.
+ * @NL80211_EXT_FEATURE_STA_MON_TXRATE_CONFIG: With this driver will accept
+ * %NL80211_ATTR_STA_MON_LOW_TXRATE_THOLD attribute as low txrate and
+ * %NL80211_ATTR_STA_MON_HIGH_TXRATE_THOLD attribute as high txrate
+ * for AP/AP_VLAN/P2P_GO interface to monitor txrate for the connected
+ * stations and the drvier should advertise txrate via ieee80211_tx_status.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5227,6 +5260,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_TXQS,
NL80211_EXT_FEATURE_STA_MON_RSSI_CONFIG,
NL80211_EXT_FEATURE_STA_MON_RSSI_LIST,
+ NL80211_EXT_FEATURE_STA_MON_TXRATE_CONFIG,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c0fccb4..31680d6 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -10138,6 +10138,10 @@ static int nl80211_set_cqm_txe(struct genl_info *info,
[NL80211_ATTR_STA_MON_RSSI_HYST] = { .type = NLA_U32 },
[NL80211_ATTR_STA_MON_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
[NL80211_ATTR_STA_MON_RSSI_LEVEL] = { .type = NLA_S32 },
+ [NL80211_ATTR_STA_MON_LOW_TXRATE_THOLD] = { .type = NLA_U32 },
+ [NL80211_ATTR_STA_MON_HIGH_TXRATE_THOLD] = { .type = NLA_U32 },
+ [NL80211_ATTR_STA_MON_TXRATE_THRESHOLD_EVENT] = { .type = NLA_U32 },
+ [NL80211_ATTR_STA_MON_TXRATE_LEVEL] = { .type = NLA_U32 },
};
static int cfg80211_set_rssi_range(struct cfg80211_registered_device *rdev,
@@ -13016,6 +13020,27 @@ static int nl80211_set_sta_mon_rssi(struct genl_info *info,
return err;
}
+static int nl80211_set_sta_mon_txrate(struct genl_info *info, const u8 *addr,
+ u32 low_thold, u32 high_thold)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (!rdev->ops->set_sta_mon_txrate_config)
+ return -EOPNOTSUPP;
+
+ if ((wdev->iftype != NL80211_IFTYPE_AP &&
+ wdev->iftype != NL80211_IFTYPE_P2P_GO &&
+ wdev->iftype != NL80211_IFTYPE_AP_VLAN) ||
+ (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_STA_MON_TXRATE_CONFIG)))
+ return -EOPNOTSUPP;
+
+ return rdev_set_sta_mon_txrate_config(rdev, dev, addr, low_thold,
+ high_thold);
+}
+
static int nl80211_sta_mon(struct sk_buff *skb, struct genl_info *info)
{
struct nlattr *attrs[NL80211_ATTR_STA_MON_MAX + 1];
@@ -13049,6 +13074,21 @@ static int nl80211_sta_mon(struct sk_buff *skb, struct genl_info *info)
return nl80211_set_sta_mon_rssi(info, addr, tholds, len / 4,
hysteresis);
}
+
+ if (attrs[NL80211_ATTR_STA_MON_LOW_TXRATE_THOLD] &&
+ attrs[NL80211_ATTR_STA_MON_HIGH_TXRATE_THOLD]) {
+ u32 low_thold =
+ nla_get_u32(attrs[NL80211_ATTR_STA_MON_LOW_TXRATE_THOLD]);
+ u32 high_thold =
+ nla_get_u32(attrs[NL80211_ATTR_STA_MON_HIGH_TXRATE_THOLD]);
+
+ if (low_thold > high_thold)
+ return -EINVAL;
+
+ return nl80211_set_sta_mon_txrate(info, addr, low_thold,
+ high_thold);
+ }
+
return -EINVAL;
}
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 1184e4a..1fc5089 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1263,4 +1263,21 @@ static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
return ret;
}
+static inline int
+rdev_set_sta_mon_txrate_config(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, const u8 *peer,
+ u32 low_txrate_thold, u32 high_txrate_thold)
+{
+ int ret;
+
+ trace_rdev_set_sta_mon_txrate_config(&rdev->wiphy, dev, peer,
+ low_txrate_thold,
+ high_txrate_thold);
+ ret = rdev->ops->set_sta_mon_txrate_config(&rdev->wiphy, dev, peer,
+ low_txrate_thold,
+ high_txrate_thold);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 76c422c..ca985c2 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -3330,6 +3330,31 @@
NETDEV_PR_ARG, MAC_PR_ARG(peer),
__entry->rssi_event, __entry->rssi_level)
);
+
+TRACE_EVENT(rdev_set_sta_mon_txrate_config,
+ TP_PROTO(struct wiphy *wiphy,
+ struct net_device *netdev, const u8 *peer,
+ u32 low_txrate_thold, u32 high_txrate_thold),
+ TP_ARGS(wiphy, netdev, peer, low_txrate_thold, high_txrate_thold),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(peer)
+ __field(u32, low_txrate_thold)
+ __field(u32, high_txrate_thold)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(peer, peer);
+ __entry->low_txrate_thold = low_txrate_thold;
+ __entry->high_txrate_thold = high_txrate_thold;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT
+ ", low_txrate_thold: %u, high_txrate_thold: %u ",
+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
+ __entry->low_txrate_thold, __entry->high_txrate_thold)
+);
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
--
1.7.9.5
> +static void ieee80211_sta_mon_txrate_thold_check(struct sta_info *sta)
> +{
> + struct rate_info rinfo;
> + enum nl80211_sta_mon_txrate_threshold_event sta_txrate_event;
> + int txrate;
> +
> + if (!sta->txrate_high)
> + return;
> +
> + sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
> + txrate = cfg80211_calculate_bitrate(&rinfo);
These are quite expensive calculations, I think this is far too much to
do on every packet.
You need to find a way to do most of the calculations at configure time,
e.g. build a table of MCS configurations this station might use, and
mark bits in there that fall above/below the threshold, or something
like that?
johannes
Trigger cfg80211_sta_mon_txrate_notify with the corresponding txrate
event when the txrate for a station goes out of configured range.
This event will be useful for the application like steering to take
decision on any station depends on its current capability.
Signed-off-by: Tamizh chelvam <[email protected]>
---
include/net/mac80211.h | 5 +++++
net/mac80211/cfg.c | 1 +
net/mac80211/sta_info.h | 10 ++++++++++
net/mac80211/status.c | 40 +++++++++++++++++++++++++++++++++++++++-
4 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 96fb9a8..02714ea 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -808,6 +808,11 @@ enum mac80211_rate_control_flags {
*/
#define IEEE80211_STA_SIGNAL_AVE_MIN_COUNT 4
+/* Number of txrate count need to have been used in average station's
+ * txrate before checking against the threshold
+ */
+#define IEEE80211_STA_TXRATE_AVE_MIN_COUNT 4
+
/* there are 40 bytes if you don't need the rateset to be kept */
#define IEEE80211_TX_INFO_DRIVER_DATA_SIZE 40
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 649f5c7..36ec5fb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3904,6 +3904,7 @@ static int ieee80211_set_sta_mon_txrate_config(struct wiphy *wiphy,
sta->txrate_low = low_txrate_thold;
sta->txrate_high = high_txrate_thold;
+ sta->last_txrate_event = 0;
unlock:
mutex_unlock(&sdata->local->sta_mtx);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index a71f50c..f978e5a 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -419,6 +419,8 @@ struct ieee80211_sta_rx_stats {
*/
#define STA_SLOW_THRESHOLD 6000 /* 6 Mbps */
+DECLARE_EWMA(sta_txrate, 4, 4)
+
/**
* struct sta_info - STA information
*
@@ -501,6 +503,11 @@ struct ieee80211_sta_rx_stats {
* in 100Kbps
* @txrate_high: TXRATE upper threshold for a station to monitor, this will be
* in 100Kbps
+ * @count_sta_txrate: Number of transmitted data frames used in ave_sta_txrate
+ * @last_txrate_event: Last txrate event that triggered sta_mon event for a
+ * station
+ * @ave_sta_txrate: Average txrate to check against the txrate_low and
+ * txrate_high. Values expressed in 100kbps
*/
struct sta_info {
/* General information, mostly static */
@@ -611,6 +618,9 @@ struct sta_info {
u32 txrate_low;
u32 txrate_high;
+ unsigned int count_sta_txrate;
+ enum nl80211_sta_mon_txrate_threshold_event last_txrate_event;
+ struct ewma_sta_txrate ave_sta_txrate;
/* keep last! */
struct ieee80211_sta sta;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 9a6d720..112b18d 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -701,6 +701,40 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
dev_kfree_skb(skb);
}
+static void ieee80211_sta_mon_txrate_thold_check(struct sta_info *sta)
+{
+ struct rate_info rinfo;
+ enum nl80211_sta_mon_txrate_threshold_event sta_txrate_event;
+ int txrate;
+
+ if (!sta->txrate_high)
+ return;
+
+ sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
+ txrate = cfg80211_calculate_bitrate(&rinfo);
+ ewma_sta_txrate_add(&sta->ave_sta_txrate, txrate);
+ sta->count_sta_txrate++;
+
+ if (sta->count_sta_txrate < IEEE80211_STA_TXRATE_AVE_MIN_COUNT)
+ return;
+
+ txrate = ewma_sta_txrate_read(&sta->ave_sta_txrate);
+
+ if (txrate < sta->txrate_low)
+ sta_txrate_event = NL80211_STA_MON_TXRATE_THRESHOLD_EVENT_LOW;
+ else if (txrate > sta->txrate_high)
+ sta_txrate_event = NL80211_STA_MON_TXRATE_THRESHOLD_EVENT_HIGH;
+ else
+ sta_txrate_event = NL80211_STA_MON_TXRATE_THRESHOLD_IN_RANGE;
+
+ if (sta_txrate_event != sta->last_txrate_event) {
+ cfg80211_sta_mon_txrate_notify(sta->sdata->dev, sta->addr,
+ sta_txrate_event, txrate,
+ GFP_ATOMIC);
+ sta->last_txrate_event = sta_txrate_event;
+ }
+}
+
static void __ieee80211_tx_status(struct ieee80211_hw *hw,
struct ieee80211_tx_status *status)
{
@@ -750,9 +784,13 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL) &&
(ieee80211_is_data(hdr->frame_control)) &&
- (rates_idx != -1))
+ (rates_idx != -1)) {
sta->tx_stats.last_rate =
info->status.rates[rates_idx];
+ if (wiphy_ext_feature_isset(hw->wiphy,
+ NL80211_EXT_FEATURE_STA_MON_TXRATE_CONFIG))
+ ieee80211_sta_mon_txrate_thold_check(sta);
+ }
if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
(ieee80211_is_data_qos(fc))) {
--
1.7.9.5
I'd say squash this with patch 1 - there's no point in adding the
configurations if you can't use them :-)
> +void
> +cfg80211_sta_mon_txrate_notify(struct net_device *dev, const u8 *peer,
> + enum nl80211_sta_mon_txrate_threshold_event txrate_event,
> + u32 txrate_level, gfp_t gfp)
Maybe the actual MCS would be useful?
johannes
On Wed, 2018-06-13 at 16:28 +0530, Tamizh chelvam wrote:
> Add support to configure station specific txrate threshold
> to monitor variation in the txrate for a station. Configuration
> is passed using NL80211_ATTR_STA_MON_LOW_TXRATE_THOLD and
> NL80211_ATTR_STA_MON_HIGH_TXRATE_THOLD in NL80211_CMD_SET_STA_MON
> command and the configuration will be represented in 100kbps.
> This will be useful for the application like steering which requires
> station's current capability.
>
> Driver supporting this configuration feature should advertise
> NL80211_EXT_FEATURE_STA_MON_TXRATE_CONFIG.
Are you also going to split this into multiple thresholds later? Perhaps
just consider that today already?
> + * @set_sta_mon_txrate_config: Configure low and high TXRATE threshold in 100kbs
> + * for a connected station. The driver should(soon) send an event
> + * indicating the current attempted frame txrate level is above/below the
> + * configured threshold
This is a bit awkward to implement I guess - 100kbps units are hard to
deal with since the calculations between MCS and bitrate aren't exactly
simple and cheap... But I guess drivers/mac80211 can transform them
somehow at configuration time, e.g. by building a bitmap.
johannes
Add set_sta_mon_txrate_config api to configure low and high
txrate threshold for a connected station. The configuration
will be represented in 100kbps.
Signed-off-by: Tamizh chelvam <[email protected]>
---
net/mac80211/cfg.c | 35 +++++++++++++++++++++++++++++++++++
net/mac80211/sta_info.h | 7 +++++++
2 files changed, 42 insertions(+)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5cdd8a3..649f5c7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3876,6 +3876,40 @@ static int ieee80211_set_sta_mon_rssi_range_cfg(struct wiphy *wiphy,
return 0;
}
+static int ieee80211_set_sta_mon_txrate_config(struct wiphy *wiphy,
+ struct net_device *dev,
+ const u8 *peer,
+ u32 low_txrate_thold,
+ u32 high_txrate_thold)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct sta_info *sta;
+
+ if (sdata->vif.type == NL80211_IFTYPE_AP &&
+ !wiphy_ext_feature_isset(sdata->local->hw.wiphy,
+ NL80211_EXT_FEATURE_STA_MON_TXRATE_CONFIG))
+ return -EOPNOTSUPP;
+
+ mutex_lock(&sdata->local->sta_mtx);
+
+ sta = sta_info_get_bss(sdata, peer);
+ if (!sta) {
+ mutex_unlock(&sdata->local->sta_mtx);
+ return -ENOENT;
+ }
+
+ if (sta->txrate_low == low_txrate_thold &&
+ sta->txrate_high == high_txrate_thold)
+ goto unlock;
+
+ sta->txrate_low = low_txrate_thold;
+ sta->txrate_high = high_txrate_thold;
+
+unlock:
+ mutex_unlock(&sdata->local->sta_mtx);
+ return 0;
+}
+
const struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -3972,4 +4006,5 @@ static int ieee80211_set_sta_mon_rssi_range_cfg(struct wiphy *wiphy,
.get_txq_stats = ieee80211_get_txq_stats,
.set_sta_mon_rssi_config = ieee80211_set_sta_mon_rssi_config,
.set_sta_mon_rssi_range_config = ieee80211_set_sta_mon_rssi_range_cfg,
+ .set_sta_mon_txrate_config = ieee80211_set_sta_mon_txrate_config,
};
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 05d68f8..a71f50c 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -497,6 +497,10 @@ struct ieee80211_sta_rx_stats {
* @count_rx_signal: Number of data frames used in averaging station signal.
* This can be used to avoid generating less reliable station rssi cross
* events that would be based only on couple of received frames
+ * @txrate_low: TXRATE lower threshold for a station to monitor, this will be
+ * in 100Kbps
+ * @txrate_high: TXRATE upper threshold for a station to monitor, this will be
+ * in 100Kbps
*/
struct sta_info {
/* General information, mostly static */
@@ -605,6 +609,9 @@ struct sta_info {
int last_sta_mon_event_signal;
unsigned int count_rx_signal;
+ u32 txrate_low;
+ u32 txrate_high;
+
/* keep last! */
struct ieee80211_sta sta;
};
--
1.7.9.5
Add cfg80211_sta_mon_txrate_notify to update userspace upon
crossing the configured txrate threshold for a station.
This uses NL80211_CMD_NOTIFY_STA_MON along with
NL80211_ATTR_STA_MON_TXRATE_THRESHOLD_EVENT, NL80211_ATTR_MAC
and NL80211_ATTR_STA_MON_TXRATE_LEVEL. Userspace application can
make a decision on the station depends on this notification.
Signed-off-by: Tamizh chelvam <[email protected]>
---
include/net/cfg80211.h | 17 +++++++++++++++++
net/wireless/nl80211.c | 38 ++++++++++++++++++++++++++++++++++++++
net/wireless/trace.h | 25 +++++++++++++++++++++++++
3 files changed, 80 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5bf0000..c0f8018 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5899,6 +5899,23 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
s32 rssi_level, gfp_t gfp);
/**
+ * cfg80211_sta_mon_txrate_notify - txrate event for connected stations
+ * @dev: network device
+ * @peer: peer's MAC address
+ * @txrate_event: the triggered TX RATE event
+ * @txrate_level: new TX RATE level value or 0 if not available
+ * @gfp: context flags
+ *
+ * This function is called when a average of attempted frame txrate crossed
+ * above configured high txrate or below configured low txrate event
+ * occurs for a station.
+ */
+void
+cfg80211_sta_mon_txrate_notify(struct net_device *dev, const u8 *peer,
+ enum nl80211_sta_mon_txrate_threshold_event txrate_event,
+ u32 txrate_level, gfp_t gfp);
+
+/**
* cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer
* @dev: network device
* @peer: peer's MAC address
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 31680d6..645a9fd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -15576,6 +15576,44 @@ void cfg80211_sta_mon_rssi_notify(struct net_device *dev, const u8 *peer,
}
EXPORT_SYMBOL(cfg80211_sta_mon_rssi_notify);
+void
+cfg80211_sta_mon_txrate_notify(struct net_device *dev, const u8 *peer,
+ enum nl80211_sta_mon_txrate_threshold_event txrate_event,
+ u32 txrate_level, gfp_t gfp)
+{
+ struct sk_buff *msg;
+
+ trace_cfg80211_sta_mon_txrate_notify(dev, peer, txrate_event,
+ txrate_level);
+
+ if (WARN_ON(txrate_event !=
+ NL80211_STA_MON_TXRATE_THRESHOLD_EVENT_LOW &&
+ txrate_event !=
+ NL80211_STA_MON_TXRATE_THRESHOLD_EVENT_HIGH &&
+ txrate_event !=
+ NL80211_STA_MON_TXRATE_THRESHOLD_IN_RANGE))
+ return;
+
+ msg = cfg80211_prepare_sta_mon(dev, peer, gfp);
+ if (!msg)
+ return;
+
+ if (nla_put_u32(msg, NL80211_ATTR_STA_MON_TXRATE_THRESHOLD_EVENT,
+ txrate_event))
+ goto nla_put_failure;
+
+ if (txrate_level && nla_put_u32(msg, NL80211_ATTR_STA_MON_TXRATE_LEVEL,
+ txrate_level))
+ goto nla_put_failure;
+
+ cfg80211_send_sta_mon(msg, gfp);
+
+ return;
+nla_put_failure:
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_sta_mon_txrate_notify);
+
static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
struct cfg80211_chan_def *chandef,
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ca985c2..95f4a31 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -3355,6 +3355,31 @@
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
__entry->low_txrate_thold, __entry->high_txrate_thold)
);
+
+TRACE_EVENT(cfg80211_sta_mon_txrate_notify,
+ TP_PROTO(struct net_device *netdev, const u8 *peer,
+ enum nl80211_sta_mon_txrate_threshold_event txrate_event,
+ u32 txrate_level),
+ TP_ARGS(netdev, peer, txrate_event, txrate_level),
+ TP_STRUCT__entry(
+ NETDEV_ENTRY
+ MAC_ENTRY(peer)
+ __field(enum nl80211_sta_mon_txrate_threshold_event,
+ txrate_event)
+ __field(u32, txrate_level)
+ ),
+ TP_fast_assign(
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(peer, peer);
+ __entry->txrate_event = txrate_event;
+ __entry->txrate_level = txrate_level;
+ ),
+ TP_printk(NETDEV_PR_FMT ", peer: " MAC_PR_FMT
+ ", tx_rate event: %d, txrate : %u",
+ NETDEV_PR_ARG, MAC_PR_ARG(peer),
+ __entry->txrate_event, __entry->txrate_level)
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
--
1.7.9.5
Tamizh Chelvam Raja <[email protected]> writes:
>> This patchsets introduced new NL command and api to support
>> configuring txrate threshold for the connected stations and api to
>> notify userspace application upon crossing the configured txrate threshold.
>> This will be useful for the application which requires station's
>> current capability change information.
>
> What is the intended use case? Asking mostly out of curiosity :)
> [Tamizh] This is to monitor txrate change for a station. By notifying
> userspace when the txrate for a station goes out of configured
> threshold, It can take steering decisions on the particular station.
Yeah, I got that part. I was curious as to what (userspace) application
you were planning to use this for? I.e., what kind of steering
decisions? :)
-Toke
On Wed, 2018-06-13 at 16:28 +0530, Tamizh chelvam wrote:
> + if (sta->txrate_low == low_txrate_thold &&
> + sta->txrate_high == high_txrate_thold)
> + goto unlock;
> +
> + sta->txrate_low = low_txrate_thold;
> + sta->txrate_high = high_txrate_thold;
You don't really do anything here so what do you gain by doing the ==
comparison and jumping over the assignment?
I'd understand if you did some calculations here or whatever, but as it
is it reads more like something was missed than like it was intended
this way?
Again, I think you need to squash this with patch 4.
johannes
On 6/13/2018 5:10 PM, Toke H?iland-J?rgensen wrote:
> Tamizh Chelvam Raja <[email protected]> writes:
>
>>> This patchsets introduced new NL command and api to support
>>> configuring txrate threshold for the connected stations and api to
>>> notify userspace application upon crossing the configured txrate threshold.
>>> This will be useful for the application which requires station's
>>> current capability change information.
>>
>> What is the intended use case? Asking mostly out of curiosity :)
>
>> [Tamizh] This is to monitor txrate change for a station. By notifying
>> userspace when the txrate for a station goes out of configured
>> threshold, It can take steering decisions on the particular station.
>
> Yeah, I got that part. I was curious as to what (userspace) application
> you were planning to use this for? I.e., what kind of steering
> decisions? :)
It sounds like network initiated handover as opposed to station roaming.
Suspect the user-space application referred to here is a proprietary
application. At plumbers conf I attended a couple of years ago there was
an idea to have a network management application controlling multiple
hostapd instances for this type of functionality, but not sure if that
project ever got of the ground.
Regards,
Arend
2018-06-14 9:50 GMT+02:00 Arend van Spriel <[email protected]>:
> On 6/13/2018 5:10 PM, Toke H=C3=B8iland-J=C3=B8rgensen wrote:
>>
>> Tamizh Chelvam Raja <[email protected]> writes:
>>
>>>> This patchsets introduced new NL command and api to support
>>>> configuring txrate threshold for the connected stations and api to
>>>> notify userspace application upon crossing the configured txrate
>>>> threshold.
>>>> This will be useful for the application which requires station's
>>>> current capability change information.
>>>
>>>
>>> What is the intended use case? Asking mostly out of curiosity :)
>>
>>
>>> [Tamizh] This is to monitor txrate change for a station. By notifying
>>> userspace when the txrate for a station goes out of configured
>>> threshold, It can take steering decisions on the particular station.
>>
Do we really need kernel notification for that?
You can simple monitor all this information same way iw station dump show.
As a metric use tx/rx bitrate, signal or even expected throughput.
Maybe small patch that will average tx/rx bitrate for few seconds
(additional fields in station dump) could be helpful here.
BR
Janusz
>>
>> Yeah, I got that part. I was curious as to what (userspace) application
>> you were planning to use this for? I.e., what kind of steering
>> decisions? :)
>
>
> It sounds like network initiated handover as opposed to station roaming.
> Suspect the user-space application referred to here is a proprietary
> application. At plumbers conf I attended a couple of years ago there was =
an
> idea to have a network management application controlling multiple hostap=
d
> instances for this type of functionality, but not sure if that project ev=
er
> got of the ground.
>
> Regards,
> Arend
>
--=20
Janusz Dziedzic
> This patchsets introduced new NL command and api to support=20
> configuring txrate threshold for the connected stations and api to=20
> notify userspace application upon crossing the configured txrate threshol=
d.
> This will be useful for the application which requires station's=20
> current capability change information.
What is the intended use case? Asking mostly out of curiosity :)
[Tamizh] This is to monitor txrate change for a station. By notifying users=
pace when the txrate for a station goes out of configured threshold, It can=
take steering decisions on the particular station.
-Toke
On 2018-06-15 17:16, Janusz Dziedzic wrote:
> 2018-06-14 9:50 GMT+02:00 Arend van Spriel
> <[email protected]>:
>> On 6/13/2018 5:10 PM, Toke Høiland-Jørgensen wrote:
>>>
>>> Tamizh Chelvam Raja <[email protected]> writes:
>>>
>>>>> This patchsets introduced new NL command and api to support
>>>>> configuring txrate threshold for the connected stations and api to
>>>>> notify userspace application upon crossing the configured txrate
>>>>> threshold.
>>>>> This will be useful for the application which requires station's
>>>>> current capability change information.
>>>>
>>>>
>>>> What is the intended use case? Asking mostly out of curiosity :)
>>>
>>>
>>>> [Tamizh] This is to monitor txrate change for a station. By
>>>> notifying
>>>> userspace when the txrate for a station goes out of configured
>>>> threshold, It can take steering decisions on the particular station.
>>>
> Do we really need kernel notification for that?
> You can simple monitor all this information same way iw station dump
> show.
In this case user space application need to fetch the station statistics
periodically and parse those detail.
Let say AP has more number of stations(like more than 50) in all
bands(2G and 5G), then the system overhead will be more for fetching the
detail periodically.
But with this kernel notification we can avoid those overhead and more
or less this is similar to the CQM(rssi, txe,..) notification in STA
mode.
Thanks,
Tamizh.
> As a metric use tx/rx bitrate, signal or even expected throughput.
>
> Maybe small patch that will average tx/rx bitrate for few seconds
> (additional fields in station dump) could be helpful here.
>
> BR
> Janusz
>
>>>
>>> Yeah, I got that part. I was curious as to what (userspace)
>>> application
>>> you were planning to use this for? I.e., what kind of steering
>>> decisions? :)
>>
>>
>> It sounds like network initiated handover as opposed to station
>> roaming.
>> Suspect the user-space application referred to here is a proprietary
>> application. At plumbers conf I attended a couple of years ago there
>> was an
>> idea to have a network management application controlling multiple
>> hostapd
>> instances for this type of functionality, but not sure if that project
>> ever
>> got of the ground.
>>
>> Regards,
>> Arend
>>