Przeglądaj źródła

qcacld-3.0: Update max tx pwr allowed received from fw

Wlan firmware updates "max tx pwr allowed" to host in vdev start response
event and roam sync indication event. Host uses this value to update
power constraint ie in assoc request and TPC query response.

Host updates "max tx pwr allowed" value to firmware after association
completion, so that firmware uses the same max power to transmit mgmt and
data frames.

Change-Id: Ifd8d47fd830bd02bdde2633c22ea82820adf73a0
CRs-Fixed: 2652690
Abhishek Ambure 5 lat temu
rodzic
commit
716952641d

+ 1 - 0
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)
 

+ 5 - 1
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;
 

+ 10 - 0
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,

+ 7 - 0
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. */
 

+ 17 - 0
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);
 }

+ 9 - 0
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

+ 1 - 0
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

+ 5 - 10
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);

+ 3 - 0
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;

+ 26 - 0
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

+ 6 - 0
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,