From: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: "Luis R . Rodriguez" <rodrigue@qca.qualcomm.com>,
Jouni Malinen <jouni@qca.qualcomm.com>,
"John W . Linville" <linville@tuxdriver.com>,
<linux-wireless@vger.kernel.org>
Subject: Re: [RFC] P2P find offload
Date: Sun, 10 Mar 2013 17:43:55 +0200 [thread overview]
Message-ID: <2799886.P5v870j3h2@lx-vladimir> (raw)
In-Reply-To: <1628850.y8u4o7KRXH@lx-vladimir>
On Thursday, March 07, 2013 04:10:37 PM Vladimir Kondratiev wrote:
> On Thursday, March 07, 2013 11:08:58 AM Johannes Berg wrote:
> > > + int n_channels;
> > > + /* Up to 4 social channels: 3 in 2.4GHz band + 1 in 60GHz band */
> > > + struct ieee80211_channel *channels[4];
> >
> > Hmm, is 4 really a good limit?
Allocated dynamically
> > > + * start_p2p_find: start P2P find phase
> > > + * Parameters include IEs for probe/probe resp and channels to operate on
> >
> > The parameters?
Documented
> > > + i = 0;
> > > + if (attr_freq) {
> >
> > i can be inside the if()?
Moved to initializer
>
> >
> > > + /* user specified, bail out if channel not found */
> > > + nla_for_each_nested(attr, attr_freq, tmp) {
> > > + struct ieee80211_channel *chan;
> > > +
> > > + chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
> > > +
> > > + if (!chan)
> > > + return -EINVAL;
> > > +
> > > + /* ignore disabled channels */
> > > + if (chan->flags & IEEE80211_CHAN_DISABLED)
> > > + continue;
> >
> > I think you should reject them, also if they have passive scan or
> > various other flags set, I think?
> Passive channel may be used as social for the listening; and may be
> actively scanned if beacon found on the channel. Scan do not filter
> based on these flags, I suppose same reason apply here.
>
> >
> > > + params.channels[i] = chan;
> > > + i++;
> > > + }
> > > + if (!i)
> > > + return -EINVAL;
> > > + }
> > > +
> > > + params.n_channels = i;
> >
> > if you also move that assignment
> >
> > > + i = 0;
> >
> > Not needed.
Sure, done
> >
> > > + attr = info->attrs[NL80211_ATTR_IE];
> > > + if (attr) {
> >
> > This is not typically done in nl80211, I'd prefer not having the
> > variable I think.
> It is to reasonable fit code into 80 columns. Let me know if this
> argument don't play for you, I'll revert to variables.
>
> >
> > > + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> > > + if (!msg)
> > > + return -ENOMEM;
> > > +
> > > + hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
> > > + NL80211_CMD_START_P2P_FIND);
> >
> > Err? What's the value of sending a reply back here? It would seem maybe
> > appropriate to send one when it *actually* started, but you haven't
> > implemented that.
> >
> > > + hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
> > > + NL80211_CMD_STOP_P2P_FIND);
> >
> > same here ...
Removed; notification function added
>
> >
> > You're also entirely missing feature advertising, so userspace can only
> > guess whether it's supported or not ...
Done
>
> >Also ...
> >
> > I really don't think this should be supported on IBSS/AP/... netdevs.
> > Seems like the only reasonable ones are P2P_DEVICE and STATION, although
> > it would probably be good to have feature advertising for both, or
> > document that if P2P_DEVICE is supported at all then this doesn't have
> > to be supported on STATION interfaces, or so.
Done
> >
> > And then ... should this really be allowed to be concurrent with
> > scanning/remain-on-channel? You haven't done any checking or
> > documentation, so users and driver authors are left to guess.
Documented
I added relevant parameters for the find phase timing, accordingly to the spec.
And finally, rebased to recent wireless-testing.
>From c7e67726b042f6ed490858b02a6d1961be22bfa4 Mon Sep 17 00:00:00 2001
From: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Date: Sun, 10 Mar 2013 15:52:37 +0200
Subject: [PATCH v2] cfg80211: P2P find phase offload
Allow to implement P2P find phase in the driver/firmware.
Offload scheme designed as follows:
- Driver provide methods start_p2p_find and stop_p2p_find in the cfg80211_ops;
indicates support for p2p find offload by setting feature
NL80211_FEATURE_P2P_FIND_OFFLOAD
- Driver indicate firmware or driver responds to the probe requests by setting
feature NL80211_FEATURE_P2P_PROBE_RESP_OFFLOAD
- wpa_supplicant analyses feature flags to discover p2p find offload support;
to perform p2p scan, wpa_supplicant:
- perform legacy scan, through driver's cfg80211_ops 'scan' method
- configure rx management filter to get probe-request and probe-response frames
- start p2p find via driver's cfg80211_ops start_p2p_find method
- driver start p2p find with hardware and notify wpa_supplicant with
cfg80211_p2p_find_notify(NL80211_CMD_START_P2P_FIND)
- driver/firmware toggle search/listen states. Received probe-request and
probe-response frames passed to the wpa_supplicant via cfg80211_rx_mgmt
- when wpa_supplicant wants to stop p2p find, it calls driver's cfg80211_ops stop_p2p_find
method. Alternatively, driver/firmware may decide to stop p2p find. In all cases,
driver notifies wpa_supplicant using
cfg80211_p2p_find_notify(NL80211_CMD_STOP_P2P_FIND)
All driver to user space communication done through nl80211 layer.
Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
---
include/net/cfg80211.h | 53 ++++++++++++++
include/uapi/linux/nl80211.h | 16 +++++
net/wireless/nl80211.c | 157 ++++++++++++++++++++++++++++++++++++++++++
net/wireless/rdev-ops.h | 19 +++++
net/wireless/trace.h | 35 ++++++++++
5 files changed, 280 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bdba9b6..ef276f6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1780,6 +1780,30 @@ struct cfg80211_update_ft_ies_params {
};
/**
+ * struct cfg80211_p2p_find_params - parameters for P2P find
+ * @probe_ie: IE's for probe frames
+ * @probe_ie_len: length, bytes, of @probe_ie
+ * @probe_resp_ie: IE's for probe response frames
+ * @probe_resp_ie_len: length, bytes, of @probe_resp_ie
+ * @min_discoverable_interval and
+ * @max_discoverable_interval: min/max for random multiplier of 100TU's
+ * for the listen state duration
+ * @n_channels: number of channels to operate on
+ * @channels: channels to operate on
+ */
+struct cfg80211_p2p_find_params {
+ const u8 *probe_ie;
+ size_t probe_ie_len;
+ const u8 *probe_resp_ie;
+ size_t probe_resp_ie_len;
+ u32 min_discoverable_interval;
+ u32 max_discoverable_interval;
+
+ int n_channels;
+ struct ieee80211_channel **channels;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -1998,6 +2022,15 @@ struct cfg80211_update_ft_ies_params {
* advertise the support for MAC based ACL have to implement this callback.
*
* @start_radar_detection: Start radar detection in the driver.
+ *
+ * start_p2p_find: start P2P find phase
+ * Parameters include IEs for probe/probe-resp frames;
+ * and channels to operate on.
+ * Parameters are not retained after call, driver need to copy data if
+ * it need it later.
+ * P2P find can't run concurrently with ROC or scan, and driver should
+ * check this.
+ * stop_p2p_find: stop P2P find phase
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2227,6 +2260,12 @@ struct cfg80211_ops {
struct cfg80211_chan_def *chandef);
int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_update_ft_ies_params *ftie);
+
+ int (*start_p2p_find)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct cfg80211_p2p_find_params *params);
+ void (*stop_p2p_find)(struct wiphy *wiphy,
+ struct wireless_dev *wdev);
};
/*
@@ -4122,6 +4161,20 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
struct cfg80211_wowlan_wakeup *wakeup,
gfp_t gfp);
+/**
+ * cfg80211_p2p_find_notify - report p2p find state change
+ * @wdev: the wireless device reporting the event
+ * @cmd: the event, NL80211_CMD_START_P2P_FIND or NL80211_CMD_STOP_P2P_FIND
+ * @gfp: allocation flags
+ *
+ * This function reports p2p find state chenge for the given device
+ * When hardware actually starts p2p find, NL80211_CMD_START_P2P_FIND
+ * should be reported
+ * When p2p find finished, either unsolicited or in response to
+ * @ops->p2p_stop_find, NL80211_CMD_STOP_P2P_FIND should be reported
+ */
+void cfg80211_p2p_find_notify(struct wireless_dev *wdev, int cmd, gfp_t gfp);
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 79da871..8c87815 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -798,6 +798,9 @@ enum nl80211_commands {
NL80211_CMD_UPDATE_FT_IES,
NL80211_CMD_FT_EVENT,
+ NL80211_CMD_START_P2P_FIND,
+ NL80211_CMD_STOP_P2P_FIND,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1414,6 +1417,10 @@ enum nl80211_commands {
* @NL80211_ATTR_IE_RIC: Resource Information Container Information
* Element
*
+ * @NL80211_ATTR_MIN_DISCOVERABLE_INTERVAL,
+ * @NL80211_ATTR_MAX_DISCOVERABLE_INTERVAL: min/max discoverable interval
+ * for the p2p find, represented as u32
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1709,6 +1716,9 @@ enum nl80211_attrs {
NL80211_ATTR_MDID,
NL80211_ATTR_IE_RIC,
+ NL80211_ATTR_MIN_DISCOVERABLE_INTERVAL,
+ NL80211_ATTR_MAX_DISCOVERABLE_INTERVAL,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -3538,6 +3548,10 @@ enum nl80211_ap_sme_features {
* Peering Management entity which may be implemented by registering for
* beacons or NL80211_CMD_NEW_PEER_CANDIDATE events. The mesh beacon is
* still generated by the driver.
+ * @NL80211_FEATURE_P2P_FIND_OFFLOAD: The driver supports P2P find phase
+ * offload.
+ * @NL80211_FEATURE_P2P_PROBE_RESP_OFFLOAD: When in P2P find phase,
+ * the device responds to probe-requests in hardware.
*/
enum nl80211_feature_flags {
NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
@@ -3557,6 +3571,8 @@ enum nl80211_feature_flags {
NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15,
NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
+ NL80211_FEATURE_P2P_FIND_OFFLOAD = 1 << 17,
+ NL80211_FEATURE_P2P_PROBE_RESP_OFFLOAD = 1 << 18,
};
/**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f924d45..d51aa2c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -378,6 +378,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_MDID] = { .type = NLA_U16 },
[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
+ [NL80211_ATTR_MIN_DISCOVERABLE_INTERVAL] = { .type = NLA_U32 },
+ [NL80211_ATTR_MAX_DISCOVERABLE_INTERVAL] = { .type = NLA_U32 },
};
/* policy for the key attributes */
@@ -1417,6 +1419,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
}
CMD(start_p2p_device, START_P2P_DEVICE);
CMD(set_mcast_rate, SET_MCAST_RATE);
+ CMD(start_p2p_find, START_P2P_FIND);
+ CMD(stop_p2p_find, STOP_P2P_FIND);
#ifdef CONFIG_NL80211_TESTMODE
CMD(testmode_cmd, TESTMODE);
@@ -8196,6 +8200,115 @@ static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
return rdev_update_ft_ies(rdev, dev, &ft_params);
}
+static int nl80211_start_p2p_find(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct wireless_dev *wdev = info->user_ptr[1];
+ struct wiphy *wiphy = &rdev->wiphy;
+ struct cfg80211_p2p_find_params params = {};
+ struct nlattr *attr_freq = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES];
+ struct nlattr *attr;
+ int err, tmp, n_channels, i = 0;
+ struct ieee80211_channel **channels = NULL;
+
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_P2P_DEVICE:
+ case NL80211_IFTYPE_STATION:
+ break;
+ default:
+ return -EOPNOTSUPP;
+
+ }
+
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]))
+ return -EINVAL;
+
+ if (!(wiphy->features & NL80211_FEATURE_P2P_FIND_OFFLOAD) ||
+ !rdev->ops->start_p2p_find || !rdev->ops->stop_p2p_find)
+ return -EOPNOTSUPP;
+
+ if (rdev->scan_req)
+ return -EBUSY;
+
+ if (attr_freq) {
+ n_channels = validate_scan_freqs(attr_freq);
+ if (!n_channels)
+ return -EINVAL;
+
+ channels = kzalloc(n_channels * sizeof(*channels), GFP_KERNEL);
+ if (!channels)
+ return -ENOMEM;
+
+ /* user specified, bail out if channel not found */
+ nla_for_each_nested(attr, attr_freq, tmp) {
+ struct ieee80211_channel *chan;
+
+ chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
+
+ if (!chan)
+ return -EINVAL;
+
+ /* ignore disabled channels */
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ params.channels[i] = chan;
+ i++;
+ }
+ if (!i) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ params.n_channels = i;
+ params.channels = channels;
+ }
+
+
+ attr = info->attrs[NL80211_ATTR_IE];
+ if (attr) {
+ params.probe_ie_len = nla_len(attr);
+ params.probe_ie = nla_data(attr);
+ }
+
+ attr = info->attrs[NL80211_ATTR_IE_PROBE_RESP];
+ if (attr) {
+ params.probe_resp_ie_len = nla_len(attr);
+ params.probe_resp_ie = nla_data(attr);
+ }
+
+ attr = info->attrs[NL80211_ATTR_MIN_DISCOVERABLE_INTERVAL];
+ if (attr)
+ params.min_discoverable_interval = nla_get_u32(attr);
+
+ attr = info->attrs[NL80211_ATTR_MAX_DISCOVERABLE_INTERVAL];
+ if (attr)
+ params.max_discoverable_interval = nla_get_u32(attr);
+
+ err = rdev_start_p2p_find(rdev, wdev, ¶ms);
+
+out_free:
+ kfree(channels);
+
+ return err;
+}
+
+static int nl80211_stop_p2p_find(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct wireless_dev *wdev = info->user_ptr[1];
+
+ if (!rdev->ops->start_p2p_find || !rdev->ops->stop_p2p_find)
+ return -EOPNOTSUPP;
+
+ rdev_stop_p2p_find(rdev, wdev);
+
+ return 0;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -8873,6 +8986,22 @@ static struct genl_ops nl80211_ops[] = {
NL80211_FLAG_NEED_RTNL,
},
{
+ .cmd = NL80211_CMD_START_P2P_FIND,
+ .doit = nl80211_start_p2p_find,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_STOP_P2P_FIND,
+ .doit = nl80211_stop_p2p_find,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
.cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
.doit = nl80211_get_protocol_features,
.policy = nl80211_policy,
@@ -10547,6 +10676,34 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
}
EXPORT_SYMBOL(cfg80211_tdls_oper_request);
+void cfg80211_p2p_find_notify(struct wireless_dev *wdev, int cmd, gfp_t gfp)
+{
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+
+ trace_cfg80211_p2p_find_notify(wdev, cmd);
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_scan_mcgrp.id, GFP_KERNEL);
+}
+EXPORT_SYMBOL(cfg80211_p2p_find_notify);
+
static int nl80211_netlink_notify(struct notifier_block * nb,
unsigned long state,
void *_notify)
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index d77e1c1..5e43d50 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -901,4 +901,23 @@ static inline int rdev_update_ft_ies(struct cfg80211_registered_device *rdev,
return ret;
}
+static inline int rdev_start_p2p_find(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
+ struct cfg80211_p2p_find_params *params)
+{
+ int ret;
+ trace_rdev_start_p2p_find(&rdev->wiphy, wdev, params);
+ ret = rdev->ops->start_p2p_find(&rdev->wiphy, wdev, params);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
+static inline void rdev_stop_p2p_find(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev)
+{
+ trace_rdev_stop_p2p_find(&rdev->wiphy, wdev);
+ rdev->ops->stop_p2p_find(&rdev->wiphy, wdev);
+ trace_rdev_return_void(&rdev->wiphy);
+}
+
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 23e063b..850dd3b 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1805,6 +1805,26 @@ TRACE_EVENT(rdev_update_ft_ies,
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->md)
);
+TRACE_EVENT(rdev_start_p2p_find,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+ struct cfg80211_p2p_find_params *params),
+ TP_ARGS(wiphy, wdev, params),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ WDEV_ENTRY
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ WDEV_ASSIGN;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
+);
+
+DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_p2p_find,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+ TP_ARGS(wiphy, wdev)
+);
+
/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/
@@ -2459,6 +2479,21 @@ TRACE_EVENT(cfg80211_ft_event,
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap))
);
+TRACE_EVENT(cfg80211_p2p_find_notify,
+ TP_PROTO(struct wireless_dev *wdev, int cmd),
+ TP_ARGS(wdev, cmd),
+ TP_STRUCT__entry(
+ WDEV_ENTRY
+ __field(int, cmd)
+ ),
+ TP_fast_assign(
+ WDEV_ASSIGN;
+ __entry->cmd = cmd;
+ ),
+ TP_printk(WDEV_PR_FMT ", cmd: %d", WDEV_PR_ARG,
+ __entry->cmd)
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
--
1.7.10.4
next prev parent reply other threads:[~2013-03-10 15:43 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-27 12:24 [RFC] P2P find offload Vladimir Kondratiev
2013-03-04 15:47 ` Johannes Berg
2013-03-07 7:10 ` Vladimir Kondratiev
2013-03-07 9:31 ` Vladimir Kondratiev
2013-03-07 10:08 ` Johannes Berg
2013-03-07 10:11 ` Johannes Berg
2013-03-07 14:10 ` Vladimir Kondratiev
2013-03-10 15:43 ` Vladimir Kondratiev [this message]
2013-03-15 18:40 ` Johannes Berg
2013-03-17 8:56 ` Vladimir Kondratiev
2013-03-18 20:31 ` Johannes Berg
[not found] ` <3959922.dEpYdEMVAq@lx-vladimir>
2013-03-19 20:27 ` Johannes Berg
2013-03-15 15:51 ` Johannes Berg
2013-03-07 10:01 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2799886.P5v870j3h2@lx-vladimir \
--to=qca_vkondrat@qca.qualcomm.com \
--cc=johannes@sipsolutions.net \
--cc=jouni@qca.qualcomm.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=rodrigue@qca.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox