From: Pooventhiran G <pooventhiran.g@oss.qualcomm.com>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org,
pooventhiran.g@oss.qualcomm.com
Subject: [PATCH wireless-next v4 09/21] wifi: nl80211/cfg80211: add support for SMD context programming
Date: Fri, 06 Nov 2026 13:28:46 +0530 [thread overview]
Message-ID: <20261106-smd-v4-9-62e39487f51a@oss.qualcomm.com> (raw)
In-Reply-To: <20261106-smd-v4-0-62e39487f51a@oss.qualcomm.com>
On the target AP MLD to which the STA will be transitioning, the dynamic
context collected and sent by the current AP MLD needs to be programmed
on the TX and RX queues to enable seamless transition and reception.
Such data include Sequence Number (SN), Packet Number (PN), BlockAck
sessions, and any driver-specific data.
Add nl80211 support to handle NL80211_CMD_SET_SMD_CTX, parse the SMD
context attributes, and invoke the cfg80211 operation on the target AP
MLD.
Signed-off-by: Pooventhiran G <pooventhiran.g@oss.qualcomm.com>
---
include/net/cfg80211.h | 7 +
net/wireless/nl80211.c | 347 ++++++++++++++++++++++++++++++++++++++++++++++++
net/wireless/rdev-ops.h | 14 ++
net/wireless/trace.h | 35 +++++
4 files changed, 403 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 877845477ce9..42cfdc885c90 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5361,6 +5361,10 @@ struct cfg80211_smd_transition_info {
*
* @start_pd: Start the PD interface.
* @stop_pd: Stop the PD interface.
+ *
+ * @set_smd_ctx: Set UHR SMD context data for the non-AP MLD. @st_info->ctx is
+ * freed immediately after this call returns; drivers must copy
+ * @st_info->ctx if asynchronous processing is required.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -5759,6 +5763,9 @@ struct cfg80211_ops {
bool val);
int (*start_pd)(struct wiphy *wiphy, struct wireless_dev *wdev);
void (*stop_pd)(struct wiphy *wiphy, struct wireless_dev *wdev);
+ int (*set_smd_ctx)(struct wiphy *wiphy, struct wireless_dev *wdev,
+ const u8 *addr,
+ struct cfg80211_smd_transition_info *st_info);
};
/*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 33e52b8bb5fa..249d7a3c2841 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -20413,6 +20413,310 @@ static int nl80211_put_smd_ctx(struct sk_buff *msg,
return -EINVAL;
}
+static int
+nl80211_parse_smd_ctx_ba_params(struct nlattr *tb,
+ struct ieee80211_smd_ctx_ba *ba_tids)
+{
+ struct nlattr *ba_tb[NL80211_SMD_CTX_BA_ATTR_MAX + 1];
+ struct ieee80211_smd_ctx_ba *ba;
+ struct nlattr *ba_attr;
+ int n_tids = 0;
+ int rem, tid;
+
+ nla_for_each_nested(ba_attr, tb, rem) {
+ tid = nla_type(ba_attr) - 1;
+ if (tid < 0 || tid >= IEEE80211_SMD_CTX_NUM_TIDS)
+ return -EINVAL;
+
+ if (nla_parse_nested(ba_tb, NL80211_SMD_CTX_BA_ATTR_MAX,
+ ba_attr, nl80211_smd_ctx_ba_policy,
+ NULL))
+ return -EINVAL;
+
+ ba = &ba_tids[tid];
+
+ if (ba_tb[NL80211_SMD_CTX_BA_ATTR_BUFF_SIZE])
+ ba->buffer_size =
+ nla_get_u16(ba_tb[NL80211_SMD_CTX_BA_ATTR_BUFF_SIZE]);
+
+ if (ba_tb[NL80211_SMD_CTX_BA_ATTR_POLICY])
+ ba->ba_policy =
+ nla_get_u8(ba_tb[NL80211_SMD_CTX_BA_ATTR_POLICY]);
+
+ ba->amsdu_supported =
+ !!ba_tb[NL80211_SMD_CTX_BA_ATTR_AMSDU_SUPPORT];
+
+ if (ba_tb[NL80211_SMD_CTX_BA_ATTR_TIMEOUT])
+ ba->timeout =
+ nla_get_u16(ba_tb[NL80211_SMD_CTX_BA_ATTR_TIMEOUT]);
+
+ ba->ext_no_frag = !!ba_tb[NL80211_SMD_CTX_BA_ATTR_EXT_NO_FRAG];
+
+ if (ba_tb[NL80211_SMD_CTX_BA_ATTR_EXT_FRAG_LEVEL])
+ ba->extfrag_level =
+ nla_get_u8(ba_tb[NL80211_SMD_CTX_BA_ATTR_EXT_FRAG_LEVEL]);
+
+ if (ba_tb[NL80211_SMD_CTX_BA_ATTR_EXT_BUFF_SIZE])
+ ba->ext_buffer_size =
+ nla_get_u16(ba_tb[NL80211_SMD_CTX_BA_ATTR_EXT_BUFF_SIZE]);
+
+ if (ba_tb[NL80211_SMD_CTX_BA_ATTR_WINSTARTO])
+ ba->winstarto =
+ nla_get_u16(ba_tb[NL80211_SMD_CTX_BA_ATTR_WINSTARTO]);
+
+ n_tids++;
+ }
+
+ if (!n_tids)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int nl80211_parse_smd_ctx(struct genl_info *info,
+ struct cfg80211_smd_transition_info *st_info)
+{
+ struct nlattr *dl_tb[NL80211_SMD_CTX_DL_ATTR_MAX + 1];
+ struct nlattr *ul_tb[NL80211_SMD_CTX_UL_ATTR_MAX + 1];
+ struct nlattr *tb[NL80211_SMD_CTX_ATTR_MAX + 1];
+ struct ieee80211_smd_ctx *ctx;
+ struct nlattr *bmap_attr;
+
+ st_info->type = nla_get_u8(info->attrs[NL80211_ATTR_SMD_CTX_TYPE]);
+
+ if (nla_parse_nested(tb, NL80211_SMD_CTX_ATTR_MAX,
+ info->attrs[NL80211_ATTR_SMD_CTX],
+ nl80211_smd_ctx_policy, NULL)) {
+ GENL_SET_ERR_MSG(info, "failed to parse SMD context");
+ return -EINVAL;
+ }
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ st_info->ctx = ctx;
+
+ /* DL Context */
+ if (tb[NL80211_SMD_CTX_ATTR_DL]) {
+ struct nlattr *ba_attr;
+
+ if (nla_parse_nested(dl_tb, NL80211_SMD_CTX_DL_ATTR_MAX,
+ tb[NL80211_SMD_CTX_ATTR_DL],
+ nl80211_smd_ctx_dl_policy, NULL)) {
+ GENL_SET_ERR_MSG(info, "failed to parse DL context");
+ goto err_free_ctx;
+ }
+
+ bmap_attr = dl_tb[NL80211_SMD_CTX_DL_ATTR_VALID_TID_BITMAP];
+ if (bmap_attr)
+ ctx->dl.valid_tid_bmap = nla_get_u8(bmap_attr);
+
+ if (dl_tb[NL80211_SMD_CTX_DL_ATTR_SN]) {
+ struct nlattr *sn_attr;
+ int n_tids = 0;
+ int rem, tid;
+
+ nla_for_each_nested(sn_attr,
+ dl_tb[NL80211_SMD_CTX_DL_ATTR_SN],
+ rem) {
+ tid = nla_type(sn_attr) - 1;
+ if (tid < 0 ||
+ tid >= IEEE80211_SMD_CTX_NUM_TIDS) {
+ GENL_SET_ERR_MSG(info,
+ "invalid DL SN tid");
+ goto err_free_ctx;
+ }
+
+ if (nla_len(sn_attr) != sizeof(u16)) {
+ GENL_SET_ERR_MSG(info,
+ "invalid DL SN len");
+ goto err_free_ctx;
+ }
+
+ ctx->dl.sn[tid] = nla_get_u16(sn_attr);
+ n_tids++;
+ }
+
+ if (!n_tids) {
+ GENL_SET_ERR_MSG(info, "empty DL SN nesting");
+ goto err_free_ctx;
+ }
+
+ ctx->dl_sn_valid = 1;
+ }
+
+ if (dl_tb[NL80211_SMD_CTX_DL_ATTR_PN]) {
+ const u8 *pn_data =
+ nla_data(dl_tb[NL80211_SMD_CTX_DL_ATTR_PN]);
+
+ ctx->pn_len =
+ nla_len(dl_tb[NL80211_SMD_CTX_DL_ATTR_PN]);
+ if (ctx->pn_len > IEEE80211_SMD_CTX_MAX_PN_LEN) {
+ GENL_SET_ERR_MSG(info, "invalid DL PN length");
+ goto err_free_ctx;
+ }
+
+ memcpy(ctx->dl.pn, pn_data, ctx->pn_len);
+ ctx->pn_valid = 1;
+ }
+
+ ba_attr = dl_tb[NL80211_SMD_CTX_DL_ATTR_BA_PARAMS];
+ if (ba_attr) {
+ if (nl80211_parse_smd_ctx_ba_params(ba_attr,
+ ctx->dl.ba)) {
+ GENL_SET_ERR_MSG(info,
+ "failed to parse DL BlockAck params");
+ goto err_free_ctx;
+ }
+
+ ctx->ba_params_valid = 1;
+ }
+
+ if (dl_tb[NL80211_SMD_CTX_DL_ATTR_MGMT_SN]) {
+ ctx->dl.mgmt_sn =
+ nla_get_u16(dl_tb[NL80211_SMD_CTX_DL_ATTR_MGMT_SN]);
+ ctx->mgmt_tid_valid = 1;
+ ctx->dl_sn_valid = 1;
+ }
+ }
+
+ /* UL Context */
+ if (tb[NL80211_SMD_CTX_ATTR_UL]) {
+ struct nlattr *ba_attr;
+
+ if (nla_parse_nested(ul_tb, NL80211_SMD_CTX_UL_ATTR_MAX,
+ tb[NL80211_SMD_CTX_ATTR_UL],
+ nl80211_smd_ctx_ul_policy, NULL)) {
+ GENL_SET_ERR_MSG(info, "failed to parse UL context");
+ goto err_free_ctx;
+ }
+
+ bmap_attr = ul_tb[NL80211_SMD_CTX_UL_ATTR_VALID_TID_BITMAP];
+ if (bmap_attr)
+ ctx->ul.valid_tid_bmap = nla_get_u8(bmap_attr);
+
+ if (ul_tb[NL80211_SMD_CTX_UL_ATTR_SN]) {
+ struct nlattr *sn_attr;
+ int n_tids = 0;
+ int rem, tid;
+
+ nla_for_each_nested(sn_attr,
+ ul_tb[NL80211_SMD_CTX_UL_ATTR_SN],
+ rem) {
+ tid = nla_type(sn_attr) - 1;
+ if (tid < 0 ||
+ tid >= IEEE80211_SMD_CTX_NUM_TIDS) {
+ GENL_SET_ERR_MSG(info,
+ "invalid UL SN tid");
+ goto err_free_ctx;
+ }
+
+ if (nla_len(sn_attr) != sizeof(u16)) {
+ GENL_SET_ERR_MSG(info,
+ "invalid UL SN len");
+ goto err_free_ctx;
+ }
+
+ ctx->ul.sn[tid] = nla_get_u16(sn_attr);
+ n_tids++;
+ }
+
+ if (!n_tids) {
+ GENL_SET_ERR_MSG(info, "empty UL SN nesting");
+ goto err_free_ctx;
+ }
+
+ ctx->ul_sn_valid = 1;
+ }
+
+ if (ul_tb[NL80211_SMD_CTX_UL_ATTR_PN]) {
+ struct nlattr *pn_attr;
+ int n_tids = 0;
+ int rem, tid;
+
+ nla_for_each_nested(pn_attr,
+ ul_tb[NL80211_SMD_CTX_UL_ATTR_PN],
+ rem) {
+ u8 pn_len;
+
+ tid = nla_type(pn_attr) - 1;
+ if (tid < 0 ||
+ tid >= IEEE80211_SMD_CTX_NUM_TIDS) {
+ GENL_SET_ERR_MSG(info,
+ "invalid UL PN tid");
+ goto err_free_ctx;
+ }
+
+ /*
+ * PN length must be the same for all DL and
+ * UL TIDs.
+ */
+ pn_len = nla_len(pn_attr);
+ if (pn_len > IEEE80211_SMD_CTX_MAX_PN_LEN ||
+ (ctx->pn_len && pn_len != ctx->pn_len)) {
+ GENL_SET_ERR_MSG(info,
+ "invalid PN length");
+ goto err_free_ctx;
+ }
+ ctx->pn_len = pn_len;
+
+ memcpy(ctx->ul.pn[tid], nla_data(pn_attr),
+ ctx->pn_len);
+ n_tids++;
+ }
+
+ if (!n_tids) {
+ GENL_SET_ERR_MSG(info, "empty UL PN nesting");
+ goto err_free_ctx;
+ }
+
+ ctx->pn_valid = 1;
+ }
+
+ ba_attr = ul_tb[NL80211_SMD_CTX_UL_ATTR_BA_PARAMS];
+ if (ba_attr) {
+ if (nl80211_parse_smd_ctx_ba_params(ba_attr,
+ ctx->ul.ba)) {
+ GENL_SET_ERR_MSG(info,
+ "failed to parse UL BlockAck params");
+ goto err_free_ctx;
+ }
+
+ ctx->ba_params_valid = 1;
+ }
+
+ if (ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_SN]) {
+ ctx->ul.mgmt_sn =
+ nla_get_u16(ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_SN]);
+ ctx->mgmt_tid_valid = 1;
+ ctx->ul_sn_valid = 1;
+ }
+
+ if (ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_PN]) {
+ u8 pn_len = nla_len(ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_PN]);
+
+ if (pn_len > IEEE80211_SMD_CTX_MAX_PN_LEN ||
+ (ctx->pn_len && pn_len != ctx->pn_len)) {
+ GENL_SET_ERR_MSG(info, "invalid UL mgmt PN length");
+ goto err_free_ctx;
+ }
+ memcpy(ctx->ul.mgmt_pn,
+ nla_data(ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_PN]),
+ pn_len);
+ ctx->mgmt_tid_valid = 1;
+ ctx->pn_valid = 1;
+ }
+ }
+
+ return 0;
+
+err_free_ctx:
+ kfree(ctx);
+ st_info->ctx = NULL;
+ return -EINVAL;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -20845,6 +21149,42 @@ static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
return err;
}
+static int nl80211_set_smd_ctx(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct cfg80211_smd_transition_info st_info = {};
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ const u8 *addr;
+ int err;
+
+ if (!rdev->ops->set_smd_ctx)
+ return -EOPNOTSUPP;
+
+ if (wdev->iftype != NL80211_IFTYPE_AP &&
+ wdev->iftype != NL80211_IFTYPE_AP_VLAN)
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_MLD_ADDR] ||
+ !info->attrs[NL80211_ATTR_SMD_CTX] ||
+ !info->attrs[NL80211_ATTR_SMD_CTX_TYPE]) {
+ GENL_SET_ERR_MSG(info, "required attributes are missing");
+ return -EINVAL;
+ }
+
+ addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
+
+ err = nl80211_parse_smd_ctx(info, &st_info);
+ if (err)
+ return err;
+
+ /* drivers must copy @ctx for any deferred processing */
+ err = rdev_set_smd_ctx(rdev, wdev, addr, &st_info);
+
+ kfree(st_info.ctx);
+ return err;
+}
+
#define SELECTOR(__sel, name, value) \
((__sel) == (value)) ? NL80211_IFL_SEL_##name :
int __missing_selector(void);
@@ -21762,6 +22102,13 @@ static const struct genl_small_ops nl80211_small_ops[] = {
.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NO_WIPHY_MTX),
},
+ {
+ .cmd = NL80211_CMD_SET_SMD_CTX,
+ .doit = nl80211_set_smd_ctx,
+ .flags = GENL_UNS_ADMIN_PERM,
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_CLEAR_SKB),
+ },
};
static struct genl_family nl80211_fam __ro_after_init = {
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 7b8440c1f697..96a47eccc196 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1713,4 +1713,18 @@ rdev_set_epcs(struct cfg80211_registered_device *rdev,
return ret;
}
+static inline int rdev_set_smd_ctx(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev, const u8 *addr,
+ struct cfg80211_smd_transition_info *st_info)
+{
+ int ret = -EOPNOTSUPP;
+
+ trace_rdev_set_smd_ctx(&rdev->wiphy, wdev, addr, st_info);
+ if (rdev->ops->set_smd_ctx)
+ ret = rdev->ops->set_smd_ctx(&rdev->wiphy, wdev, addr, st_info);
+ 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 31000ffebe43..67db0b032808 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -4474,6 +4474,41 @@ TRACE_EVENT(cfg80211_nan_channel_evac,
TP_printk(WDEV_PR_FMT ", " WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
WDEV_PR_ARG, WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
);
+
+TRACE_EVENT(rdev_set_smd_ctx,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, const u8 *addr,
+ struct cfg80211_smd_transition_info *st_info),
+
+ TP_ARGS(wiphy, wdev, addr, st_info),
+
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ WDEV_ENTRY
+ MAC_ENTRY(sta_addr)
+ __field(u8, st_type)
+ __field(u8, dl_tid_bitmap)
+ __field(u8, ul_tid_bitmap)
+ ),
+
+ TP_fast_assign(
+ struct ieee80211_smd_ctx *ctx = st_info->ctx;
+
+ WIPHY_ASSIGN;
+ WDEV_ASSIGN;
+ MAC_ASSIGN(sta_addr, addr);
+ __entry->st_type = st_info->type;
+ __entry->dl_tid_bitmap = ctx->dl.valid_tid_bmap;
+ __entry->ul_tid_bitmap = ctx->ul.valid_tid_bmap;
+ ),
+
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT
+ ", sta=%pM, ST type=%u DL TIDs: 0x%x, UL TIDs: 0x%x",
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->sta_addr,
+ __entry->st_type,
+ __entry->dl_tid_bitmap, __entry->ul_tid_bitmap
+ )
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
--
2.34.1
next prev parent reply other threads:[~2026-11-06 7:59 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 7:58 [PATCH wireless-next v4 00/21] wifi: Add Seamless Mobility Domain (SMD) AP support Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 01/21] wifi: nl80211: define Seamless Mobility Domain (SMD) device capability Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 02/21] wifi: nl80211/cfg80211: define interfaces for SMD setup and STA update Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 03/21] wifi: nl80211: add SMD BSS Transition sub-state STA flags Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 04/21] wifi: cfg80211: define layouts for SMD BSS Transition context Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 05/21] wifi: nl80211: define interfaces for SMD BSS Transition context transfer Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 06/21] wifi: ieee80211: define APIs for UHR Link Reconfiguration frame checks Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 07/21] wifi: ieee80211: define API to check if frame is class 3 Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 08/21] wifi: nl80211/cfg80211: pack SMD dynamic context along with frame Pooventhiran G
2026-11-06 7:58 ` Pooventhiran G [this message]
2026-11-06 7:58 ` [PATCH wireless-next v4 10/21] wifi: nl80211/cfg80211: add support for querying SMD context for target AP MLD Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 11/21] wifi: nl80211/cfg80211: define API to notify SMD Drain completion Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 12/21] wifi: mac80211: set SMD parameters for AP setup and STA update Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 13/21] wifi: mac80211: apply SMD BSS Transition STA sub-states Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 14/21] wifi: mac80211: add driver_op for SMD substate changes Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 15/21] wifi: mac80211: filter uplink and downlink frames based on SMD states Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 16/21] wifi: mac80211: send BlockAck policy in AMPDU action Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 17/21] wifi: mac80211: pass rx_data directly from ieee80211_rx_list() Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 18/21] wifi: mac80211: handle UHR Link Reconfiguration frame Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 19/21] wifi: mac80211: add mac80211 support to handle NL80211_CMD_SET_SMD_CTX Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 20/21] wifi: mac80211: add mac80211 support to handle NL80211_CMD_GET_SMD_CTX Pooventhiran G
2026-11-06 7:58 ` [PATCH wireless-next v4 21/21] wifi: mac80211: define API to invoke SMD Drain Completion event Pooventhiran G
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=20261106-smd-v4-9-62e39487f51a@oss.qualcomm.com \
--to=pooventhiran.g@oss.qualcomm.com \
--cc=johannes@sipsolutions.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®