diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-01-04 21:51:07 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-01-04 21:51:07 -0800 |
| commit | 8cc5ff68960340807b79d85b9ddddef4cde11311 (patch) | |
| tree | d874056b0b0c5cedad611b8dbc8c313c75f396eb /src | |
| parent | 87125e9e65d712cb52ef29a8cd08b51cd45b4f37 (diff) | |
| parent | e6c9bd4bfe7d5b615561dc658565010e072ca88f (diff) | |
| download | android_external_wpa_supplicant_8-8cc5ff68960340807b79d85b9ddddef4cde11311.tar.gz android_external_wpa_supplicant_8-8cc5ff68960340807b79d85b9ddddef4cde11311.tar.bz2 android_external_wpa_supplicant_8-8cc5ff68960340807b79d85b9ddddef4cde11311.zip | |
Merge "nl80211: Cancel all pending TX frame cookies" into wlan-service.lnx.1.0-dev.1.0
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; |
