diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index d7b473e3d96f..ea4a690ca5b6 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -655,6 +655,7 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_ROAM_SCAN_CH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 414) #define SIR_HAL_REQ_SEND_DELBA_REQ_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 415) +#define SIR_HAL_SEND_MAX_TX_POWER (SIR_HAL_ITC_MSG_TYPES_BEGIN + 416) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) 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 579b9ed6b8cc..e07e6d6e13d4 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -3727,6 +3727,7 @@ lim_send_tpc_report_frame(struct mac_context *mac, uint32_t nBytes, nPayload, nStatus; void *pPacket; QDF_STATUS qdf_status; + struct vdev_mlme_obj *mlme_obj; qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); @@ -3734,7 +3735,10 @@ lim_send_tpc_report_frame(struct mac_context *mac, frm.Action.action = ACTION_SPCT_TPC_RPRT; frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken; - frm.TPCReport.tx_power = 0; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev); + if (mlme_obj) + frm.TPCReport.tx_power = mlme_obj->mgmt.generic.tx_pwrlimit; + frm.TPCReport.link_margin = 0; frm.TPCReport.present = 1; diff --git a/core/mac/src/pe/rrm/rrm_api.c b/core/mac/src/pe/rrm/rrm_api.c index 469df5287cf1..8609bdf7355e 100644 --- a/core/mac/src/pe/rrm/rrm_api.c +++ b/core/mac/src/pe/rrm/rrm_api.c @@ -229,6 +229,7 @@ rrm_process_link_measurement_request(struct mac_context *mac, tpSirMacMgmtHdr pHdr; int8_t currentRSSI = 0; struct lim_max_tx_pwr_attr tx_pwr_attr = {0}; + struct vdev_mlme_obj *mlme_obj; pe_debug("Received Link measurement request"); @@ -243,6 +244,15 @@ rrm_process_link_measurement_request(struct mac_context *mac, LinkReport.txPower = lim_get_max_tx_power(mac, &tx_pwr_attr); + /** If firmware updated max tx power is non zero, respond to rrm link + * measurement request with min of firmware updated ap tx power and + * max power derived from lim_get_max_tx_power API. + */ + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev); + if (mlme_obj && mlme_obj->mgmt.generic.tx_pwrlimit) + LinkReport.txPower = QDF_MIN(LinkReport.txPower, + mlme_obj->mgmt.generic.tx_pwrlimit); + if ((LinkReport.txPower != (uint8_t) (pe_session->maxTxPower)) && (QDF_STATUS_SUCCESS == rrm_send_set_max_tx_power_req(mac, LinkReport.txPower, diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 64efedc583bf..1a895d47f52e 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -1417,6 +1417,8 @@ populate_dot11f_power_caps(struct mac_context *mac, tDot11fIEPowerCaps *pCaps, uint8_t nAssocType, struct pe_session *pe_session) { + struct vdev_mlme_obj *mlme_obj; + if (nAssocType == LIM_REASSOC) { pCaps->minTxPower = pe_session->pLimReAssocReq->powerCap.minTxPower; @@ -1430,6 +1432,11 @@ populate_dot11f_power_caps(struct mac_context *mac, } + /* Use firmware updated max tx power if non zero */ + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev); + if (mlme_obj && mlme_obj->mgmt.generic.tx_pwrlimit) + pCaps->maxTxPower = mlme_obj->mgmt.generic.tx_pwrlimit; + pCaps->present = 1; } /* End populate_dot11f_power_caps. */ diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index c5c244bfe63a..617c5ae55790 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -7649,6 +7649,21 @@ static inline void csr_roam_process_he_info(struct join_rsp *sme_join_rsp, } #endif +static void csr_update_tx_pwr_to_fw(struct mac_context *mac_ctx, + uint8_t vdev_id) +{ + struct scheduler_msg msg = {0}; + + msg.type = WMA_SEND_MAX_TX_POWER; + msg.bodyval = vdev_id; + if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, + &msg)) { + sme_err("Failed to post WMA_SEND_MAX_TX_POWER message to WMA"); + } +} + /** * csr_roam_process_join_res() - Process the Join results * @mac_ctx: Global MAC Context @@ -8057,6 +8072,8 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, #endif csr_roam_link_up(mac_ctx, conn_profile->bssid); } + + csr_update_tx_pwr_to_fw(mac_ctx, session_id); sme_free_join_rsp_fils_params(roam_info); qdf_mem_free(roam_info); } diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 93a0c51dfda6..1946cefa2c01 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1071,6 +1071,15 @@ void wma_set_max_tx_power(WMA_HANDLE handle, void wma_disable_sta_ps_mode(tpDisablePsParams ps_req); +/** + * wma_send_max_tx_pwrlmt() - send max tx power limit to fw + * @handle: wma handle + * @vdev_id: vdev id + * + * Return: none + */ +void wma_send_max_tx_pwrlmt(WMA_HANDLE handle, uint8_t vdev_id); + /** * wma_enable_uapsd_mode() - enable uapsd mode in fw * @wma: wma handle diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index bf33afbe9d11..237305f38f18 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -175,6 +175,7 @@ #define WMA_SET_TX_POWER_REQ SIR_HAL_SET_TX_POWER_REQ #define WMA_SET_TX_POWER_RSP SIR_HAL_SET_TX_POWER_RSP #define WMA_GET_TX_POWER_REQ SIR_HAL_GET_TX_POWER_REQ +#define WMA_SEND_MAX_TX_POWER SIR_HAL_SEND_MAX_TX_POWER #define WMA_ENABLE_UAPSD_REQ SIR_HAL_ENABLE_UAPSD_REQ #define WMA_DISABLE_UAPSD_REQ SIR_HAL_DISABLE_UAPSD_REQ diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 8c0d6ff70a69..7b0c33730663 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1285,6 +1285,11 @@ QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_SUCCESS; } + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + mlme_obj->mgmt.generic.tx_pwrlimit = rsp->max_allowed_tx_power; if (iface->type == WMI_VDEV_TYPE_STA) assoc_type = mlme_get_assoc_type(vdev_mlme->vdev); @@ -1297,11 +1302,6 @@ QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme, if (QDF_IS_STATUS_ERROR(status)) return QDF_STATUS_E_FAILURE; } else if (iface->type == WMI_VDEV_TYPE_OCB) { - mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); - if (!mlme_obj) { - WMA_LOGE("%s: Failed to get mlme obj", __func__); - return QDF_STATUS_E_INVAL; - } mlme_obj->proto.sta.assoc_id = iface->aid; if (vdev_mgr_up_send(mlme_obj) != QDF_STATUS_SUCCESS) { WMA_LOGE(FL("failed to send vdev up")); @@ -1319,11 +1319,6 @@ QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme, WMA_LOGE("%s: Failed to get bssid", __func__); return QDF_STATUS_E_INVAL; } - mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); - if (!mlme_obj) { - WMA_LOGE("%s: Failed to get mlme obj", __func__); - return QDF_STATUS_E_INVAL; - } qdf_mem_copy(mlme_obj->mgmt.generic.bssid, bss_peer.bytes, QDF_MAC_ADDR_SIZE); wma_vdev_start_rsp(wma, vdev_mlme->vdev, rsp); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index eb48e026562d..91630eeba626 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -8460,6 +8460,9 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) wma_set_max_tx_power(wma_handle, (tpMaxTxPowerParams) msg->bodyptr); break; + case WMA_SEND_MAX_TX_POWER: + wma_send_max_tx_pwrlmt(wma_handle, msg->bodyval); + break; case WMA_SET_KEEP_ALIVE: wma_set_keepalive_req(wma_handle, msg->bodyptr); break; diff --git a/core/wma/src/wma_power.c b/core/wma/src/wma_power.c index 7d6321a45dba..5b914e0e46e9 100644 --- a/core/wma/src/wma_power.c +++ b/core/wma/src/wma_power.c @@ -401,6 +401,32 @@ end: WMA_LOGE("Failed to set vdev param WMI_VDEV_PARAM_TX_PWRLIMIT"); } +void wma_send_max_tx_pwrlmt(WMA_HANDLE handle, uint8_t vdev_id) +{ + uint32_t max_tx_pwr; + struct wma_txrx_node *iface; + struct vdev_mlme_obj *mlme_obj; + tp_wma_handle wma_handle = (tp_wma_handle) handle; + + iface = &wma_handle->interfaces[vdev_id]; + if (!iface) { + wma_err("Failed to get iface handle for vdev_id %d", vdev_id); + return; + } + + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!mlme_obj) + return; + + max_tx_pwr = mlme_obj->mgmt.generic.tx_pwrlimit; + if (!max_tx_pwr) + return; + + wma_vdev_set_param(wma_handle->wmi_handle, vdev_id, + WMI_VDEV_PARAM_TX_PWRLIMIT, + max_tx_pwr); +} + /** * wma_set_max_tx_power() - set max tx power limit in fw * @handle: wma handle diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 9dc499b0d488..bb24935afc3b 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -3218,6 +3218,7 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, struct wma_txrx_node *iface = NULL; wmi_roam_synch_event_fixed_param *synch_event = NULL; WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf = NULL; + struct vdev_mlme_obj *mlme_obj; if (!event) { wma_err_rl("event param null"); @@ -3242,6 +3243,11 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, } iface = &wma->interfaces[synch_event->vdev_id]; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (mlme_obj) + mlme_obj->mgmt.generic.tx_pwrlimit = + synch_event->max_allowed_tx_power; + qdf_status = wlan_vdev_mlme_sm_deliver_evt(iface->vdev, WLAN_VDEV_SM_EV_ROAM, len,