Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b160a90b authored by Jingxiang Ge's avatar Jingxiang Ge
Browse files

qcacld-3.0: Classify qmi/wmi for WMI_REQUEST_STATS_CMDID

Current only TYPE_STATION_STATS is designed to be send
by qmi. and other request type should send by wmi.
if sending by qmi, qmi_get/qmi_put should be call to protect
qmi send and qmi response.

Change to check type and only allow TYPE_STATION_STATS to be
send by qmi.

Change-Id: I57b0bdb6717e259606993ea24ef024745a456664
CRs-Fixed: 3073744
parent 071b358f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1320,11 +1320,20 @@ static QDF_STATUS target_if_cp_stats_send_stats_req(
		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;

	/* only very frequent periodic stats needs to go over QMI.
	 * for that, wlan_hdd_qmi_get_sync_resume/wlan_hdd_qmi_put_suspend
	 * needs to be called to cover the period between qmi send and
	 * qmi resonse.
	 */
	if (TYPE_STATION_STATS == type)
		param.is_qmi_send_support = true;

	return wmi_unified_stats_request_send(wmi_handle, req->peer_mac_addr,
					      &param);
}
+10 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <cdp_txrx_stats_struct.h>
#include <cdp_txrx_peer_ops.h>
#include <cdp_txrx_host_stats.h>
#include "wlan_hdd_stats.h"

/*
 * define short names for the global vendor params
@@ -2417,8 +2418,17 @@ int32_t hdd_cfg80211_get_sta_info_cmd(struct wiphy *wiphy,
	if (errno)
		return errno;

	errno = wlan_hdd_qmi_get_sync_resume();
	if (errno) {
		hdd_err("qmi sync resume failed: %d", errno);
		goto end;
	}

	errno = __hdd_cfg80211_get_sta_info_cmd(wiphy, wdev, data, data_len);

	wlan_hdd_qmi_put_suspend();

end:
	osif_vdev_sync_op_stop(vdev_sync);

	return errno;
+83 −70
Original line number Diff line number Diff line
@@ -242,6 +242,79 @@ hdd_update_station_stats_cached_timestamp(struct hdd_adapter *adapter)
}
#endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */

#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
/**
 * wlan_hdd_qmi_get_sync_resume() - Get operation to trigger RTPM
 * sync resume without WoW exit
 *
 * call qmi_get before sending qmi, and do qmi_put after all the
 * qmi response rececived from fw. so this request wlan host to
 * wait for the last qmi response, if it doesn't wait, qmi put
 * which cause MHI enter M3(suspend) before all the qmi response,
 * and MHI will trigger a RTPM resume, this violated design of by
 * sending cmd by qmi without wow resume.
 *
 * Returns: 0 for success, non-zero for failure
 */
int wlan_hdd_qmi_get_sync_resume(void)
{
	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	if (!hdd_ctx->config->is_qmi_stats_enabled) {
		hdd_debug("periodic stats over qmi is disabled");
		return 0;
	}

	if (!qdf_ctx) {
		hdd_err("qdf_ctx is null");
		return -EINVAL;
	}

	return pld_qmi_send_get(qdf_ctx->dev);
}

/**
 * wlan_hdd_qmi_put_suspend() - Put operation to trigger RTPM suspend
 * without WoW entry
 *
 * Returns: 0 for success, non-zero for failure
 */
int wlan_hdd_qmi_put_suspend(void)
{
	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	if (!hdd_ctx->config->is_qmi_stats_enabled) {
		hdd_debug("periodic stats over qmi is disabled");
		return 0;
	}

	if (!qdf_ctx) {
		hdd_err("qdf_ctx is null");
		return -EINVAL;
	}

	return pld_qmi_send_put(qdf_ctx->dev);
}
#else
int wlan_hdd_qmi_get_sync_resume(void)
{
	return 0;
}

int wlan_hdd_qmi_put_suspend(void)
{
	return 0;
}
#endif /* end if of WLAN_FEATURE_WMI_SEND_RECV_QMI */

#ifdef WLAN_FEATURE_LINK_LAYER_STATS

/**
@@ -2113,61 +2186,6 @@ __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
	return 0;
}

#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
/**
 * wlan_hdd_qmi_get_sync_resume() - Get operation to trigger RTPM
 * sync resume without WoW exit
 * @hdd_ctx: hdd context
 * @dev: device context
 *
 * Returns: 0 for success, non-zero for failure
 */
