From 445dbe2cdb756d79d91f70c57d757f9705120a76 Mon Sep 17 00:00:00 2001 From: Hu Wang Date: Wed, 11 Aug 2021 15:56:36 +0800 Subject: [PATCH] P2P: Do not stop Listen state if it is moving to correct channel Commit 0b8889d8e5de ("P2P: Do not stop Listen state if it is on correct channel") added a optimization to use Listen state's remain-on-channel to send out GO Negotiation response frame quickly. But in Listen state, if GO Negotiation request frame is received before the remain-on-channel started event from the driver, the above optimization is not triggered. This showed up in following manner in the debug log: p2p0: Starting radio work 'p2p-listen'@0xb4000070ae22d420 after 0.000114 second wait nl80211: Remain-on-channel cookie 0x100 for freq=2412 MHz duration=204 P2P: Received GO Negotiation Request from 6e:fa:a7:86:e5:e5(freq=2412) P2P: GO Negotiation with 6e:fa:a7:86:e5:e5 P2P: Stopping find P2P: Clear timeout (state=WAIT_PEER_CONNECT) P2P: State WAIT_PEER_CONNECT -> IDLE nl80211: Cancel remain-on-channel with cookie 0x100 p2p0: Radio work 'p2p-listen'@0xb4000070ae22d420 done in 0.074348 seconds p2p0: radio_work_free('p2p-listen'@0xb4000070ae22d420): num_active_works --> 0 P2P: State IDLE -> GO_NEG P2P: Sending GO Negotiation Response Off-channel: Send action frame: freq=2412 dst=6e:fa:a7:86:e5:e5 src=da:3c:83:7d:70:2b bssid=da:3c:83:7d:70:2b len=196 nl80211: Remain-on-channel event (cancel=0 freq=2412 channel_type=0 duration=400 cookie=0x100 (match)) nl80211: Remain-on-channel event (cancel=1 freq=2412 channel_type=0 duration=0 cookie=0x100 (match)) P2P: GO Negotiation Response (failure) TX callback: success=0 Fix this by adding p2p->pending_listen_freq == freq condition for the optimization so that the case where the remain-on-channel command has already been issued to the driver, but the start event has not yet been received, is covered as well. Fixes: 0b8889d8e5de ("P2P: Do not stop Listen state if it is on correct channel") Signed-off-by: Hu Wang --- src/p2p/p2p.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 9ac505735..598a449c1 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1326,7 +1326,9 @@ void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq) { - if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { + if (freq > 0 && + ((p2p->drv_in_listen == freq && p2p->in_listen) || + p2p->pending_listen_freq == (unsigned int) freq)) { p2p_dbg(p2p, "Skip stop_listen since we are on correct channel for response"); return; }