From 296a51846faedc853f7da1bb3b99c9cce5ca0aa8 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Mon, 25 Sep 2017 14:02:48 -0700 Subject: [PATCH] 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 --- core/mac/src/pe/lim/lim_p2p.c | 4 +- core/mac/src/pe/lim/lim_process_tdls.c | 11 ++-- .../src/pe/lim/lim_send_frames_host_roam.c | 5 +- .../src/pe/lim/lim_send_management_frames.c | 59 ++++++++++------- core/mac/src/pe/lim/lim_utils.c | 61 +++++++++++++++++ core/mac/src/pe/lim/lim_utils.h | 12 ++++ core/wma/inc/wma_types.h | 28 ++++++-- core/wma/src/wma_data.c | 65 ++++++++++++++++++- 8 files changed, 206 insertions(+), 39 deletions(-) diff --git a/core/mac/src/pe/lim/lim_p2p.c b/core/mac/src/pe/lim/lim_p2p.c index 5da8a6144774..c5e19cf7246c 100644 --- a/core/mac/src/pe/lim/lim_p2p.c +++ b/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"); diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c index 85d5e9b74b1c..a2524d5a6abb 100644 --- a/core/mac/src/pe/lim/lim_process_tdls.c +++ b/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 diff --git a/core/mac/src/pe/lim/lim_send_frames_host_roam.c b/core/mac/src/pe/lim/lim_send_frames_host_roam.c index 293390a44358..bce9c7f45636 100644 --- a/core/mac/src/pe/lim/lim_send_frames_host_roam.c +++ b/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)); diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 45fa672af85f..d815136bcdc2 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/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) { diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index fd732a6e7845..7411801fecdd 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/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; +} diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index adc38424dbd8..b86044adb4f6 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/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 */ diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index a216cad9d952..fdb76bcef668 100644 --- a/core/wma/inc/wma_types.h +++ b/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); diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 09a890b1e371..9adf77bd7966 100644 --- a/core/wma/src/wma_data.c +++ b/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__);