Browse Source

qcacld-3.0: Fix P2P GO Negotiation failure issue

qcacld-2.0 to qcacld-3.0 propagation

Sometimes it is possible for the host to receive the ack for
go negotiation request after the go negotiation confirmation
is sent. So supplicant assumes go negotiation confirmation is
success though it is not and results in connection failure.

To address this, drop the pending ack for the go negotiation
request. so that the supplicant will wait for the ack of the
negotiation confirmation.

CRs-Fixed: 1032185
Change-Id: I54f305319e23b1ffcbd54cc6e7dcc74d39a2e511
(cherry picked from commit 83df79da05419397ef85b77acef353a9ffb05ced)
(cherry picked from commit f13a15829f20a644e5cbaad4a1783a33d0f78014)
Gowri, Deepthi 8 years ago
parent
commit
62da33e948
2 changed files with 22 additions and 2 deletions
  1. 5 0
      core/hdd/inc/wlan_hdd_main.h
  2. 17 2
      core/hdd/src/wlan_hdd_p2p.c

+ 5 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -631,6 +631,11 @@ typedef struct hdd_cfg80211_state_s {
 	hdd_remain_on_chan_ctx_t *remain_on_chan_ctx;
 	struct mutex remain_on_chan_ctx_lock;
 	eP2PActionFrameState actionFrmState;
+	/* is_go_neg_ack_received flag is set to 1 when
+	* the pending ack for GO negotiation req is
+	* received.
+	*/
+	bool is_go_neg_ack_received;
 } hdd_cfg80211_state_t;
 
 /**

+ 17 - 2
core/hdd/src/wlan_hdd_p2p.c

@@ -1684,13 +1684,27 @@ void hdd_send_action_cnf(hdd_adapter_t *pAdapter, bool actionSendSuccess)
 
 	cfgState->actionFrmState = HDD_IDLE;
 
-	hddLog(LOG1, "Send Action cnf, actionSendSuccess %d",
-	       actionSendSuccess);
 
 	if (NULL == cfgState->buf) {
 		return;
 	}
 
+	if (cfgState->is_go_neg_ack_received) {
+
+		cfgState->is_go_neg_ack_received = 0;
+		/* Sometimes its possible that host may receive the ack for GO
+		 * negotiation req after sending go negotaition confirmation,
+		 * in such case drop the ack received for the go negotiation
+		 * request, so that supplicant waits for the confirmation ack
+		 * from firmware.
+		 */
+		hdd_info("Drop the pending ack received in cfgState->actionFrmState %d",
+				cfgState->actionFrmState);
+		return;
+	}
+
+	hdd_info("Send Action cnf, actionSendSuccess %d",
+		actionSendSuccess);
 	/*
 	 * buf is the same pointer it passed us to send. Since we are sending
 	 * it through control path, we use different buffers.
@@ -2482,6 +2496,7 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
 					hddLog(LOG1,
 					       "%s: ACK_PENDING and But received RESP for Action frame ",
 					       __func__);
+					cfgState->is_go_neg_ack_received = 1;
 					hdd_send_action_cnf(pAdapter, true);
 				}
 			}