Forráskód Böngészése

qcacld-3.0: Add support to send rate information for mgmt frames

Add support to send rate information for mgmt frames.

Currently default rates are used by target for the mgmt frames before
association. If the AP does not support the default rates (1 Mbps for
2.4G and 6Mbps for 5G), STA would still send AUTH, ASSOC frames with
the default rates. Add support to send the minimum rate supported by
the AP as part of the MGMT Tx WMI command.

Change-Id: I38d832818bbbd5fe3dec5660bd01dd08798bf0be
CRs-Fixed: 2085006
Naveen Rawat 7 éve
szülő
commit
296a51846f

+ 2 - 2
core/mac/src/pe/lim/lim_p2p.c

@@ -475,7 +475,7 @@ static void lim_tx_action_frame(tpAniSirGlobal mac_ctx,
 			TXRX_FRM_802_11_MGMT,
 			ANI_TXDIR_TODS, 7, lim_tx_complete,
 			frame, tx_flag, sme_session_id,
-			channel_freq);
+			channel_freq, RATEID_DEFAULT);
 
 		if (!mb_msg->noack)
 			lim_p2p_action_cnf(mac_ctx, packet,
@@ -490,7 +490,7 @@ static void lim_tx_action_frame(tpAniSirGlobal mac_ctx,
 				ANI_TXDIR_TODS, 7, lim_tx_complete,
 				frame, lim_p2p_action_cnf, tx_flag,
 				sme_session_id, false,
-				channel_freq);
+				channel_freq, RATEID_DEFAULT);
 
 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 			pe_err("couldn't send action frame");

+ 7 - 4
core/mac/src/pe/lim/lim_process_tdls.c

@@ -681,7 +681,7 @@ static tSirRetStatus lim_send_tdls_dis_req_frame(tpAniSirGlobal pMac,
 					lim_mgmt_tdls_tx_complete,
 					HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME |
 					HAL_USE_PEER_STA_REQUESTED_MASK,
-					smeSessionId, false, 0);
+					smeSessionId, false, 0, RATEID_DEFAULT);
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 		pMac->lim.tdls_frm_session_id = NO_SESSION;
 		pe_err("could not send TDLS Discovery Request frame");
@@ -987,7 +987,8 @@ static tSirRetStatus lim_send_tdls_dis_rsp_frame(tpAniSirGlobal pMac,
 					      lim_tx_complete, pFrame,
 					      lim_mgmt_tdls_tx_complete,
 					      HAL_USE_SELF_STA_REQUESTED_MASK,
-					      smeSessionId, false, 0);
+					      smeSessionId, false, 0,
+					      RATEID_DEFAULT);
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 		pMac->lim.tdls_frm_session_id = NO_SESSION;
 		pe_err("could not send TDLS Discovery Response frame!");
@@ -1069,7 +1070,8 @@ wma_tx_frame_with_tx_complete_send(tpAniSirGlobal pMac, void *pPacket,
 					  lim_mgmt_tdls_tx_complete,
 					  HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
 					  | HAL_USE_PEER_STA_REQUESTED_MASK,
-					  smeSessionId, flag, 0);
+					  smeSessionId, flag, 0,
+					  RATEID_DEFAULT);
 }
 #else
 
@@ -1089,7 +1091,8 @@ wma_tx_frame_with_tx_complete_send(tpAniSirGlobal pMac, void *pPacket,
 					  lim_mgmt_tdls_tx_complete,
 					  HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
 					  | HAL_USE_PEER_STA_REQUESTED_MASK,
-					  smeSessionId, false, 0);
+					  smeSessionId, false, 0,
+					  RATEID_DEFAULT);
 }
 #endif
 

+ 3 - 2
core/mac/src/pe/lim/lim_send_frames_host_roam.c

@@ -450,7 +450,7 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(tpAniSirGlobal mac_ctx,
 				(uint16_t) (bytes + ft_ies_length),
 				TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
 				lim_tx_complete, frame, tx_flag, sme_sessionid,
-				0);
+				0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 		       pe_session->peSessionId, qdf_status));
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -777,7 +777,8 @@ void lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal pMac,
 		wma_tx_frame(pMac, pPacket,
 			   (uint16_t) (sizeof(tSirMacMgmtHdr) + nPayload),
 			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
-			   lim_tx_complete, pFrame, txFlag, smeSessionId, 0);
+			   lim_tx_complete, pFrame, txFlag, smeSessionId, 0,
+			   RATEID_DEFAULT);
 	MTRACE(qdf_trace
 		       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 		       psessionEntry->peSessionId, qdf_status));

+ 34 - 25
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -458,7 +458,7 @@ lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
 			   (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
 			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
 			   lim_tx_complete, frame, txflag, sme_sessionid,
-			   0);
+			   0, RATEID_DEFAULT);
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 		pe_err("could not send Probe Request frame!");
 		/* Pkt will be freed up by the callback */
@@ -867,7 +867,7 @@ lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, frame, tx_flag,
-				sme_sessionid, 0);
+				sme_sessionid, 0, RATEID_DEFAULT);
 
 	/* Pkt will be freed up by the callback */
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
@@ -1082,7 +1082,7 @@ lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 psessionEntry->peSessionId, qdf_status));
 
@@ -1440,7 +1440,7 @@ lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, frame, tx_flag,
-				sme_session, 0);
+				sme_session, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 pe_session->peSessionId, qdf_status));
 
@@ -1587,7 +1587,7 @@ lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 psessionEntry->peSessionId, qdf_status));
 	/* Pkt will be freed up by the callback */
@@ -1672,6 +1672,7 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
 	uint8_t *bcn_ie = NULL;
 	uint32_t bcn_ie_len = 0;
 	uint32_t aes_block_size_len = 0;
+	enum rateid min_rid = RATEID_DEFAULT;
 
 	if (NULL == pe_session) {
 		pe_err("pe_session is NULL");
@@ -2065,15 +2066,17 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
 			 pe_session->peSessionId, mac_hdr->fc.subType));
 
 	pe_debug("Sending Association Request length %d to ", bytes);
+	min_rid = lim_get_min_session_txrate(pe_session);
 	qdf_status =
 		wma_tx_frameWithTxComplete(mac_ctx, packet,
 			   (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
 			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
 			   lim_tx_complete, frame, lim_assoc_tx_complete_cnf,
-			   tx_flag, sme_sessionid, false, 0);
+			   tx_flag, sme_sessionid, false, 0, min_rid);
 	MTRACE(qdf_trace
 		       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 		       pe_session->peSessionId, qdf_status));
+
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 		pe_err("Failed to send Association Request (%X)!",
 			qdf_status);
@@ -2160,6 +2163,7 @@ lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
 	uint8_t sme_sessionid = 0;
 	uint16_t ft_ies_length = 0;
 	bool challenge_req = false;
+	enum rateid min_rid = RATEID_DEFAULT;
 
 	if (NULL == session) {
 		pe_err("Error: psession Entry is NULL");
@@ -2436,12 +2440,13 @@ alloc_packet:
 			 session->peSessionId, mac_hdr->fc.subType));
 
 	mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
+	min_rid = lim_get_min_session_txrate(session);
 	qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
 				 (uint16_t)frame_len,
 				 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
 				 7, lim_tx_complete, frame,
 				 lim_auth_tx_complete_cnf,
-				 tx_flag, sme_sessionid, false, 0);
+				 tx_flag, sme_sessionid, false, 0, min_rid);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 		session->peSessionId, qdf_status));
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -2786,7 +2791,8 @@ lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
 					 TXRX_FRM_802_11_MGMT,
 					 ANI_TXDIR_TODS, 7, lim_tx_complete,
 					 pFrame, lim_disassoc_tx_complete_cnf,
-					 txFlag, smeSessionId, false, 0);
+					 txFlag, smeSessionId, false, 0,
+					 RATEID_DEFAULT);
 		MTRACE(qdf_trace
 			       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			       psessionEntry->peSessionId, qdf_status));
@@ -2816,7 +2822,7 @@ lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
 					ANI_TXDIR_TODS,
 					7,
 					lim_tx_complete, pFrame, txFlag,
-					smeSessionId, 0);
+					smeSessionId, 0, RATEID_DEFAULT);
 		MTRACE(qdf_trace
 			       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			       psessionEntry->peSessionId, qdf_status));
@@ -2961,7 +2967,8 @@ lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
 					 TXRX_FRM_802_11_MGMT,
 					 ANI_TXDIR_TODS, 7, lim_tx_complete,
 					 pFrame, lim_deauth_tx_complete_cnf,
-					 txFlag, smeSessionId, false, 0);
+					 txFlag, smeSessionId, false, 0,
+					 RATEID_DEFAULT);
 		MTRACE(qdf_trace
 			       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			       psessionEntry->peSessionId, qdf_status));
@@ -3004,7 +3011,7 @@ lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
 				wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
 					   TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
 					   7, lim_tx_complete, pFrame, txFlag,
-					   smeSessionId, 0);
+					   smeSessionId, 0, RATEID_DEFAULT);
 		} else {
 #endif
 		/* Queue Disassociation frame in high priority WQ */
@@ -3012,7 +3019,7 @@ lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
 			wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
 				   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
 				   7, lim_tx_complete, pFrame, txFlag,
-				   smeSessionId, 0);
+				   smeSessionId, 0, RATEID_DEFAULT);
 #ifdef FEATURE_WLAN_TDLS
 	}
 #endif
@@ -3142,7 +3149,7 @@ lim_send_meas_report_frame(tpAniSirGlobal pMac,
 	qdf_status =
 		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
 			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
-			   lim_tx_complete, pFrame, 0, 0);
+			   lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace
 		       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 		       ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
@@ -3242,7 +3249,7 @@ lim_send_tpc_request_frame(tpAniSirGlobal pMac,
 	qdf_status =
 		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
 			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
-			   lim_tx_complete, pFrame, 0, 0);
+			   lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace
 		       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 		       ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
@@ -3345,7 +3352,7 @@ lim_send_tpc_report_frame(tpAniSirGlobal pMac,
 	qdf_status =
 		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
 			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
-			   lim_tx_complete, pFrame, 0, 0);
+			   lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace
 		(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 		((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
@@ -3474,7 +3481,7 @@ lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 psessionEntry->peSessionId, qdf_status));
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -3601,7 +3608,8 @@ lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
 						 ANI_TXDIR_TODS,
 						 7,
 						 lim_tx_complete, frame,
-						 txFlag, sme_session_id, 0);
+						 txFlag, sme_session_id, 0,
+						 RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			session_entry->peSessionId, qdf_status));
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -3749,7 +3757,7 @@ lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
 			TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
 			7, lim_tx_complete, frame,
 			lim_oper_chan_change_confirm_tx_complete_cnf,
-			tx_flag, sme_session_id, false, 0);
+			tx_flag, sme_session_id, false, 0, RATEID_DEFAULT);
 
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			session_entry->peSessionId, qdf_status));
@@ -3852,7 +3860,7 @@ lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 psessionEntry->peSessionId, qdf_status));
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -3987,7 +3995,7 @@ lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 psessionEntry->peSessionId, qdf_status));
 	if (QDF_STATUS_SUCCESS != qdf_status) {
@@ -4134,7 +4142,7 @@ lim_send_link_report_action_frame(tpAniSirGlobal pMac,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 psessionEntry->peSessionId, qdf_status));
 	if (QDF_STATUS_SUCCESS != qdf_status) {
@@ -4319,7 +4327,7 @@ lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 psessionEntry->peSessionId, qdf_status));
 	if (QDF_STATUS_SUCCESS != qdf_status) {
@@ -4455,7 +4463,7 @@ tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *tran
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	if (QDF_STATUS_SUCCESS != qdf_status) {
 		pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
 		nSirStatus = eSIR_FAILURE;
@@ -4587,7 +4595,7 @@ tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, pFrame, txFlag,
-				smeSessionId, 0);
+				smeSessionId, 0, RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 psessionEntry->peSessionId, qdf_status));
 	if (QDF_STATUS_SUCCESS != qdf_status) {
@@ -4729,7 +4737,8 @@ QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
 			 session->peSessionId, mgmt_hdr->fc.subType));
 	qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t) num_bytes,
 			TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
-			lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0);
+			lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0,
+			RATEID_DEFAULT);
 	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
 			 session->peSessionId, qdf_status));
 	if (QDF_STATUS_SUCCESS != qdf_status) {

+ 61 - 0
core/mac/src/pe/lim/lim_utils.c

@@ -8082,3 +8082,64 @@ QDF_STATUS lim_util_get_type_subtype(void *pkt, uint8_t *type,
 	}
 	return QDF_STATUS_SUCCESS;
 }
