qcacld-3.0: Limit the BA window buffer size

In case where peer itself exhibits BA window size more
than the allowed value, crash can happen. So, limit the
BA window size to maximum allowed BA buffer size in case
peer BA req buffer size is more than it.

Bug: 182634675
Change-Id: Ie695b9787b555616a5443077147d4bc3a3aefb78
CRs-Fixed: 2766363
Signed-off-by: Hsiu-Chang Chen <hsiuchangchen@google.com>
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
index d251afe..7cc1446 100644
--- a/core/mac/src/pe/lim/lim_process_action_frame.c
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -1639,6 +1639,9 @@
 	uint8_t peer_id;
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
 	void *peer, *pdev;
+	tpDphHashNode sta_ds;
+	uint16_t aid, buff_size;
+	bool he_cap = false;
 
 	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
 	if (!pdev) {
@@ -1668,11 +1671,30 @@
 		pe_warn("warning: unpack addba Req(0x%08x, %d bytes)",
 			status, frame_len);
 	}
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+				       &session->dph.dphHashTable);
+	if (sta_ds && lim_is_session_he_capable(session))
+		he_cap = lim_is_sta_he_capable(sta_ds);
+	if (sta_ds && sta_ds->staType == STA_ENTRY_NDI_PEER)
+		he_cap = lim_is_session_he_capable(session);
+
+	if (he_cap)
+		buff_size = MAX_BA_BUFF_SIZE;
+	else
+		buff_size = SIR_MAC_BA_DEFAULT_BUFF_SIZE;
+
+	if (mac_ctx->usr_cfg_ba_buff_size)
+		buff_size = mac_ctx->usr_cfg_ba_buff_size;
+
+	if (addba_req->addba_param_set.buff_size)
+		buff_size = QDF_MIN(buff_size,
+				    addba_req->addba_param_set.buff_size);
+
 	pe_debug("token %d tid %d timeout %d buff_size %d ssn %d",
 		 addba_req->DialogToken.token, addba_req->addba_param_set.tid,
 		 addba_req->ba_timeout.timeout,
-		 addba_req->addba_param_set.buff_size,
-		 addba_req->ba_start_seq_ctrl.ssn);
+		 buff_size, addba_req->ba_start_seq_ctrl.ssn);
 
 	peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->sa, &peer_id,
 					PEER_DEBUG_ID_WMA_ADDBA_REQ);
@@ -1685,8 +1707,7 @@
 			addba_req->DialogToken.token,
 			addba_req->addba_param_set.tid,
 			addba_req->ba_timeout.timeout,
-			addba_req->addba_param_set.buff_size,
-			addba_req->ba_start_seq_ctrl.ssn);
+			buff_size, addba_req->ba_start_seq_ctrl.ssn);
 
 	if (QDF_STATUS_SUCCESS == qdf_status) {
 		qdf_status = lim_send_addba_response_frame(mac_ctx,