Commit fbf07000 authored by Chung-Hsien Hsu's avatar Chung-Hsien Hsu Committed by Kalle Valo

brcmfmac: fix full timeout waiting for action frame on-channel tx

The driver sends an action frame down and waits for a completion signal
triggered by the received BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE event
to continue the process. However, the action frame could be transmitted
either on the current channel or on an off channel. For the on-channel
case, only BRCMF_E_ACTION_FRAME_COMPLETE event will be received when
the frame is transmitted, which make the driver always wait a full
timeout duration. This patch has the completion signal be triggered by
receiving the BRCMF_E_ACTION_FRAME_COMPLETE event for the on-channel
case.

This change fixes WFA p2p certification 5.1.19 failure.
Signed-off-by: default avatarChung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: default avatarChi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent edb6d688
...@@ -1457,10 +1457,12 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp, ...@@ -1457,10 +1457,12 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
return 0; return 0;
if (e->event_code == BRCMF_E_ACTION_FRAME_COMPLETE) { if (e->event_code == BRCMF_E_ACTION_FRAME_COMPLETE) {
if (e->status == BRCMF_E_STATUS_SUCCESS) if (e->status == BRCMF_E_STATUS_SUCCESS) {
set_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, set_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED,
&p2p->status); &p2p->status);
else { if (!p2p->wait_for_offchan_complete)
complete(&p2p->send_af_done);
} else {
set_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status); set_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
/* If there is no ack, we don't need to wait for /* If there is no ack, we don't need to wait for
* WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE event * WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE event
...@@ -1511,6 +1513,17 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, ...@@ -1511,6 +1513,17 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
p2p->af_sent_channel = le32_to_cpu(af_params->channel); p2p->af_sent_channel = le32_to_cpu(af_params->channel);
p2p->af_tx_sent_jiffies = jiffies; p2p->af_tx_sent_jiffies = jiffies;
if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status) &&
p2p->af_sent_channel ==
ieee80211_frequency_to_channel(p2p->remain_on_channel.center_freq))
p2p->wait_for_offchan_complete = false;
else
p2p->wait_for_offchan_complete = true;
brcmf_dbg(TRACE, "Waiting for %s tx completion event\n",
(p2p->wait_for_offchan_complete) ?
"off-channel" : "on-channel");
timeout = wait_for_completion_timeout(&p2p->send_af_done, timeout = wait_for_completion_timeout(&p2p->send_af_done,
P2P_AF_MAX_WAIT_TIME); P2P_AF_MAX_WAIT_TIME);
......
...@@ -124,6 +124,7 @@ struct afx_hdl { ...@@ -124,6 +124,7 @@ struct afx_hdl {
* @gon_req_action: about to send go negotiation requets frame. * @gon_req_action: about to send go negotiation requets frame.
* @block_gon_req_tx: drop tx go negotiation requets frame. * @block_gon_req_tx: drop tx go negotiation requets frame.
* @p2pdev_dynamically: is p2p device if created by module param or supplicant. * @p2pdev_dynamically: is p2p device if created by module param or supplicant.
* @wait_for_offchan_complete: wait for off-channel tx completion event.
*/ */
struct brcmf_p2p_info { struct brcmf_p2p_info {
struct brcmf_cfg80211_info *cfg; struct brcmf_cfg80211_info *cfg;
...@@ -144,6 +145,7 @@ struct brcmf_p2p_info { ...@@ -144,6 +145,7 @@ struct brcmf_p2p_info {
bool gon_req_action; bool gon_req_action;
bool block_gon_req_tx; bool block_gon_req_tx;
bool p2pdev_dynamically; bool p2pdev_dynamically;
bool wait_for_offchan_complete;
}; };
s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced); s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment