ef2d0934fcc206109cccfce4812cab79b814633b
[oweals/openwrt.git] /
1 From fbf07000960d9c8a13fdc17c6de0230d681c7543 Mon Sep 17 00:00:00 2001
2 From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
3 Date: Thu, 27 Sep 2018 14:59:49 +0000
4 Subject: [PATCH] brcmfmac: fix full timeout waiting for action frame
5  on-channel tx
6
7 The driver sends an action frame down and waits for a completion signal
8 triggered by the received BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE event
9 to continue the process. However, the action frame could be transmitted
10 either on the current channel or on an off channel. For the on-channel
11 case, only BRCMF_E_ACTION_FRAME_COMPLETE event will be received when
12 the frame is transmitted, which make the driver always wait a full
13 timeout duration. This patch has the completion signal be triggered by
14 receiving the BRCMF_E_ACTION_FRAME_COMPLETE event for the on-channel
15 case.
16
17 This change fixes WFA p2p certification 5.1.19 failure.
18
19 Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
20 Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
21 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
22 ---
23  drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 17 +++++++++++++++--
24  drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h |  2 ++
25  2 files changed, 17 insertions(+), 2 deletions(-)
26
27 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
28 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
29 @@ -1457,10 +1457,12 @@ int brcmf_p2p_notify_action_tx_complete(
30                 return 0;
31  
32         if (e->event_code == BRCMF_E_ACTION_FRAME_COMPLETE) {
33 -               if (e->status == BRCMF_E_STATUS_SUCCESS)
34 +               if (e->status == BRCMF_E_STATUS_SUCCESS) {
35                         set_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED,
36                                 &p2p->status);
37 -               else {
38 +                       if (!p2p->wait_for_offchan_complete)
39 +                               complete(&p2p->send_af_done);
40 +               } else {
41                         set_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
42                         /* If there is no ack, we don't need to wait for
43                          * WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE event
44 @@ -1511,6 +1513,17 @@ static s32 brcmf_p2p_tx_action_frame(str
45         p2p->af_sent_channel = le32_to_cpu(af_params->channel);
46         p2p->af_tx_sent_jiffies = jiffies;
47  
48 +       if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status) &&
49 +           p2p->af_sent_channel ==
50 +           ieee80211_frequency_to_channel(p2p->remain_on_channel.center_freq))
51 +               p2p->wait_for_offchan_complete = false;
52 +       else
53 +               p2p->wait_for_offchan_complete = true;
54 +
55 +       brcmf_dbg(TRACE, "Waiting for %s tx completion event\n",
56 +                 (p2p->wait_for_offchan_complete) ?
57 +                  "off-channel" : "on-channel");
58 +
59         timeout = wait_for_completion_timeout(&p2p->send_af_done,
60                                               P2P_AF_MAX_WAIT_TIME);
61  
62 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
63 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
64 @@ -124,6 +124,7 @@ struct afx_hdl {
65   * @gon_req_action: about to send go negotiation requets frame.
66   * @block_gon_req_tx: drop tx go negotiation requets frame.
67   * @p2pdev_dynamically: is p2p device if created by module param or supplicant.
68 + * @wait_for_offchan_complete: wait for off-channel tx completion event.
69   */
70  struct brcmf_p2p_info {
71         struct brcmf_cfg80211_info *cfg;
72 @@ -144,6 +145,7 @@ struct brcmf_p2p_info {
73         bool gon_req_action;
74         bool block_gon_req_tx;
75         bool p2pdev_dynamically;
76 +       bool wait_for_offchan_complete;
77  };
78  
79  s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced);