aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c11
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/mlme.c5
-rw-r--r--net/wireless/nl80211.c39
4 files changed, 36 insertions, 21 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e072fea69a3..ab3258ac0b2 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1936,7 +1936,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1936 enum nl80211_channel_type channel_type, 1936 enum nl80211_channel_type channel_type,
1937 bool channel_type_valid, unsigned int wait, 1937 bool channel_type_valid, unsigned int wait,
1938 const u8 *buf, size_t len, bool no_cck, 1938 const u8 *buf, size_t len, bool no_cck,
1939 u64 *cookie) 1939 bool dont_wait_for_ack, u64 *cookie)
1940{ 1940{
1941 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1941 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1942 struct ieee80211_local *local = sdata->local; 1942 struct ieee80211_local *local = sdata->local;
@@ -1944,10 +1944,15 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1944 struct sta_info *sta; 1944 struct sta_info *sta;
1945 struct ieee80211_work *wk; 1945 struct ieee80211_work *wk;
1946 const struct ieee80211_mgmt *mgmt = (void *)buf; 1946 const struct ieee80211_mgmt *mgmt = (void *)buf;
1947 u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | 1947 u32 flags;
1948 IEEE80211_TX_CTL_REQ_TX_STATUS;
1949 bool is_offchan = false; 1948 bool is_offchan = false;
1950 1949
1950 if (dont_wait_for_ack)
1951 flags = IEEE80211_TX_CTL_NO_ACK;
1952 else
1953 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
1954 IEEE80211_TX_CTL_REQ_TX_STATUS;
1955
1951 /* Check that we are on the requested channel for transmission */ 1956 /* Check that we are on the requested channel for transmission */
1952 if (chan != local->tmp_channel && 1957 if (chan != local->tmp_channel &&
1953 chan != local->oper_channel) 1958 chan != local->oper_channel)
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 4c6ff402435..1c7d4df5418 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -378,7 +378,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
378 enum nl80211_channel_type channel_type, 378 enum nl80211_channel_type channel_type,
379 bool channel_type_valid, unsigned int wait, 379 bool channel_type_valid, unsigned int wait,
380 const u8 *buf, size_t len, bool no_cck, 380 const u8 *buf, size_t len, bool no_cck,
381 u64 *cookie); 381 bool dont_wait_for_ack, u64 *cookie);
382 382
383/* SME */ 383/* SME */
384int __cfg80211_connect(struct cfg80211_registered_device *rdev, 384int __cfg80211_connect(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 34891e08c54..6c1bafd508c 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -904,7 +904,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
904 enum nl80211_channel_type channel_type, 904 enum nl80211_channel_type channel_type,
905 bool channel_type_valid, unsigned int wait, 905 bool channel_type_valid, unsigned int wait,
906 const u8 *buf, size_t len, bool no_cck, 906 const u8 *buf, size_t len, bool no_cck,
907 u64 *cookie) 907 bool dont_wait_for_ack, u64 *cookie)
908{ 908{
909 struct wireless_dev *wdev = dev->ieee80211_ptr; 909 struct wireless_dev *wdev = dev->ieee80211_ptr;
910 const struct ieee80211_mgmt *mgmt; 910 const struct ieee80211_mgmt *mgmt;
@@ -995,7 +995,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
995 /* Transmit the Action frame as requested by user space */ 995 /* Transmit the Action frame as requested by user space */
996 return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, 996 return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
997 channel_type, channel_type_valid, 997 channel_type, channel_type_valid,
998 wait, buf, len, no_cck, cookie); 998 wait, buf, len, no_cck, dont_wait_for_ack,
999 cookie);
999} 1000}
1000 1001
1001bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, 1002bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5b659068b02..0ef09415c89 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -196,6 +196,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
196 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 }, 196 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
197 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG }, 197 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
198 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG }, 198 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
199 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
199}; 200};
200 201
201/* policy for the key attributes */ 202/* policy for the key attributes */
@@ -5282,10 +5283,11 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5282 int err; 5283 int err;
5283 void *hdr; 5284 void *hdr;
5284 u64 cookie; 5285 u64 cookie;
5285 struct sk_buff *msg; 5286 struct sk_buff *msg = NULL;
5286 unsigned int wait = 0; 5287 unsigned int wait = 0;
5287 bool offchan; 5288 bool offchan, no_cck, dont_wait_for_ack;
5288 bool no_cck; 5289
5290 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
5289 5291
5290 if (!info->attrs[NL80211_ATTR_FRAME] || 5292 if (!info->attrs[NL80211_ATTR_FRAME] ||
5291 !info->attrs[NL80211_ATTR_WIPHY_FREQ]) 5293 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
@@ -5329,29 +5331,36 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5329 if (chan == NULL) 5331 if (chan == NULL)
5330 return -EINVAL; 5332 return -EINVAL;
5331 5333
5332 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 5334 if (!dont_wait_for_ack) {
5333 if (!msg) 5335 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5334 return -ENOMEM; 5336 if (!msg)
5337 return -ENOMEM;
5335 5338
5336 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 5339 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
5337 NL80211_CMD_FRAME); 5340 NL80211_CMD_FRAME);
5338 5341
5339 if (IS_ERR(hdr)) { 5342 if (IS_ERR(hdr)) {
5340 err = PTR_ERR(hdr); 5343 err = PTR_ERR(hdr);
5341 goto free_msg; 5344 goto free_msg;
5345 }
5342 } 5346 }
5347
5343 err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type, 5348 err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type,
5344 channel_type_valid, wait, 5349 channel_type_valid, wait,
5345 nla_data(info->attrs[NL80211_ATTR_FRAME]), 5350 nla_data(info->attrs[NL80211_ATTR_FRAME]),
5346 nla_len(info->attrs[NL80211_ATTR_FRAME]), 5351 nla_len(info->attrs[NL80211_ATTR_FRAME]),
5347 no_cck, &cookie); 5352 no_cck, dont_wait_for_ack, &cookie);
5348 if (err) 5353 if (err)
5349 goto free_msg; 5354 goto free_msg;
5350 5355
5351 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); 5356 if (msg) {
5357 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
5352 5358
5353 genlmsg_end(msg, hdr); 5359 genlmsg_end(msg, hdr);
5354 return genlmsg_reply(msg, info); 5360 return genlmsg_reply(msg, info);
5361 }
5362
5363 return 0;
5355 5364
5356 nla_put_failure: 5365 nla_put_failure:
5357 err = -ENOBUFS; 5366 err = -ENOBUFS;