diff options
| author | Jouni Malinen <jouni@qca.qualcomm.com> | 2015-12-02 00:12:32 +0200 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2015-12-30 03:05:15 -0800 |
| commit | e6c9bd4bfe7d5b615561dc658565010e072ca88f (patch) | |
| tree | a79a98de145db2ea3d131bf8c66d28682b4ee761 /src | |
| parent | 20c1104d002d61af3a12ee58e346a9f28937d620 (diff) | |
| download | android_external_wpa_supplicant_8-e6c9bd4bfe7d5b615561dc658565010e072ca88f.tar.gz android_external_wpa_supplicant_8-e6c9bd4bfe7d5b615561dc658565010e072ca88f.tar.bz2 android_external_wpa_supplicant_8-e6c9bd4bfe7d5b615561dc658565010e072ca88f.zip | |
nl80211: Cancel all pending TX frame cookies
These needs to be cancelled so that the kernel driver does not get left
with all old entries blocking other offchannel operations
Git-commit: 759a8a3a99845af1c5c10685ec7cb9cf4daa4593
Git-repo : git://w1.fi/srv/git/hostap.git
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
CRs-Fixed: 950786
Change-Id: Ia9a964c407c72384b606dbb1f033e110b8091b5c
Diffstat (limited to 'src')
| -rw-r--r-- | src/drivers/driver_nl80211.c | 45 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211.h | 3 |
2 files changed, 44 insertions, 4 deletions
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 43a49f24..6cd36c04 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -6154,6 +6154,20 @@ static int nl80211_send_frame_cmd(struct i802_bss *bss, if (cookie_out) *cookie_out = no_ack ? (u64) -1 : cookie; + + if (drv->num_send_action_cookies == MAX_SEND_ACTION_COOKIES) { + wpa_printf(MSG_DEBUG, + "nl80211: Drop oldest pending send action cookie 0x%llx", + (long long unsigned int) + drv->send_action_cookies[0]); + os_memmove(&drv->send_action_cookies[0], + &drv->send_action_cookies[1], + (MAX_SEND_ACTION_COOKIES - 1) * + sizeof(u64)); + drv->num_send_action_cookies--; + } + drv->send_action_cookies[drv->num_send_action_cookies] = cookie; + drv->num_send_action_cookies++; } fail: @@ -6208,17 +6222,16 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss, } -static void wpa_driver_nl80211_send_action_cancel_wait(void *priv) +static void nl80211_frame_wait_cancel(struct i802_bss *bss, u64 cookie) { - struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; struct nl_msg *msg; int ret; wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx", - (long long unsigned int) drv->send_action_cookie); + (long long unsigned int) cookie); if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_FRAME_WAIT_CANCEL)) || - nla_put_u64(msg, NL80211_ATTR_COOKIE, drv->send_action_cookie)) { + nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) { nlmsg_free(msg); return; } @@ -6230,6 +6243,30 @@ static void wpa_driver_nl80211_send_action_cancel_wait(void *priv) } +static void wpa_driver_nl80211_send_action_cancel_wait(void *priv) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + unsigned int i; + u64 cookie; + + /* Cancel the last pending TX cookie */ + nl80211_frame_wait_cancel(bss, drv->send_action_cookie); + + /* + * Cancel the other pending TX cookies, if any. This is needed since + * the driver may keep a list of all pending offchannel TX operations + * and free up the radio only once they have expired or cancelled. + */ + for (i = drv->num_send_action_cookies; i > 0; i--) { + cookie = drv->send_action_cookies[i - 1]; + if (cookie != drv->send_action_cookie) + nl80211_frame_wait_cancel(bss, cookie); + } + drv->num_send_action_cookies = 0; +} + + static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq, unsigned int duration) { diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index 1536d2ff..ffb5fa7e 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -149,6 +149,9 @@ struct wpa_driver_nl80211_data { u64 remain_on_chan_cookie; u64 send_action_cookie; +#define MAX_SEND_ACTION_COOKIES 20 + u64 send_action_cookies[MAX_SEND_ACTION_COOKIES]; + unsigned int num_send_action_cookies; unsigned int last_mgmt_freq; |
