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. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
850e054c0f
commit
759a8a3a99
2 changed files with 44 additions and 4 deletions
|
@ -6183,6 +6183,20 @@ static int nl80211_send_frame_cmd(struct i802_bss *bss,
|
||||||
|
|
||||||
if (cookie_out)
|
if (cookie_out)
|
||||||
*cookie_out = no_ack ? (u64) -1 : cookie;
|
*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:
|
fail:
|
||||||
|
@ -6237,17 +6251,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 wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
struct nl_msg *msg;
|
struct nl_msg *msg;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx",
|
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)) ||
|
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);
|
nlmsg_free(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -6259,6 +6272,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,
|
static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
|
||||||
unsigned int duration)
|
unsigned int duration)
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,6 +153,9 @@ struct wpa_driver_nl80211_data {
|
||||||
u64 vendor_scan_cookie;
|
u64 vendor_scan_cookie;
|
||||||
u64 remain_on_chan_cookie;
|
u64 remain_on_chan_cookie;
|
||||||
u64 send_action_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;
|
unsigned int last_mgmt_freq;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue