Parcourir la source

qcacmn: Add target_if/wmi implementation of get_tx_power

Add changes to support get tx power from within cp_stats component.

Change-Id: I89ac372bd31a8aa5a76938dc4ea4cfe05d6c7cf1
CRs-Fixed: 2210311
Naveen Rawat il y a 7 ans
Parent
commit
299269828a

+ 1 - 1
target_if/cp_stats/inc/target_if_cp_stats.h

@@ -72,7 +72,7 @@ target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
  */
 QDF_STATUS
-target_if_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *tx_ops);
+target_if_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops);
 #else
 static inline QDF_STATUS
 target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)

+ 6 - 0
target_if/cp_stats/src/target_if_cp_stats.c

@@ -78,3 +78,9 @@ target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS
+target_if_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+	return QDF_STATUS_SUCCESS;
+}

+ 186 - 3
target_if/cp_stats/src/target_if_mc_cp_stats.c

@@ -40,7 +40,129 @@
 #include <wlan_tgt_def_config.h>
 #include <wmi_unified_api.h>
 #include <wlan_osif_priv.h>
-#include "wlan_cp_stats_utils_api.h"
+#include <wlan_cp_stats_utils_api.h>
+#include <wlan_cp_stats_mc_tgt_api.h>
+
+#define TGT_INVALID_SNR         (0)
+#define TGT_NOISE_FLOOR_DBM     (-96)
+#define TGT_MAX_SNR             (TGT_NOISE_FLOOR_DBM * (-1))
+#define TGT_IS_VALID_SNR(x)     ((x) >= 0 && (x) < TGT_MAX_SNR)
+
+static void target_if_cp_stats_free_stats_event(struct stats_event *ev)
+{
+	qdf_mem_free(ev->pdev_stats);
+	ev->pdev_stats = NULL;
+}
+
+static QDF_STATUS target_if_cp_stats_extract_pdev_stats(
+					struct wmi_unified *wmi_hdl,
+					wmi_host_stats_event *stats_param,
+					struct stats_event *ev,
+					uint8_t *data)
+{
+	uint32_t i;
+	QDF_STATUS status;
+	wmi_host_pdev_stats pdev_stats;
+
+	ev->num_pdev_stats = stats_param->num_pdev_stats;
+	if (!ev->num_pdev_stats)
+		return QDF_STATUS_SUCCESS;
+
+	/*
+	 * num_pdev_stats is validated within function wmi_extract_stats_param
+	 * which is called to populated wmi_host_stats_event stats_param
+	 */
+	ev->pdev_stats = qdf_mem_malloc(sizeof(*ev->pdev_stats) *
+						ev->num_pdev_stats);
+	if (!ev->pdev_stats) {
+		cp_stats_err("malloc failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	for (i = 0; i < ev->num_pdev_stats; i++) {
+		status = wmi_extract_pdev_stats(wmi_hdl, data, i, &pdev_stats);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			cp_stats_err("wmi_extract_pdev_stats failed");
+			return status;
+		}
+		ev->pdev_stats[i].max_pwr = pdev_stats.chan_tx_pwr;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
+						   struct stats_event *ev,
+						   uint8_t *data)
+{
+	QDF_STATUS status;
+	wmi_host_stats_event stats_param = {0};
+
+	status = wmi_extract_stats_param(wmi_hdl, data, &stats_param);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_debug("stats param extract failed: %d", status);
+		return status;
+	}
+	cp_stats_debug("num: pdev: %d, vdev: %d, peer: %d, rssi: %d",
+		       stats_param.num_pdev_stats, stats_param.num_vdev_stats,
+		       stats_param.num_peer_stats, stats_param.num_rssi_stats);
+
+	status = target_if_cp_stats_extract_pdev_stats(wmi_hdl, &stats_param,
+						       ev, data);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * target_if_mc_cp_stats_stats_event_handler() - function to handle stats event
+ * from firmware.
+ * @scn: scn handle
+ * @data: data buffer for event
+ * @datalen: data length
+ *
+ * Return: status of operation.
+ */
+static int target_if_mc_cp_stats_stats_event_handler(ol_scn_t scn,
+						     uint8_t *data,
+						     uint32_t datalen)
+{
+	QDF_STATUS status;
+	struct stats_event ev = {0};
+	struct wlan_objmgr_psoc *psoc;
+	struct wmi_unified *wmi_handle;
+	struct wlan_lmac_if_cp_stats_rx_ops *rx_ops;
+
+	if (!scn || !data) {
+		cp_stats_err("scn: 0x%pK, data: 0x%pK", scn, data);
+		return -EINVAL;
+	}
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		cp_stats_err("null psoc");
+		return -EINVAL;
+	}
+	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+
+	rx_ops = target_if_cp_stats_get_rx_ops(psoc);
+	if (!rx_ops || !rx_ops->process_stats_event) {
+		cp_stats_err("callback not registered");
+		return -EINVAL;
+	}
+
+	status = target_if_cp_stats_extract_event(wmi_handle, &ev, data);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("extract event failed");
+		goto end;
+	}
+
+	status = rx_ops->process_stats_event(psoc, &ev);
+
+end:
+	target_if_cp_stats_free_stats_event(&ev);
+	return qdf_status_to_os_return(status);
+}
 
 static void target_if_cp_stats_inc_wake_lock_stats(uint32_t reason,
 					struct wake_lock_stats *stats,
@@ -86,9 +208,20 @@ static void target_if_cp_stats_inc_wake_lock_stats(uint32_t reason,
 static QDF_STATUS
 target_if_cp_stats_register_event_handler(struct wlan_objmgr_psoc *psoc)
 {
+	QDF_STATUS status;
+
 	if (!psoc) {
 		cp_stats_err("PSOC is NULL!");
-		return QDF_STATUS_E_INVAL;
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = wmi_unified_register_event_handler(GET_WMI_HDL_FROM_PSOC(psoc),
+			wmi_update_stats_event_id,
+			target_if_mc_cp_stats_stats_event_handler,
+			WMI_RX_WORK_CTX);
+	if (status) {
+		cp_stats_err("Failed to register stats event cb");
+		return status;
 	}
 
 	return QDF_STATUS_SUCCESS;
@@ -102,9 +235,52 @@ target_if_cp_stats_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
 		return QDF_STATUS_E_INVAL;
 	}
 
+	wmi_unified_unregister_event_handler(GET_WMI_HDL_FROM_PSOC(psoc),
+					     wmi_update_stats_event_id);
+
 	return QDF_STATUS_SUCCESS;
 }
 
+static uint32_t get_stats_id(enum stats_req_type type)
+{
+	switch (type) {
+	default:
+		break;
+	case TYPE_CONNECTION_TX_POWER:
+		return WMI_REQUEST_PDEV_STAT;
+	}
+	return 0;
+}
+
+/**
+ * target_if_cp_stats_send_stats_req() - API to send stats request to wmi
+ * @psoc: pointer to psoc object
+ * @req: pointer to object containing stats request parameters
+ *
+ * Return: status of operation.
+ */
+static QDF_STATUS target_if_cp_stats_send_stats_req(
+					struct wlan_objmgr_psoc *psoc,
+					enum stats_req_type type,
+					struct request_info *req)
+
+{
+	struct wmi_unified *wmi_handle;
+	struct stats_request_params param = {0};
+
+	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+	if (!wmi_handle) {
+		cp_stats_err("wmi_handle is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+	/* refer  (WMI_REQUEST_STATS_CMDID) */
+	param.stats_id = get_stats_id(type);
+	param.vdev_id = req->vdev_id;
+	param.pdev_id = req->pdev_id;
+	return wmi_unified_stats_request_send(wmi_handle, req->peer_mac_addr,
+					      &param);
+}
+
 QDF_STATUS
 target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 {
@@ -127,7 +303,14 @@ target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 		target_if_cp_stats_unregister_event_handler;
 	cp_stats_tx_ops->inc_wake_lock_stats =
 		target_if_cp_stats_inc_wake_lock_stats;
-
+	cp_stats_tx_ops->send_req_stats = target_if_cp_stats_send_stats_req;
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS
+target_if_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+	rx_ops->cp_stats_rx_ops.process_stats_event =
+					tgt_mc_cp_stats_process_stats_event;
+	return QDF_STATUS_SUCCESS;
+}

+ 2 - 0
wmi/inc/wmi_unified_param.h

@@ -4874,6 +4874,7 @@ struct rx_reorder_queue_remove_params {
  * @num_chan_stats: number of channel stats
  * @pdev_id: device id for the radio
  * @num_bcn_stats: number of beacon stats
+ * @num_rssi_stats: number of rssi stats
  */
 typedef struct {
 	wmi_host_stats_id stats_id;
@@ -4885,6 +4886,7 @@ typedef struct {
 	uint32_t num_chan_stats;
 	uint32_t pdev_id;
 	uint32_t num_bcn_stats;
+	uint32_t num_rssi_stats;
 } wmi_host_stats_event;
 
 /**

+ 19 - 3
wmi/src/wmi_unified_tlv.c

@@ -19145,14 +19145,16 @@ static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle,
 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
 	void *evt_buf, wmi_host_stats_event *stats_param)
 {
-	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
 	wmi_stats_event_fixed_param *ev;
+	wmi_per_chain_rssi_stats *rssi_event;
+	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
 
+	qdf_mem_zero(stats_param, sizeof(*stats_param));
 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
-
 	ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
+	rssi_event = param_buf->chain_stats;
 	if (!ev) {
-		WMI_LOGE("%s: Failed to alloc memory\n", __func__);
+		WMI_LOGE("%s: event fixed param NULL\n", __func__);
 		return QDF_STATUS_E_FAILURE;
 	}
 
@@ -19201,6 +19203,20 @@ static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
 	stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
 							ev->pdev_id);
 
+	/* if chain_stats is not populated */
+	if (!param_buf->chain_stats || !param_buf->num_chain_stats)
+		return QDF_STATUS_SUCCESS;
+
+	if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats !=
+	    WMITLV_GET_TLVTAG(rssi_event->tlv_header))
+		return QDF_STATUS_SUCCESS;
+
+	if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) !=
+	    WMITLV_GET_TLVTAG(rssi_event->tlv_header))
+		return QDF_STATUS_SUCCESS;
+
+	stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats;
+
 	return QDF_STATUS_SUCCESS;
 }