* [PATCH 2/6] mac80211: fix connection polling
2013-11-18 17:02 [PATCH 1/6] mac80211: Tx frame latency statistics Emmanuel Grumbach
@ 2013-11-18 17:02 ` Emmanuel Grumbach
2013-11-18 17:02 ` [PATCH 3/6] mac80211: remove sta_info_flush() from interface teardown Emmanuel Grumbach
` (4 subsequent siblings)
5 siblings, 0 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:02 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Eliad Peller
From: Eliad Peller <eliad@wizery.com>
Commit 392b9ff ("mac80211: change beacon/connection polling")
removed the IEEE80211_STA_BEACON_POLL flag.
However, it accidentally removed the setting of
IEEE80211_STA_CONNECTION_POLL, making the connection polling
completely useless (the flag is always clear, so the result
is never being checked). Fix it.
Signed-off-by: Eliad Peller <eliad@wizery.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/mlme.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d7504ab..b3a3ce3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1910,6 +1910,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
already = true;
+ ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
+
mutex_unlock(&sdata->local->mtx);
if (already)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 3/6] mac80211: remove sta_info_flush() from interface teardown
2013-11-18 17:02 [PATCH 1/6] mac80211: Tx frame latency statistics Emmanuel Grumbach
2013-11-18 17:02 ` [PATCH 2/6] mac80211: fix connection polling Emmanuel Grumbach
@ 2013-11-18 17:02 ` Emmanuel Grumbach
2013-11-18 17:02 ` [PATCH 4/6] mac80211: update ht flag if bss configuration changed Emmanuel Grumbach
` (3 subsequent siblings)
5 siblings, 0 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:02 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
All interface types now properly clean up their stations
using some form of sta_info_flush() themselves, so there's
no need to try it again at teardown. Remove the call to
get rid of the extra delay from the synchronize_net() and
rcu_barrier() calls.
Reported-by: Moshe Benji <moshe.benji@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/iface.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index ff101ea..a3d106d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1036,7 +1036,6 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
*/
static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
{
- int flushed;
int i;
/* free extra data */
@@ -1050,9 +1049,6 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
if (ieee80211_vif_is_mesh(&sdata->vif))
mesh_rmc_free(sdata);
-
- flushed = sta_info_flush(sdata);
- WARN_ON(flushed);
}
static void ieee80211_uninit(struct net_device *dev)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 4/6] mac80211: update ht flag if bss configuration changed
2013-11-18 17:02 [PATCH 1/6] mac80211: Tx frame latency statistics Emmanuel Grumbach
2013-11-18 17:02 ` [PATCH 2/6] mac80211: fix connection polling Emmanuel Grumbach
2013-11-18 17:02 ` [PATCH 3/6] mac80211: remove sta_info_flush() from interface teardown Emmanuel Grumbach
@ 2013-11-18 17:02 ` Emmanuel Grumbach
2013-11-18 17:02 ` [PATCH 5/6] cfg80211: Aggregate mgmt_tx parameters into a struct Emmanuel Grumbach
` (2 subsequent siblings)
5 siblings, 0 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:02 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avri Altman
From: Avri Altman <avri.altman@intel.com>
The bug concerned failing to update the ht flag properly.
updating the ht flag when bss configuration changes should
be done independently of channel changes.
Signed-off-by: Avri Altman <avri.altman@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/mlme.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b3a3ce3..03aa33f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -330,6 +330,16 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
if (WARN_ON_ONCE(!sta))
return -EINVAL;
+ /*
+ * if bss configuration changed store the new one -
+ * this may be applicable even if channel is identical
+ */
+ ht_opmode = le16_to_cpu(ht_oper->operation_mode);
+ if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
+ *changed |= BSS_CHANGED_HT;
+ sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
+ }
+
chan = sdata->vif.bss_conf.chandef.chan;
sband = local->hw.wiphy->bands[chan->band];
@@ -416,14 +426,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
IEEE80211_RC_BW_CHANGED);
}
- ht_opmode = le16_to_cpu(ht_oper->operation_mode);
-
- /* if bss configuration changed store the new one */
- if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
- *changed |= BSS_CHANGED_HT;
- sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
- }
-
return 0;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 5/6] cfg80211: Aggregate mgmt_tx parameters into a struct
2013-11-18 17:02 [PATCH 1/6] mac80211: Tx frame latency statistics Emmanuel Grumbach
` (2 preceding siblings ...)
2013-11-18 17:02 ` [PATCH 4/6] mac80211: update ht flag if bss configuration changed Emmanuel Grumbach
@ 2013-11-18 17:02 ` Emmanuel Grumbach
2013-11-18 17:02 ` [PATCH 6/6] cfg80211: Fix setting channel in mgmt_tx parameters Emmanuel Grumbach
2013-11-18 17:06 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Emmanuel Grumbach
5 siblings, 0 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:02 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Andrei Otcheretianski
From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Change cfg80211 and mac80211 to use cfg80211_mgmt_tx_params
struct to aggregate parameters for mgmt_tx functions.
This makes the functions' signatures less clumsy and allows
less painful parameters extension.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/cfg80211.h | 28 +++++++++++++++++++++++++---
net/mac80211/cfg.c | 29 +++++++++++++++--------------
net/wireless/core.h | 5 ++---
net/wireless/mlme.c | 12 ++++--------
net/wireless/nl80211.c | 31 +++++++++++++++----------------
net/wireless/rdev-ops.h | 12 ++++--------
net/wireless/trace.h | 15 +++++++--------
7 files changed, 72 insertions(+), 60 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3eae46c..54bdded 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1945,6 +1945,29 @@ struct cfg80211_update_ft_ies_params {
};
/**
+ * struct cfg80211_mgmt_tx_params - mgmt tx parameters
+ *
+ * This structure provides information needed to transmit a mgmt frame
+ *
+ * @chan: channel to use
+ * @offchan: indicates wether off channel operation is required
+ * @wait: duration for ROC
+ * @buf: buffer to transmit
+ * @len: buffer length
+ * @no_cck: don't use cck rates for this frame
+ * @dont_wait_for_ack: tells the low level not to wait for an ack
+ */
+struct cfg80211_mgmt_tx_params {
+ struct ieee80211_channel *chan;
+ bool offchan;
+ unsigned int wait;
+ const u8 *buf;
+ size_t len;
+ bool no_cck;
+ bool dont_wait_for_ack;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2342,9 +2365,8 @@ struct cfg80211_ops {
u64 cookie);
int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie);
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie);
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
struct wireless_dev *wdev,
u64 cookie);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 95667b0..9442837 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3146,26 +3146,25 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct sta_info *sta;
- const struct ieee80211_mgmt *mgmt = (void *)buf;
+ const struct ieee80211_mgmt *mgmt = (void *)params->buf;
bool need_offchan = false;
u32 flags;
int ret;
- if (dont_wait_for_ack)
+ if (params->dont_wait_for_ack)
flags = IEEE80211_TX_CTL_NO_ACK;
else
flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
IEEE80211_TX_CTL_REQ_TX_STATUS;
- if (no_cck)
+ if (params->no_cck)
flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
switch (sdata->vif.type) {
@@ -3213,7 +3212,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
/* configurations requiring offchan cannot work if no channel has been
* specified
*/
- if (need_offchan && !chan)
+ if (need_offchan && !params->chan)
return -EINVAL;
mutex_lock(&local->mtx);
@@ -3226,8 +3225,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (chanctx_conf) {
- need_offchan = chan && (chan != chanctx_conf->def.chan);
- } else if (!chan) {
+ need_offchan = params->chan &&
+ (params->chan !=
+ chanctx_conf->def.chan);
+ } else if (!params->chan) {
ret = -EINVAL;
rcu_read_unlock();
goto out_unlock;
@@ -3237,19 +3238,19 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
rcu_read_unlock();
}
- if (need_offchan && !offchan) {
+ if (need_offchan && !params->offchan) {
ret = -EBUSY;
goto out_unlock;
}
- skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + params->len);
if (!skb) {
ret = -ENOMEM;
goto out_unlock;
}
skb_reserve(skb, local->hw.extra_tx_headroom);
- memcpy(skb_put(skb, len), buf, len);
+ memcpy(skb_put(skb, params->len), params->buf, params->len);
IEEE80211_SKB_CB(skb)->flags = flags;
@@ -3269,8 +3270,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
local->hw.offchannel_tx_hw_queue;
/* This will handle all kinds of coalescing and immediate TX */
- ret = ieee80211_start_roc_work(local, sdata, chan,
- wait, cookie, skb,
+ ret = ieee80211_start_roc_work(local, sdata, params->chan,
+ params->wait, cookie, skb,
IEEE80211_ROC_TYPE_MGMT_TX);
if (ret)
kfree_skb(skb);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index eb0f7a3..bff9869 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -317,9 +317,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie);
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie);
void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
const struct ieee80211_ht_cap *ht_capa_mask);
void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 6a6b1c8..a9cecd7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -520,9 +520,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+ struct cfg80211_mgmt_tx_params *params, u64 *cookie)
{
const struct ieee80211_mgmt *mgmt;
u16 stype;
@@ -533,10 +531,10 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
if (!rdev->ops->mgmt_tx)
return -EOPNOTSUPP;
- if (len < 24 + 1)
+ if (params->len < 24 + 1)
return -EINVAL;
- mgmt = (const struct ieee80211_mgmt *) buf;
+ mgmt = (const struct ieee80211_mgmt *)params->buf;
if (!ieee80211_is_mgmt(mgmt->frame_control))
return -EINVAL;
@@ -615,9 +613,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
return -EINVAL;
/* Transmit the Action frame as requested by user space */
- return rdev_mgmt_tx(rdev, wdev, chan, offchan,
- wait, buf, len, no_cck, dont_wait_for_ack,
- cookie);
+ return rdev_mgmt_tx(rdev, wdev, params, cookie);
}
bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a7f4e79..c2627ba 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7428,10 +7428,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
void *hdr = NULL;
u64 cookie;
struct sk_buff *msg = NULL;
- unsigned int wait = 0;
- bool offchan, no_cck, dont_wait_for_ack;
-
- dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
+ struct cfg80211_mgmt_tx_params params = {
+ .dont_wait_for_ack =
+ info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
+ };
if (!info->attrs[NL80211_ATTR_FRAME])
return -EINVAL;
@@ -7458,24 +7458,24 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_DURATION]) {
if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
return -EINVAL;
- wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
+ params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
/*
* We should wait on the channel for at least a minimum amount
* of time (10ms) but no longer than the driver supports.
*/
- if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
- wait > rdev->wiphy.max_remain_on_channel_duration)
+ if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
+ params.wait > rdev->wiphy.max_remain_on_channel_duration)
return -EINVAL;
}
- offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
+ params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
- if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
+ if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
return -EINVAL;
- no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
+ params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
/* get the channel if any has been specified, otherwise pass NULL to
* the driver. The latter will use the current one
@@ -7487,10 +7487,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
return err;
}
- if (!chandef.chan && offchan)
+ if (!chandef.chan && params.offchan)
return -EINVAL;
- if (!dont_wait_for_ack) {
+ if (!params.dont_wait_for_ack) {
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -7503,10 +7503,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
}
}
- err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
- nla_data(info->attrs[NL80211_ATTR_FRAME]),
- nla_len(info->attrs[NL80211_ATTR_FRAME]),
- no_cck, dont_wait_for_ack, &cookie);
+ params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+ params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+ err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie);
if (err)
goto free_msg;
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 37ce9fd..a6c03ab 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -624,16 +624,12 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev,
static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie)
{
int ret;
- trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
- wait, no_cck, dont_wait_for_ack);
- ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
- wait, buf, len, no_cck,
- dont_wait_for_ack, cookie);
+ trace_rdev_mgmt_tx(&rdev->wiphy, wdev, params);
+ ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, params, cookie);
trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
return ret;
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ba5f0d6..f7aa7a7 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1653,9 +1653,8 @@ TRACE_EVENT(rdev_cancel_remain_on_channel,
TRACE_EVENT(rdev_mgmt_tx,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, bool no_cck, bool dont_wait_for_ack),
- TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack),
+ struct cfg80211_mgmt_tx_params *params),
+ TP_ARGS(wiphy, wdev, params),
TP_STRUCT__entry(
WIPHY_ENTRY
WDEV_ENTRY
@@ -1668,11 +1667,11 @@ TRACE_EVENT(rdev_mgmt_tx,
TP_fast_assign(
WIPHY_ASSIGN;
WDEV_ASSIGN;
- CHAN_ASSIGN(chan);
- __entry->offchan = offchan;
- __entry->wait = wait;
- __entry->no_cck = no_cck;
- __entry->dont_wait_for_ack = dont_wait_for_ack;
+ CHAN_ASSIGN(params->chan);
+ __entry->offchan = params->offchan;
+ __entry->wait = params->wait;
+ __entry->no_cck = params->no_cck;
+ __entry->dont_wait_for_ack = params->dont_wait_for_ack;
),
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s,"
" wait: %u, no cck: %s, dont wait for ack: %s",
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 6/6] cfg80211: Fix setting channel in mgmt_tx parameters
2013-11-18 17:02 [PATCH 1/6] mac80211: Tx frame latency statistics Emmanuel Grumbach
` (3 preceding siblings ...)
2013-11-18 17:02 ` [PATCH 5/6] cfg80211: Aggregate mgmt_tx parameters into a struct Emmanuel Grumbach
@ 2013-11-18 17:02 ` Emmanuel Grumbach
2013-11-18 17:04 ` Emmanuel Grumbach
2013-11-18 17:06 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Emmanuel Grumbach
5 siblings, 1 reply; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:02 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Andrei Otcheretianski
From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
The cfg80211_mgmt_tx_params.chan member wasn't set which
caused a bug in offchan operations.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
net/wireless/nl80211.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c2627ba..73ca4fc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7505,6 +7505,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+ params.chan = chandef.chan;
err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie);
if (err)
goto free_msg;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH RESEND 1/5] mac80211: Tx frame latency statistics
2013-11-18 17:02 [PATCH 1/6] mac80211: Tx frame latency statistics Emmanuel Grumbach
` (4 preceding siblings ...)
2013-11-18 17:02 ` [PATCH 6/6] cfg80211: Fix setting channel in mgmt_tx parameters Emmanuel Grumbach
@ 2013-11-18 17:06 ` Emmanuel Grumbach
2013-11-18 17:06 ` [PATCH RESEND 2/5] mac80211: fix connection polling Emmanuel Grumbach
` (4 more replies)
5 siblings, 5 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:06 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Matti Gottlieb
From: Matti Gottlieb <matti.gottlieb@intel.com>
Measure TX latency and jitter statistics per station per TID.
These Measurements are disabled by default and can be enabled
via debugfs.
Features included for each station's TID:
1. Keep count of the maximum and average latency of Tx frames.
2. Keep track of many frames arrived in a specific time range
(need to enable through debugfs and configure the bins ranges)
Signed-off-by: Matti Gottlieb <matti.gottlieb@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/debugfs.c | 168 ++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/debugfs_sta.c | 134 +++++++++++++++++++++++++++++++++++
net/mac80211/ieee80211_i.h | 24 +++++++
net/mac80211/main.c | 2 +
net/mac80211/sta_info.c | 34 +++++++++
net/mac80211/sta_info.h | 22 ++++++
net/mac80211/status.c | 78 ++++++++++++++++++++
net/mac80211/tx.c | 24 +++++++
8 files changed, 486 insertions(+)
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 5c090e4..fa16e54 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -17,6 +17,172 @@
#define DEBUGFS_FORMAT_BUFFER_SIZE 100
+#define TX_LATENCY_BIN_DELIMTER_C ','
+#define TX_LATENCY_BIN_DELIMTER_S ","
+#define TX_LATENCY_BINS_DISABLED "enable(bins disabled)\n"
+#define TX_LATENCY_DISABLED "disable\n"
+
+
+/*
+ * Display if Tx latency statistics & bins are enabled/disabled
+ */
+static ssize_t sta_tx_latency_stat_read(struct file *file,
+ char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ struct ieee80211_tx_latency_bin_ranges *tx_latency;
+ char *buf;
+ int bufsz, i, ret;
+ int pos = 0;
+
+ rcu_read_lock();
+
+ tx_latency = rcu_dereference(local->tx_latency);
+
+ if (tx_latency && tx_latency->n_ranges) {
+ bufsz = tx_latency->n_ranges * 15;
+ buf = kzalloc(bufsz, GFP_ATOMIC);
+ if (!buf)
+ goto err;
+
+ for (i = 0; i < tx_latency->n_ranges; i++)
+ pos += scnprintf(buf + pos, bufsz - pos, "%d,",
+ tx_latency->ranges[i]);
+ pos += scnprintf(buf + pos, bufsz - pos, "\n");
+ } else if (tx_latency) {
+ bufsz = sizeof(TX_LATENCY_BINS_DISABLED) + 1;
+ buf = kzalloc(bufsz, GFP_ATOMIC);
+ if (!buf)
+ goto err;
+
+ pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
+ TX_LATENCY_BINS_DISABLED);
+ } else {
+ bufsz = sizeof(TX_LATENCY_DISABLED) + 1;
+ buf = kzalloc(bufsz, GFP_ATOMIC);
+ if (!buf)
+ goto err;
+
+ pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
+ TX_LATENCY_DISABLED);
+ }
+
+ rcu_read_unlock();
+
+ ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+ kfree(buf);
+
+ return ret;
+err:
+ rcu_read_unlock();
+ return -ENOMEM;
+}
+
+/*
+ * Receive input from user regarding Tx latency statistics
+ * The input should indicate if Tx latency statistics and bins are
+ * enabled/disabled.
+ * If bins are enabled input should indicate the amount of different bins and
+ * their ranges. Each bin will count how many Tx frames transmitted within the
+ * appropriate latency.
+ * Legal input is:
+ * a) "enable(bins disabled)" - to enable only general statistics
+ * b) "a,b,c,d,...z" - to enable general statistics and bins, where all are
+ * numbers and a < b < c < d.. < z
+ * c) "disable" - disable all statistics
+ * NOTE: must configure Tx latency statistics bins before stations connected.
+ */
+
+static ssize_t sta_tx_latency_stat_write(struct file *file,
+ const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ char buf[128] = {};
+ char *bins = buf;
+ char *token;
+ int buf_size, i, alloc_size;
+ int prev_bin = 0;
+ int n_ranges = 0;
+ int ret = count;
+ struct ieee80211_tx_latency_bin_ranges *tx_latency;
+
+ if (sizeof(buf) <= count)
+ return -EINVAL;
+ buf_size = count;
+ if (copy_from_user(buf, userbuf, buf_size))
+ return -EFAULT;
+
+ mutex_lock(&local->sta_mtx);
+
+ /* cannot change config once we have stations */
+ if (local->num_sta)
+ goto unlock;
+
+ tx_latency =
+ rcu_dereference_protected(local->tx_latency,
+ lockdep_is_held(&local->sta_mtx));
+
+ /* disable Tx statistics */
+ if (!strcmp(buf, TX_LATENCY_DISABLED)) {
+ if (!tx_latency)
+ goto unlock;
+ rcu_assign_pointer(local->tx_latency, NULL);
+ synchronize_rcu();
+ kfree(tx_latency);
+ goto unlock;
+ }
+
+ /* Tx latency already enabled */
+ if (tx_latency)
+ goto unlock;
+
+ if (strcmp(TX_LATENCY_BINS_DISABLED, buf)) {
+ /* check how many bins and between what ranges user requested */
+ token = buf;
+ while (*token != '\0') {
+ if (*token == TX_LATENCY_BIN_DELIMTER_C)
+ n_ranges++;
+ token++;
+ }
+ n_ranges++;
+ }
+
+ alloc_size = sizeof(struct ieee80211_tx_latency_bin_ranges) +
+ n_ranges * sizeof(u32);
+ tx_latency = kzalloc(alloc_size, GFP_ATOMIC);
+ if (!tx_latency) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+ tx_latency->n_ranges = n_ranges;
+ for (i = 0; i < n_ranges; i++) { /* setting bin ranges */
+ token = strsep(&bins, TX_LATENCY_BIN_DELIMTER_S);
+ sscanf(token, "%d", &tx_latency->ranges[i]);
+ /* bins values should be in ascending order */
+ if (prev_bin >= tx_latency->ranges[i]) {
+ ret = -EINVAL;
+ kfree(tx_latency);
+ goto unlock;
+ }
+ prev_bin = tx_latency->ranges[i];
+ }
+ rcu_assign_pointer(local->tx_latency, tx_latency);
+
+unlock:
+ mutex_unlock(&local->sta_mtx);
+
+ return ret;
+}
+
+static const struct file_operations stats_tx_latency_ops = {
+ .write = sta_tx_latency_stat_write,
+ .read = sta_tx_latency_stat_read,
+ .open = simple_open,
+ .llseek = generic_file_llseek,
+};
+
int mac80211_format_buffer(char __user *userbuf, size_t count,
loff_t *ppos, char *fmt, ...)
{
@@ -315,4 +481,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
+
+ DEBUGFS_DEVSTATS_ADD(tx_latency);
}
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 19c54a4..80194b5 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -38,6 +38,13 @@ static const struct file_operations sta_ ##name## _ops = { \
.llseek = generic_file_llseek, \
}
+#define STA_OPS_W(name) \
+static const struct file_operations sta_ ##name## _ops = { \
+ .write = sta_##name##_write, \
+ .open = simple_open, \
+ .llseek = generic_file_llseek, \
+}
+
#define STA_OPS_RW(name) \
static const struct file_operations sta_ ##name## _ops = { \
.read = sta_##name##_read, \
@@ -388,6 +395,131 @@ static ssize_t sta_last_rx_rate_read(struct file *file, char __user *userbuf,
}
STA_OPS(last_rx_rate);
+static int
+sta_tx_latency_stat_header(struct ieee80211_tx_latency_bin_ranges *tx_latency,
+ char *buf, int pos, int bufsz)
+{
+ int i;
+ int range_count = tx_latency->n_ranges;
+ u32 *bin_ranges = tx_latency->ranges;
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "Station\t\t\tTID\tMax\tAvg");
+ if (range_count) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\t<=%d", bin_ranges[0]);
+ for (i = 0; i < range_count - 1; i++)
+ pos += scnprintf(buf + pos, bufsz - pos, "\t%d-%d",
+ bin_ranges[i], bin_ranges[i+1]);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\t%d<", bin_ranges[range_count - 1]);
+ }
+
+ pos += scnprintf(buf + pos, bufsz - pos, "\n");
+
+ return pos;
+}
+
+static int
+sta_tx_latency_stat_table(struct ieee80211_tx_latency_bin_ranges *tx_lat_range,
+ struct ieee80211_tx_latency_stat *tx_lat,
+ char *buf, int pos, int bufsz, int tid)
+{
+ u32 avg = 0;
+ int j;
+ int bin_count = tx_lat->bin_count;
+
+ pos += scnprintf(buf + pos, bufsz - pos, "\t\t\t%d", tid);
+ /* make sure you don't divide in 0 */
+ if (tx_lat->counter)
+ avg = tx_lat->sum / tx_lat->counter;
+
+ pos += scnprintf(buf + pos, bufsz - pos, "\t%d\t%d",
+ tx_lat->max, avg);
+
+ if (tx_lat_range->n_ranges && tx_lat->bins)
+ for (j = 0; j < bin_count; j++)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\t%d", tx_lat->bins[j]);
+ pos += scnprintf(buf + pos, bufsz - pos, "\n");
+
+ return pos;
+}
+
+/*
+ * Output Tx latency statistics station && restart all statistics information
+ */
+static ssize_t sta_tx_latency_stat_read(struct file *file,
+ char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct sta_info *sta = file->private_data;
+ struct ieee80211_local *local = sta->local;
+ struct ieee80211_tx_latency_bin_ranges *tx_latency;
+ char *buf;
+ int bufsz, ret, i;
+ int pos = 0;
+
+ bufsz = 20 * IEEE80211_NUM_TIDS *
+ sizeof(struct ieee80211_tx_latency_stat);
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ rcu_read_lock();
+
+ tx_latency = rcu_dereference(local->tx_latency);
+
+ if (!sta->tx_lat) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "Tx latency statistics are not enabled\n");
+ goto unlock;
+ }
+
+ pos = sta_tx_latency_stat_header(tx_latency, buf, pos, bufsz);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", sta->sta.addr);
+ for (i = 0; i < IEEE80211_NUM_TIDS; i++)
+ pos = sta_tx_latency_stat_table(tx_latency, &sta->tx_lat[i],
+ buf, pos, bufsz, i);
+unlock:
+ rcu_read_unlock();
+
+ ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+ kfree(buf);
+
+ return ret;
+}
+STA_OPS(tx_latency_stat);
+
+static ssize_t sta_tx_latency_stat_reset_write(struct file *file,
+ const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ u32 *bins;
+ int bin_count;
+ struct sta_info *sta = file->private_data;
+ int i;
+
+ if (!sta->tx_lat)
+ return -EINVAL;
+
+ for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
+ bins = sta->tx_lat[i].bins;
+ bin_count = sta->tx_lat[i].bin_count;
+
+ sta->tx_lat[i].max = 0;
+ sta->tx_lat[i].sum = 0;
+ sta->tx_lat[i].counter = 0;
+
+ if (bin_count)
+ memset(bins, 0, bin_count * sizeof(u32));
+ }
+
+ return count;
+}
+STA_OPS_W(tx_latency_stat_reset);
+
#define DEBUGFS_ADD(name) \
debugfs_create_file(#name, 0400, \
sta->debugfs.dir, sta, &sta_ ##name## _ops);
@@ -441,6 +573,8 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
DEBUGFS_ADD(last_ack_signal);
DEBUGFS_ADD(current_tx_rate);
DEBUGFS_ADD(last_rx_rate);
+ DEBUGFS_ADD(tx_latency_stat);
+ DEBUGFS_ADD(tx_latency_stat_reset);
DEBUGFS_ADD_COUNTER(rx_packets, rx_packets);
DEBUGFS_ADD_COUNTER(tx_packets, tx_packets);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 29dc505..123beb6 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -896,6 +896,24 @@ struct tpt_led_trigger {
};
#endif
+/*
+ * struct ieee80211_tx_latency_bin_ranges - Tx latency statistics bins ranges
+ *
+ * Measuring Tx latency statistics. Counts how many Tx frames transmitted in a
+ * certain latency range (in Milliseconds). Each station that uses these
+ * ranges will have bins to count the amount of frames received in that range.
+ * The user can configure the ranges via debugfs.
+ * If ranges is NULL then Tx latency statistics bins are disabled for all
+ * stations.
+ *
+ * @n_ranges: number of ranges that are taken in account
+ * @ranges: the ranges that the user requested or NULL if disabled.
+ */
+struct ieee80211_tx_latency_bin_ranges {
+ int n_ranges;
+ u32 ranges[];
+};
+
/**
* mac80211 scan flags - currently active scan mode
*
@@ -1048,6 +1066,12 @@ struct ieee80211_local {
struct timer_list sta_cleanup;
int sta_generation;
+ /*
+ * Tx latency statistics parameters for all stations.
+ * Can enable via debugfs (NULL when disabled).
+ */
+ struct ieee80211_tx_latency_bin_ranges __rcu *tx_latency;
+
struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
struct tasklet_struct tx_pending_tasklet;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 21d5d44..e67dddb 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1087,6 +1087,8 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
ieee80211_free_ack_frame, NULL);
idr_destroy(&local->ack_status_frames);
+ kfree(rcu_access_pointer(local->tx_latency));
+
wiphy_free(local->hw.wiphy);
}
EXPORT_SYMBOL(ieee80211_free_hw);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 1eb66e2..1e17bdc 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -266,9 +266,17 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
*/
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
{
+ int i;
+
if (sta->rate_ctrl)
rate_control_free_sta(sta);
+ if (sta->tx_lat) {
+ for (i = 0; i < IEEE80211_NUM_TIDS; i++)
+ kfree(sta->tx_lat[i].bins);
+ kfree(sta->tx_lat);
+ }
+
sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
kfree(sta);
@@ -333,6 +341,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
struct timespec uptime;
+ struct ieee80211_tx_latency_bin_ranges *tx_latency;
int i;
sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
@@ -410,6 +419,31 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
}
}
+ rcu_read_lock();
+
+ tx_latency = rcu_dereference(local->tx_latency);
+ /* init stations Tx latency statistics && TID bins */
+ if (tx_latency)
+ sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS *
+ sizeof(struct ieee80211_tx_latency_stat),
+ GFP_ATOMIC);
+
+ /*
+ * if Tx latency and bins are enabled and the previous allocation
+ * succeeded
+ */
+ if (tx_latency && tx_latency->n_ranges && sta->tx_lat)
+ for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
+ /* size of bins is size of the ranges +1 */
+ sta->tx_lat[i].bin_count =
+ tx_latency->n_ranges + 1;
+ sta->tx_lat[i].bins = kcalloc(sta->tx_lat[i].bin_count,
+ sizeof(u32),
+ GFP_ATOMIC);
+ }
+
+ rcu_read_unlock();
+
sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
return sta;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 3ef06a2..0683be9 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -220,6 +220,25 @@ struct sta_ampdu_mlme {
u8 dialog_token_allocator;
};
+/*
+ * struct ieee80211_tx_latency_stat - Tx latency statistics
+ *
+ * Measures TX latency and jitter for a station per TID.
+ *
+ * @max: worst case latency
+ * @sum: sum of all latencies
+ * @counter: amount of Tx frames sent from interface
+ * @bins: each bin counts how many frames transmitted within a certain
+ * latency range. when disabled it is NULL.
+ * @bin_count: amount of bins.
+ */
+struct ieee80211_tx_latency_stat {
+ u32 max;
+ u32 sum;
+ u32 counter;
+ u32 *bins;
+ u32 bin_count;
+};
/**
* struct sta_info - STA information
@@ -274,6 +293,7 @@ struct sta_ampdu_mlme {
* @tid_seq: per-TID sequence numbers for sending to this STA
* @ampdu_mlme: A-MPDU state machine state
* @timer_to_tid: identity mapping to ID timers
+ * @tx_lat: Tx latency statistics
* @llid: Local link ID
* @plid: Peer link ID
* @reason: Cancel reason on PLINK_HOLDING state
@@ -380,6 +400,8 @@ struct sta_info {
struct sta_ampdu_mlme ampdu_mlme;
u8 timer_to_tid[IEEE80211_NUM_TIDS];
+ struct ieee80211_tx_latency_stat *tx_lat;
+
#ifdef CONFIG_MAC80211_MESH
/*
* Mesh peer link attributes
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 52a152b..1ee85c4 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -11,6 +11,7 @@
#include <linux/export.h>
#include <linux/etherdevice.h>
+#include <linux/time.h>
#include <net/mac80211.h>
#include <asm/unaligned.h>
#include "ieee80211_i.h"
@@ -463,6 +464,77 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
}
/*
+ * Measure Tx frame completion and removal time for Tx latency statistics
+ * calculation. A single Tx frame latency should be measured from when it
+ * is entering the Kernel until we receive Tx complete confirmation indication
+ * and remove the skb.
+ */
+static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local,
+ struct sk_buff *skb,
+ struct sta_info *sta,
+ struct ieee80211_hdr *hdr)
+{
+ ktime_t skb_dprt;
+ struct timespec dprt_time;
+ u32 msrmnt;
+ u16 tid;
+ u8 *qc;
+ int i, bin_range_count, bin_count;
+ u32 *bin_ranges;
+ __le16 fc;
+ struct ieee80211_tx_latency_stat *tx_lat;
+ struct ieee80211_tx_latency_bin_ranges *tx_latency;
+ ktime_t skb_arv = skb->tstamp;
+
+ tx_latency = rcu_dereference(local->tx_latency);
+
+ /* assert Tx latency stats are enabled & frame arrived when enabled */
+ if (!tx_latency || !ktime_to_ns(skb_arv))
+ return;
+
+ fc = hdr->frame_control;
+
+ if (!ieee80211_is_data(fc)) /* make sure it is a data frame */
+ return;
+
+ /* get frame tid */
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+ } else {
+ tid = 0;
+ }
+
+ tx_lat = &sta->tx_lat[tid];
+
+ ktime_get_ts(&dprt_time); /* time stamp completion time */
+ skb_dprt = ktime_set(dprt_time.tv_sec, dprt_time.tv_nsec);
+ msrmnt = ktime_to_ms(ktime_sub(skb_dprt, skb_arv));
+
+ if (tx_lat->max < msrmnt) /* update stats */
+ tx_lat->max = msrmnt;
+ tx_lat->counter++;
+ tx_lat->sum += msrmnt;
+
+ if (!tx_lat->bins) /* bins not activated */
+ return;
+
+ /* count how many Tx frames transmitted with the appropriate latency */
+ bin_range_count = tx_latency->n_ranges;
+ bin_ranges = tx_latency->ranges;
+ bin_count = tx_lat->bin_count;
+
+ for (i = 0; i < bin_range_count; i++) {
+ if (msrmnt <= bin_ranges[i]) {
+ tx_lat->bins[i]++;
+ break;
+ }
+ }
+ if (i == bin_range_count) /* msrmnt is bigger than the biggest range */
+ tx_lat->bins[i]++;
+}
+
+/*
* Use a static threshold for now, best value to be determined
* by testing ...
* Should it depend on:
@@ -620,6 +692,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
if (acked)
sta->last_ack_signal = info->status.ack_signal;
+
+ /*
+ * Measure frame removal for tx latency
+ * statistics calculation
+ */
+ ieee80211_tx_latency_end_msrmnt(local, skb, sta, hdr);
}
rcu_read_unlock();
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c558b24..a4f282b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -19,6 +19,7 @@
#include <linux/bitmap.h>
#include <linux/rcupdate.h>
#include <linux/export.h>
+#include <linux/time.h>
#include <net/net_namespace.h>
#include <net/ieee80211_radiotap.h>
#include <net/cfg80211.h>
@@ -1740,6 +1741,26 @@ fail:
return NETDEV_TX_OK; /* meaning, we dealt with the skb */
}
+/*
+ * Measure Tx frame arrival time for Tx latency statistics calculation
+ * A single Tx frame latency should be measured from when it is entering the
+ * Kernel until we receive Tx complete confirmation indication and the skb is
+ * freed.
+ */
+static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local,
+ struct sk_buff *skb)
+{
+ struct timespec skb_arv;
+ struct ieee80211_tx_latency_bin_ranges *tx_latency;
+
+ tx_latency = rcu_dereference(local->tx_latency);
+ if (!tx_latency)
+ return;
+
+ ktime_get_ts(&skb_arv);
+ skb->tstamp = ktime_set(skb_arv.tv_sec, skb_arv.tv_nsec);
+}
+
/**
* ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type
* subinterfaces (wlan#, WDS, and VLAN interfaces)
@@ -1790,6 +1811,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
rcu_read_lock();
+ /* Measure frame arrival for Tx latency statistics calculation */
+ ieee80211_tx_latency_start_msrmnt(local, skb);
+
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP_VLAN:
sta = rcu_dereference(sdata->u.vlan.sta);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH RESEND 2/5] mac80211: fix connection polling
2013-11-18 17:06 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Emmanuel Grumbach
@ 2013-11-18 17:06 ` Emmanuel Grumbach
2013-11-19 13:04 ` Stanislaw Gruszka
2013-11-18 17:06 ` [PATCH RESEND 3/5] mac80211: remove sta_info_flush() from interface teardown Emmanuel Grumbach
` (3 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:06 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Eliad Peller
From: Eliad Peller <eliad@wizery.com>
Commit 392b9ff ("mac80211: change beacon/connection polling")
removed the IEEE80211_STA_BEACON_POLL flag.
However, it accidentally removed the setting of
IEEE80211_STA_CONNECTION_POLL, making the connection polling
completely useless (the flag is always clear, so the result
is never being checked). Fix it.
Signed-off-by: Eliad Peller <eliad@wizery.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/mlme.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d7504ab..b3a3ce3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1910,6 +1910,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
already = true;
+ ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
+
mutex_unlock(&sdata->local->mtx);
if (already)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH RESEND 2/5] mac80211: fix connection polling
2013-11-18 17:06 ` [PATCH RESEND 2/5] mac80211: fix connection polling Emmanuel Grumbach
@ 2013-11-19 13:04 ` Stanislaw Gruszka
2013-11-19 14:24 ` Johannes Berg
0 siblings, 1 reply; 18+ messages in thread
From: Stanislaw Gruszka @ 2013-11-19 13:04 UTC (permalink / raw)
To: Emmanuel Grumbach; +Cc: johannes, linux-wireless, Eliad Peller
On Mon, Nov 18, 2013 at 07:06:46PM +0200, Emmanuel Grumbach wrote:
> From: Eliad Peller <eliad@wizery.com>
>
> Commit 392b9ff ("mac80211: change beacon/connection polling")
> removed the IEEE80211_STA_BEACON_POLL flag.
>
> However, it accidentally removed the setting of
> IEEE80211_STA_CONNECTION_POLL, making the connection polling
> completely useless (the flag is always clear, so the result
> is never being checked). Fix it.
Good catch!
Johannes, this patch should be taken to 3.13 queue.
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH RESEND 2/5] mac80211: fix connection polling
2013-11-19 13:04 ` Stanislaw Gruszka
@ 2013-11-19 14:24 ` Johannes Berg
0 siblings, 0 replies; 18+ messages in thread
From: Johannes Berg @ 2013-11-19 14:24 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Emmanuel Grumbach, linux-wireless, Eliad Peller
On Tue, 2013-11-19 at 14:04 +0100, Stanislaw Gruszka wrote:
> On Mon, Nov 18, 2013 at 07:06:46PM +0200, Emmanuel Grumbach wrote:
> > From: Eliad Peller <eliad@wizery.com>
> >
> > Commit 392b9ff ("mac80211: change beacon/connection polling")
> > removed the IEEE80211_STA_BEACON_POLL flag.
> >
> > However, it accidentally removed the setting of
> > IEEE80211_STA_CONNECTION_POLL, making the connection polling
> > completely useless (the flag is always clear, so the result
> > is never being checked). Fix it.
>
> Good catch!
>
> Johannes, this patch should be taken to 3.13 queue.
Alright, done.
johannes
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH RESEND 3/5] mac80211: remove sta_info_flush() from interface teardown
2013-11-18 17:06 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Emmanuel Grumbach
2013-11-18 17:06 ` [PATCH RESEND 2/5] mac80211: fix connection polling Emmanuel Grumbach
@ 2013-11-18 17:06 ` Emmanuel Grumbach
2013-11-18 17:06 ` [PATCH RESEND 4/5] mac80211: update ht flag if bss configuration changed Emmanuel Grumbach
` (2 subsequent siblings)
4 siblings, 0 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:06 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
All interface types now properly clean up their stations
using some form of sta_info_flush() themselves, so there's
no need to try it again at teardown. Remove the call to
get rid of the extra delay from the synchronize_net() and
rcu_barrier() calls.
Reported-by: Moshe Benji <moshe.benji@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/iface.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index ff101ea..a3d106d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1036,7 +1036,6 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
*/
static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
{
- int flushed;
int i;
/* free extra data */
@@ -1050,9 +1049,6 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
if (ieee80211_vif_is_mesh(&sdata->vif))
mesh_rmc_free(sdata);
-
- flushed = sta_info_flush(sdata);
- WARN_ON(flushed);
}
static void ieee80211_uninit(struct net_device *dev)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH RESEND 4/5] mac80211: update ht flag if bss configuration changed
2013-11-18 17:06 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Emmanuel Grumbach
2013-11-18 17:06 ` [PATCH RESEND 2/5] mac80211: fix connection polling Emmanuel Grumbach
2013-11-18 17:06 ` [PATCH RESEND 3/5] mac80211: remove sta_info_flush() from interface teardown Emmanuel Grumbach
@ 2013-11-18 17:06 ` Emmanuel Grumbach
2013-11-18 17:06 ` [PATCH RESEND 5/5] cfg80211: Aggregate mgmt_tx parameters and fix channel setting Emmanuel Grumbach
2013-11-19 15:02 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Johannes Berg
4 siblings, 0 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:06 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avri Altman
From: Avri Altman <avri.altman@intel.com>
The bug concerned failing to update the ht flag properly.
updating the ht flag when bss configuration changes should
be done independently of channel changes.
Signed-off-by: Avri Altman <avri.altman@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/mlme.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b3a3ce3..03aa33f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -330,6 +330,16 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
if (WARN_ON_ONCE(!sta))
return -EINVAL;
+ /*
+ * if bss configuration changed store the new one -
+ * this may be applicable even if channel is identical
+ */
+ ht_opmode = le16_to_cpu(ht_oper->operation_mode);
+ if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
+ *changed |= BSS_CHANGED_HT;
+ sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
+ }
+
chan = sdata->vif.bss_conf.chandef.chan;
sband = local->hw.wiphy->bands[chan->band];
@@ -416,14 +426,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
IEEE80211_RC_BW_CHANGED);
}
- ht_opmode = le16_to_cpu(ht_oper->operation_mode);
-
- /* if bss configuration changed store the new one */
- if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
- *changed |= BSS_CHANGED_HT;
- sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
- }
-
return 0;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH RESEND 5/5] cfg80211: Aggregate mgmt_tx parameters and fix channel setting
2013-11-18 17:06 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Emmanuel Grumbach
` (2 preceding siblings ...)
2013-11-18 17:06 ` [PATCH RESEND 4/5] mac80211: update ht flag if bss configuration changed Emmanuel Grumbach
@ 2013-11-18 17:06 ` Emmanuel Grumbach
2013-11-19 14:26 ` Johannes Berg
2013-11-19 14:35 ` Johannes Berg
2013-11-19 15:02 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Johannes Berg
4 siblings, 2 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-18 17:06 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Andrei Otcheretianski
From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Change cfg80211 and mac80211 to use cfg80211_mgmt_tx_params
struct to aggregate parameters for mgmt_tx functions.
This makes the functions' signatures less clumsy and allows
less painful parameters extension.
The cfg80211_mgmt_tx_params.chan member wasn't set which
caused a bug in offchan operations, fix that too.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/cfg80211.h | 28 +++++++++++++++++++++++++---
net/mac80211/cfg.c | 29 +++++++++++++++--------------
net/wireless/core.h | 5 ++---
net/wireless/mlme.c | 12 ++++--------
net/wireless/nl80211.c | 32 ++++++++++++++++----------------
net/wireless/rdev-ops.h | 12 ++++--------
net/wireless/trace.h | 15 +++++++--------
7 files changed, 73 insertions(+), 60 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3eae46c..54bdded 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1945,6 +1945,29 @@ struct cfg80211_update_ft_ies_params {
};
/**
+ * struct cfg80211_mgmt_tx_params - mgmt tx parameters
+ *
+ * This structure provides information needed to transmit a mgmt frame
+ *
+ * @chan: channel to use
+ * @offchan: indicates wether off channel operation is required
+ * @wait: duration for ROC
+ * @buf: buffer to transmit
+ * @len: buffer length
+ * @no_cck: don't use cck rates for this frame
+ * @dont_wait_for_ack: tells the low level not to wait for an ack
+ */
+struct cfg80211_mgmt_tx_params {
+ struct ieee80211_channel *chan;
+ bool offchan;
+ unsigned int wait;
+ const u8 *buf;
+ size_t len;
+ bool no_cck;
+ bool dont_wait_for_ack;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2342,9 +2365,8 @@ struct cfg80211_ops {
u64 cookie);
int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie);
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie);
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
struct wireless_dev *wdev,
u64 cookie);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 95667b0..9442837 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3146,26 +3146,25 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct sta_info *sta;
- const struct ieee80211_mgmt *mgmt = (void *)buf;
+ const struct ieee80211_mgmt *mgmt = (void *)params->buf;
bool need_offchan = false;
u32 flags;
int ret;
- if (dont_wait_for_ack)
+ if (params->dont_wait_for_ack)
flags = IEEE80211_TX_CTL_NO_ACK;
else
flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
IEEE80211_TX_CTL_REQ_TX_STATUS;
- if (no_cck)
+ if (params->no_cck)
flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
switch (sdata->vif.type) {
@@ -3213,7 +3212,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
/* configurations requiring offchan cannot work if no channel has been
* specified
*/
- if (need_offchan && !chan)
+ if (need_offchan && !params->chan)
return -EINVAL;
mutex_lock(&local->mtx);
@@ -3226,8 +3225,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (chanctx_conf) {
- need_offchan = chan && (chan != chanctx_conf->def.chan);
- } else if (!chan) {
+ need_offchan = params->chan &&
+ (params->chan !=
+ chanctx_conf->def.chan);
+ } else if (!params->chan) {
ret = -EINVAL;
rcu_read_unlock();
goto out_unlock;
@@ -3237,19 +3238,19 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
rcu_read_unlock();
}
- if (need_offchan && !offchan) {
+ if (need_offchan && !params->offchan) {
ret = -EBUSY;
goto out_unlock;
}
- skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + params->len);
if (!skb) {
ret = -ENOMEM;
goto out_unlock;
}
skb_reserve(skb, local->hw.extra_tx_headroom);
- memcpy(skb_put(skb, len), buf, len);
+ memcpy(skb_put(skb, params->len), params->buf, params->len);
IEEE80211_SKB_CB(skb)->flags = flags;
@@ -3269,8 +3270,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
local->hw.offchannel_tx_hw_queue;
/* This will handle all kinds of coalescing and immediate TX */
- ret = ieee80211_start_roc_work(local, sdata, chan,
- wait, cookie, skb,
+ ret = ieee80211_start_roc_work(local, sdata, params->chan,
+ params->wait, cookie, skb,
IEEE80211_ROC_TYPE_MGMT_TX);
if (ret)
kfree_skb(skb);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index eb0f7a3..bff9869 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -317,9 +317,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie);
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie);
void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
const struct ieee80211_ht_cap *ht_capa_mask);
void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 6a6b1c8..a9cecd7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -520,9 +520,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+ struct cfg80211_mgmt_tx_params *params, u64 *cookie)
{
const struct ieee80211_mgmt *mgmt;
u16 stype;
@@ -533,10 +531,10 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
if (!rdev->ops->mgmt_tx)
return -EOPNOTSUPP;
- if (len < 24 + 1)
+ if (params->len < 24 + 1)
return -EINVAL;
- mgmt = (const struct ieee80211_mgmt *) buf;
+ mgmt = (const struct ieee80211_mgmt *)params->buf;
if (!ieee80211_is_mgmt(mgmt->frame_control))
return -EINVAL;
@@ -615,9 +613,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
return -EINVAL;
/* Transmit the Action frame as requested by user space */
- return rdev_mgmt_tx(rdev, wdev, chan, offchan,
- wait, buf, len, no_cck, dont_wait_for_ack,
- cookie);
+ return rdev_mgmt_tx(rdev, wdev, params, cookie);
}
bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a7f4e79..73ca4fc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7428,10 +7428,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
void *hdr = NULL;
u64 cookie;
struct sk_buff *msg = NULL;
- unsigned int wait = 0;
- bool offchan, no_cck, dont_wait_for_ack;
-
- dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
+ struct cfg80211_mgmt_tx_params params = {
+ .dont_wait_for_ack =
+ info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
+ };
if (!info->attrs[NL80211_ATTR_FRAME])
return -EINVAL;
@@ -7458,24 +7458,24 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_DURATION]) {
if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
return -EINVAL;
- wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
+ params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
/*
* We should wait on the channel for at least a minimum amount
* of time (10ms) but no longer than the driver supports.
*/
- if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
- wait > rdev->wiphy.max_remain_on_channel_duration)
+ if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
+ params.wait > rdev->wiphy.max_remain_on_channel_duration)
return -EINVAL;
}
- offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
+ params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
- if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
+ if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
return -EINVAL;
- no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
+ params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
/* get the channel if any has been specified, otherwise pass NULL to
* the driver. The latter will use the current one
@@ -7487,10 +7487,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
return err;
}
- if (!chandef.chan && offchan)
+ if (!chandef.chan && params.offchan)
return -EINVAL;
- if (!dont_wait_for_ack) {
+ if (!params.dont_wait_for_ack) {
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -7503,10 +7503,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
}
}
- err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
- nla_data(info->attrs[NL80211_ATTR_FRAME]),
- nla_len(info->attrs[NL80211_ATTR_FRAME]),
- no_cck, dont_wait_for_ack, &cookie);
+ params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+ params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+ params.chan = chandef.chan;
+ err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie);
if (err)
goto free_msg;
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 37ce9fd..a6c03ab 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -624,16 +624,12 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev,
static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, const u8 *buf, size_t len,
- bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie)
{
int ret;
- trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
- wait, no_cck, dont_wait_for_ack);
- ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
- wait, buf, len, no_cck,
- dont_wait_for_ack, cookie);
+ trace_rdev_mgmt_tx(&rdev->wiphy, wdev, params);
+ ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, params, cookie);
trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
return ret;
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ba5f0d6..f7aa7a7 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1653,9 +1653,8 @@ TRACE_EVENT(rdev_cancel_remain_on_channel,
TRACE_EVENT(rdev_mgmt_tx,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
- struct ieee80211_channel *chan, bool offchan,
- unsigned int wait, bool no_cck, bool dont_wait_for_ack),
- TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack),
+ struct cfg80211_mgmt_tx_params *params),
+ TP_ARGS(wiphy, wdev, params),
TP_STRUCT__entry(
WIPHY_ENTRY
WDEV_ENTRY
@@ -1668,11 +1667,11 @@ TRACE_EVENT(rdev_mgmt_tx,
TP_fast_assign(
WIPHY_ASSIGN;
WDEV_ASSIGN;
- CHAN_ASSIGN(chan);
- __entry->offchan = offchan;
- __entry->wait = wait;
- __entry->no_cck = no_cck;
- __entry->dont_wait_for_ack = dont_wait_for_ack;
+ CHAN_ASSIGN(params->chan);
+ __entry->offchan = params->offchan;
+ __entry->wait = params->wait;
+ __entry->no_cck = params->no_cck;
+ __entry->dont_wait_for_ack = params->dont_wait_for_ack;
),
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s,"
" wait: %u, no cck: %s, dont wait for ack: %s",
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH RESEND 5/5] cfg80211: Aggregate mgmt_tx parameters and fix channel setting
2013-11-18 17:06 ` [PATCH RESEND 5/5] cfg80211: Aggregate mgmt_tx parameters and fix channel setting Emmanuel Grumbach
@ 2013-11-19 14:26 ` Johannes Berg
2013-11-19 14:35 ` Johannes Berg
1 sibling, 0 replies; 18+ messages in thread
From: Johannes Berg @ 2013-11-19 14:26 UTC (permalink / raw)
To: Emmanuel Grumbach; +Cc: linux-wireless, Andrei Otcheretianski
On Mon, 2013-11-18 at 19:06 +0200, Emmanuel Grumbach wrote:
> The cfg80211_mgmt_tx_params.chan member wasn't set which
> caused a bug in offchan operations, fix that too.
That's wrong - that was only true when you took the original patch, not
now with the fix rolled in :-)
I guess I'll edit this out (and from subject too)
johannes
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH RESEND 5/5] cfg80211: Aggregate mgmt_tx parameters and fix channel setting
2013-11-18 17:06 ` [PATCH RESEND 5/5] cfg80211: Aggregate mgmt_tx parameters and fix channel setting Emmanuel Grumbach
2013-11-19 14:26 ` Johannes Berg
@ 2013-11-19 14:35 ` Johannes Berg
2013-11-19 15:19 ` Emmanuel Grumbach
1 sibling, 1 reply; 18+ messages in thread
From: Johannes Berg @ 2013-11-19 14:35 UTC (permalink / raw)
To: Emmanuel Grumbach; +Cc: linux-wireless, Andrei Otcheretianski
On Mon, 2013-11-18 at 19:06 +0200, Emmanuel Grumbach wrote:
> From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
>
> Change cfg80211 and mac80211 to use cfg80211_mgmt_tx_params
> struct to aggregate parameters for mgmt_tx functions.
> This makes the functions' signatures less clumsy and allows
> less painful parameters extension.
Also, technically, this broke a whole bunch of drivers - I'll fix it.
johannes
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH RESEND 5/5] cfg80211: Aggregate mgmt_tx parameters and fix channel setting
2013-11-19 14:35 ` Johannes Berg
@ 2013-11-19 15:19 ` Emmanuel Grumbach
0 siblings, 0 replies; 18+ messages in thread
From: Emmanuel Grumbach @ 2013-11-19 15:19 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Andrei Otcheretianski
Emmanuel Grumbach
egrumbach@gmail.com
On Tue, Nov 19, 2013 at 4:35 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Mon, 2013-11-18 at 19:06 +0200, Emmanuel Grumbach wrote:
>> From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
>>
>> Change cfg80211 and mac80211 to use cfg80211_mgmt_tx_params
>> struct to aggregate parameters for mgmt_tx functions.
>> This makes the functions' signatures less clumsy and allows
>> less painful parameters extension.
>
> Also, technically, this broke a whole bunch of drivers - I'll fix it.
>
oh well....
Thanks:)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH RESEND 1/5] mac80211: Tx frame latency statistics
2013-11-18 17:06 ` [PATCH RESEND 1/5] mac80211: Tx frame latency statistics Emmanuel Grumbach
` (3 preceding siblings ...)
2013-11-18 17:06 ` [PATCH RESEND 5/5] cfg80211: Aggregate mgmt_tx parameters and fix channel setting Emmanuel Grumbach
@ 2013-11-19 15:02 ` Johannes Berg
4 siblings, 0 replies; 18+ messages in thread
From: Johannes Berg @ 2013-11-19 15:02 UTC (permalink / raw)
To: Emmanuel Grumbach; +Cc: linux-wireless, Matti Gottlieb
Applied all.
johannes
^ permalink raw reply [flat|nested] 18+ messages in thread