+
+enum rateid lim_get_min_session_txrate(tpPESession session)
+{
+	enum rateid rid = RATEID_DEFAULT;
+	uint8_t min_rate = SIR_MAC_RATE_54, curr_rate, i;
+	tSirMacRateSet *rateset = &session->rateSet;
+
+	if (!session)
+		return rid;
+
+	for (i = 0; i < rateset->numRates; i++) {
+		/* Ignore MSB - set to indicate basic rate */
+		curr_rate = rateset->rate[i] & 0x7F;
+		min_rate =  (curr_rate < min_rate) ? curr_rate : min_rate;
+	}
+	pe_debug("supported min_rate: %0x(%d)", min_rate, min_rate);
+
+	switch (min_rate) {
+	case SIR_MAC_RATE_1:
+		rid = RATEID_1MBPS;
+		break;
+	case SIR_MAC_RATE_2:
+		rid = RATEID_2MBPS;
+		break;
+	case SIR_MAC_RATE_5_5:
+		rid = RATEID_5_5MBPS;
+		break;
+	case SIR_MAC_RATE_11:
+		rid = RATEID_11MBPS;
+		break;
+	case SIR_MAC_RATE_6:
+		rid = RATEID_6MBPS;
+		break;
+	case SIR_MAC_RATE_9:
+		rid = RATEID_9MBPS;
+		break;
+	case SIR_MAC_RATE_12:
+		rid = RATEID_12MBPS;
+		break;
+	case SIR_MAC_RATE_18:
+		rid = RATEID_18MBPS;
+		break;
+	case SIR_MAC_RATE_24:
+		rid = RATEID_24MBPS;
+		break;
+	case SIR_MAC_RATE_36:
+		rid = RATEID_36MBPS;
+		break;
+	case SIR_MAC_RATE_48:
+		rid = RATEID_48MBPS;
+		break;
+	case SIR_MAC_RATE_54:
+		rid = RATEID_54MBPS;
+		break;
+	default:
+		rid = RATEID_DEFAULT;
+		break;
+	}
+
+	return rid;
+}

+ 12 - 0
core/mac/src/pe/lim/lim_utils.h

@@ -1192,7 +1192,19 @@ void lim_decrement_pending_mgmt_count(tpAniSirGlobal mac_ctx);
 bool lim_check_if_vendor_oui_match(tpAniSirGlobal mac_ctx,
 					uint8_t *oui, uint8_t oui_len,
 			       uint8_t *ie, uint8_t ie_len);
+
 QDF_STATUS lim_util_get_type_subtype(void *pkt, uint8_t *type,
 					uint8_t *subtype);
 
+/**
+ * lim_get_min_session_txrate() - Get the minimum rate supported in the session
+ * @session: Pointer to PE session
+ *
+ * This API will find the minimum rate supported by the given PE session and
+ * return the enum rateid corresponding to the rate.
+ *
+ * Return: enum rateid
+ */
+enum rateid lim_get_min_session_txrate(tpPESession session);
+
 #endif /* __LIM_UTILS_H */

+ 23 - 5
core/wma/inc/wma_types.h

@@ -487,7 +487,7 @@
 #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
 
 #define wma_tx_frame(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc, \
-		   pData, txFlag, sessionid, channel_freq) \
+		   pData, txFlag, sessionid, channel_freq, rid) \
 	(QDF_STATUS)( wma_tx_packet( \
 		      cds_get_context(QDF_MODULE_ID_WMA), \
 		      (pFrmBuf), \
@@ -501,11 +501,12 @@
 		      (txFlag), \
 		      (sessionid), \
 		      (false), \
-		      (channel_freq)))
+		      (channel_freq), \
+		      (rid)))
 
 #define wma_tx_frameWithTxComplete(hHal, pFrmBuf, frmLen, frmType, txDir, tid, \
 	 pCompFunc, pData, pCBackFnTxComp, txFlag, sessionid, tdlsflag, \
-	 channel_freq) \
+	 channel_freq, rid) \
 	(QDF_STATUS)( wma_tx_packet( \
 		      cds_get_context(QDF_MODULE_ID_WMA), \
 		      (pFrmBuf), \
@@ -519,7 +520,8 @@
 		      (txFlag), \
 		      (sessionid), \
 		      (tdlsflag), \
-		      (channel_freq)))
+		      (channel_freq), \
+		      (rid)))
 
 
 #define WMA_SetEnableSSR(enable_ssr) ((void)enable_ssr)
@@ -690,6 +692,22 @@ enum wma_tdls_off_chan_mode {
 
 #endif /* FEATURE_WLAN_TDLS */
 
+enum rateid {
+	RATEID_1MBPS = 0,
+	RATEID_2MBPS,
+	RATEID_5_5MBPS,
+	RATEID_11MBPS,
+	RATEID_6MBPS,
+	RATEID_9MBPS,
+	RATEID_12MBPS,
+	RATEID_18MBPS,
+	RATEID_24MBPS,
+	RATEID_36MBPS,
+	RATEID_48MBPS = 10,
+	RATEID_54MBPS,
+	RATEID_DEFAULT
+};
+
 tSirRetStatus wma_post_ctrl_msg(tpAniSirGlobal pMac,
 				struct scheduler_msg *pMsg);
 
@@ -715,7 +733,7 @@ QDF_STATUS wma_tx_packet(void *pWMA,
 			 void *pData,
 			 wma_tx_ota_comp_callback pAckTxComp,
 			 uint8_t txFlag, uint8_t sessionId, bool tdlsflag,
-			 uint16_t channel_freq);
+			 uint16_t channel_freq, enum rateid rid);
 
 QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
 		    wma_tgt_cfg_cb pTgtUpdCB, struct cds_config_info *cds_cfg);

