diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 11 | ||||
-rw-r--r-- | net/wireless/core.h | 2 | ||||
-rw-r--r-- | net/wireless/mlme.c | 5 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 39 |
4 files changed, 36 insertions, 21 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index e072fea69a30..ab3258ac0b2c 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 4c6ff4024356..1c7d4df5418c 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 */ |
384 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, | 384 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 34891e08c54a..6c1bafd508c8 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 | ||
1001 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | 1002 | bool 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 5b659068b020..0ef09415c89a 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; |