static inline
int wlan_hdd_qmi_get_sync_resume(struct hdd_context *hdd_ctx,
				 struct device *dev)
{
	if (!hdd_ctx->config->is_qmi_stats_enabled) {
		hdd_debug("periodic stats over qmi is disabled");
		return 0;
	}

	return pld_qmi_send_get(dev);
}

/**
 * wlan_hdd_qmi_put_suspend() - Put operation to trigger RTPM suspend
 * without WoW entry
 * @hdd_ctx: hdd context
 * @dev: device context
 *
 * Returns: 0 for success, non-zero for failure
 */
static inline
int wlan_hdd_qmi_put_suspend(struct hdd_context *hdd_ctx,
			     struct device *dev)
{
	if (!hdd_ctx->config->is_qmi_stats_enabled) {
		hdd_debug("periodic stats over qmi is disabled");
		return 0;
	}

	return pld_qmi_send_put(dev);
}
#else
static inline
int wlan_hdd_qmi_get_sync_resume(struct hdd_context *hdd_ctx,
				 struct device *dev)
{
	return 0;
}

static inline int wlan_hdd_qmi_put_suspend(struct hdd_context *hdd_ctx,
					   struct device *dev)
{
	return 0;
}
#endif /* end if of WLAN_FEATURE_WMI_SEND_RECV_QMI */

/**
 * wlan_hdd_cfg80211_ll_stats_get() - get ll stats
 * @wiphy: Pointer to wiphy
@@ -2185,26 +2203,23 @@ int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct osif_vdev_sync *vdev_sync;
	int errno;
	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);

	errno = wlan_hdd_validate_context(hdd_ctx);
	if (0 != errno)
		return -EINVAL;

	if (!qdf_ctx)
		return -EINVAL;

	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
	if (errno)
		return errno;

	errno = wlan_hdd_qmi_get_sync_resume(hdd_ctx, qdf_ctx->dev);
	if (errno)
	errno = wlan_hdd_qmi_get_sync_resume();
	if (errno) {
		hdd_err("qmi sync resume failed: %d", errno);
		goto end;

	}
	errno = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);

	wlan_hdd_qmi_put_suspend(hdd_ctx, qdf_ctx->dev);
	wlan_hdd_qmi_put_suspend();

end:
	osif_vdev_sync_op_stop(vdev_sync);
@@ -5937,7 +5952,6 @@ static int _wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
	int errno;
	QDF_STATUS status;

@@ -5945,9 +5959,6 @@ static int _wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
	if (errno)
		return errno;

	if (!qdf_ctx)
		return -EINVAL;

	status = wlan_hdd_stats_request_needed(adapter);
	if (QDF_IS_STATUS_ERROR(status)) {
		if (status == QDF_STATUS_E_ALREADY)
@@ -5957,15 +5968,17 @@ static int _wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
	}

	if (get_station_fw_request_needed) {
		errno = wlan_hdd_qmi_get_sync_resume(hdd_ctx, qdf_ctx->dev);
		if (errno)
		errno = wlan_hdd_qmi_get_sync_resume();
		if (errno) {
			hdd_err("qmi sync resume failed: %d", errno);
			return errno;
		}
	}

	errno = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);

	if (get_station_fw_request_needed)
		wlan_hdd_qmi_put_suspend(hdd_ctx, qdf_ctx->dev);
		wlan_hdd_qmi_put_suspend();

	get_station_fw_request_needed = true;

+3 −0
Original line number Diff line number Diff line
@@ -492,6 +492,9 @@ int wlan_hdd_get_link_speed(struct hdd_adapter *adapter, uint32_t *link_speed);
 */
int wlan_hdd_get_station_stats(struct hdd_adapter *adapter);

int wlan_hdd_qmi_get_sync_resume(void);
int wlan_hdd_qmi_put_suspend(void);

#ifdef WLAN_FEATURE_BIG_DATA_STATS
/**
 * wlan_hdd_get_big_data_station_stats() - Get big data station statistics
+9 −0
Original line number Diff line number Diff line
@@ -8387,8 +8387,17 @@ static int iw_get_statistics(struct net_device *dev,
	if (errno)
		return errno;

	errno = wlan_hdd_qmi_get_sync_resume();
	if (errno) {
		hdd_err("qmi sync resume failed: %d", errno);
		goto end;
	}

	errno = __iw_get_statistics(dev, info, wrqu, extra);

	wlan_hdd_qmi_put_suspend();

end:
	osif_vdev_sync_op_stop(vdev_sync);

	return errno;