+ 64 - 1
core/wma/src/wma_data.c

@@ -2394,6 +2394,58 @@ static int32_t wma_ieee80211_hdrsize(const void *data)
 	return size;
 }
 
+/**
+ * rate_pream: Mapping from data rates to preamble.
+ */
+static uint32_t rate_pream[] = {WMI_RATE_PREAMBLE_CCK, WMI_RATE_PREAMBLE_CCK,
+				WMI_RATE_PREAMBLE_CCK, WMI_RATE_PREAMBLE_CCK,
+				WMI_RATE_PREAMBLE_OFDM, WMI_RATE_PREAMBLE_OFDM,
+				WMI_RATE_PREAMBLE_OFDM, WMI_RATE_PREAMBLE_OFDM,
+				WMI_RATE_PREAMBLE_OFDM, WMI_RATE_PREAMBLE_OFDM,
+				WMI_RATE_PREAMBLE_OFDM, WMI_RATE_PREAMBLE_OFDM};
+
+/**
+ * rate_mcs: Mapping from data rates to MCS (+4 for OFDM to keep the sequence).
+ */
+static uint32_t rate_mcs[] = {WMI_MAX_CCK_TX_RATE_1M, WMI_MAX_CCK_TX_RATE_2M,
+			      WMI_MAX_CCK_TX_RATE_5_5M, WMI_MAX_CCK_TX_RATE_11M,
+			      WMI_MAX_OFDM_TX_RATE_6M + 4,
+			      WMI_MAX_OFDM_TX_RATE_9M + 4,
+			      WMI_MAX_OFDM_TX_RATE_12M + 4,
+			      WMI_MAX_OFDM_TX_RATE_18M + 4,
+			      WMI_MAX_OFDM_TX_RATE_24M + 4,
+			      WMI_MAX_OFDM_TX_RATE_36M + 4,
+			      WMI_MAX_OFDM_TX_RATE_48M + 4,
+			      WMI_MAX_OFDM_TX_RATE_54M + 4};
+
+#define WMA_TX_SEND_MGMT_TYPE 0
+#define WMA_TX_SEND_DATA_TYPE 1
+
+/**
+ * wma_update_tx_send_params() - Update tx_send_params TLV info
+ * @tx_param: Pointer to tx_send_params
+ * @rid: rate ID passed by PE
+ *
+ * Return: None
+ */
+static void wma_update_tx_send_params(struct tx_send_params *tx_param,
+				      enum rateid rid)
+{
+	uint8_t  preamble = 0, nss = 0, rix = 0;
+
+	preamble = rate_pream[rid];
+	rix = rate_mcs[rid];
+
+	tx_param->mcs_mask = (1 << rix);
+	tx_param->nss_mask = (1 << nss);
+	tx_param->preamble_type = (1 << preamble);
+	tx_param->frame_type = WMA_TX_SEND_MGMT_TYPE;
+
+	WMA_LOGD(FL("rate_id: %d, mcs: %0x, nss: %0x, preamble: %0x"),
+		     rid, tx_param->mcs_mask, tx_param->nss_mask,
+		     tx_param->preamble_type);
+}
+
 /**
  * wma_tx_packet() - Sends Tx Frame to TxRx
  * @wma_context: wma context
@@ -2420,7 +2472,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
 			 void *pData,
 			 wma_tx_ota_comp_callback tx_frm_ota_comp_cb,
 			 uint8_t tx_flag, uint8_t vdev_id, bool tdlsFlag,
-			 uint16_t channel_freq)
+			 uint16_t channel_freq, enum rateid rid)
 {
 	tp_wma_handle wma_handle = (tp_wma_handle) (wma_context);
 	int32_t status;
@@ -2797,6 +2849,17 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
 		mgmt_param.chanfreq = chanfreq;
 		mgmt_param.qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
 
+		/*
+		 * Update the tx_params TLV only for rates
+		 * other than 1Mbps and 6 Mbps
+		 */
+		if (rid < RATEID_DEFAULT &&
+		    (rid != RATEID_1MBPS && rid != RATEID_6MBPS)) {
+			WMA_LOGD(FL("using rate id: %d for Tx"), rid);
+			mgmt_param.tx_params_valid = true;
+			wma_update_tx_send_params(&mgmt_param.tx_param, rid);
+		}
+
 		psoc = wma_handle->psoc;
 		if (!psoc) {
 			WMA_LOGE("%s: psoc ctx is NULL", __func__);