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>
This commit is contained in:

committed by
John W. Linville

parent
e7f4a940bb
commit
e247bd9068
@@ -378,7 +378,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
enum nl80211_channel_type channel_type,
|
||||
bool channel_type_valid, unsigned int wait,
|
||||
const u8 *buf, size_t len, bool no_cck,
|
||||
u64 *cookie);
|
||||
bool dont_wait_for_ack, u64 *cookie);
|
||||
|
||||
/* SME */
|
||||
int __cfg80211_connect(struct cfg80211_registered_device *rdev,
|
||||
|
@@ -904,7 +904,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
enum nl80211_channel_type channel_type,
|
||||
bool channel_type_valid, unsigned int wait,
|
||||
const u8 *buf, size_t len, bool no_cck,
|
||||
u64 *cookie)
|
||||
bool dont_wait_for_ack, u64 *cookie)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
const struct ieee80211_mgmt *mgmt;
|
||||
@@ -995,7 +995,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
/* Transmit the Action frame as requested by user space */
|
||||
return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
|
||||
channel_type, channel_type_valid,
|
||||
wait, buf, len, no_cck, cookie);
|
||||
wait, buf, len, no_cck, dont_wait_for_ack,
|
||||
cookie);
|
||||
}
|
||||
|
||||
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
|
||||
|
@@ -196,6 +196,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
||||
[NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -5282,10 +5283,11 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
int err;
|
||||
void *hdr;
|
||||
u64 cookie;
|
||||
struct sk_buff *msg;
|
||||
struct sk_buff *msg = NULL;
|
||||
unsigned int wait = 0;
|
||||
bool offchan;
|
||||
bool no_cck;
|
||||
bool offchan, no_cck, dont_wait_for_ack;
|
||||
|
||||
dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_FRAME] ||
|
||||
!info->attrs[NL80211_ATTR_WIPHY_FREQ])
|
||||
@@ -5329,29 +5331,36 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
if (chan == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
if (!dont_wait_for_ack) {
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
|
||||
NL80211_CMD_FRAME);
|
||||
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
|
||||
NL80211_CMD_FRAME);
|
||||
|
||||
if (IS_ERR(hdr)) {
|
||||
err = PTR_ERR(hdr);
|
||||
goto free_msg;
|
||||
if (IS_ERR(hdr)) {
|
||||
err = PTR_ERR(hdr);
|
||||
goto free_msg;
|
||||
}
|
||||
}
|
||||
|
||||
err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type,
|
||||
channel_type_valid, wait,
|
||||
nla_data(info->attrs[NL80211_ATTR_FRAME]),
|
||||
nla_len(info->attrs[NL80211_ATTR_FRAME]),
|
||||
no_cck, &cookie);
|
||||
no_cck, dont_wait_for_ack, &cookie);
|
||||
if (err)
|
||||
goto free_msg;
|
||||
|
||||
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
|
||||
if (msg) {
|
||||
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
return genlmsg_reply(msg, info);
|
||||
genlmsg_end(msg, hdr);
|
||||
return genlmsg_reply(msg, info);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
err = -ENOBUFS;
|
||||
|
Reference in New Issue
Block a user