|
@@ -386,6 +386,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
|
|
[NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
|
|
|
[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
|
|
|
[NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG },
|
|
|
+ [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
|
|
|
};
|
|
|
|
|
|
/* policy for the key attributes */
|
|
@@ -7786,6 +7787,27 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (!chandef.chan && params.offchan)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
|
|
|
+ params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
|
|
|
+
|
|
|
+ if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
|
|
|
+ int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if (len % sizeof(u16))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ params.n_csa_offsets = len / sizeof(u16);
|
|
|
+ params.csa_offsets =
|
|
|
+ nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
|
|
|
+
|
|
|
+ /* check that all the offsets fit the frame */
|
|
|
+ for (i = 0; i < params.n_csa_offsets; i++) {
|
|
|
+ if (params.csa_offsets[i] >= params.len)
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (!params.dont_wait_for_ack) {
|
|
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
|
if (!msg)
|
|
@@ -7799,8 +7821,6 @@ 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)
|