aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-04 06:18:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 16:13:54 -0500
commite247bd9068e3e86c3571147c128883596ace9d05 (patch)
tree5639065f2b0bfe4cb7389a75e274bc8a53efd75f /net/wireless
parente7f4a940bb5eecd07cf0039e7d9201badc332ae0 (diff)
cfg80211/mac80211: allow management TX to not wait for ACK
For probe responses it can be useful to not wait for ACK to avoid retransmissions if the station that sent the probe is already on the next channel, so allow userspace to request not caring about the ACK with a new nl80211 flag. Since mac80211 needs to be updated for the new function prototype anyway implement it right away -- it's just a few lines of code. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/mlme.c5
-rw-r--r--net/wireless/nl80211.c39
3 files changed, 28 insertions, 18 deletions
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;