qcacmn: Add support for WMI over QMI

Add support for WMI over QMI to reduce power consumption for
periodic stats report.

Change-Id: Ic57b2bd18be803c97ffeea2e0073751d31e02202
CRs-fixed: 2521835
This commit is contained in:
Manikandan Mohan
2019-08-23 08:47:21 -07:00
committed by nshrivas
parent 258eb6429b
commit 9b1b93cfcd
5 changed files with 201 additions and 8 deletions

View File

@@ -61,6 +61,51 @@ void qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down);
*/ */
bool qdf_is_fw_down(void); bool qdf_is_fw_down(void);
/**
* qdf_wmi_recv_qmi_cb() - callback to receive WMI over QMI
* @cb_ctx: WMI event recv callback context(wmi_handle)
* @buf: WMI buffer
* @len: WMI buffer len
*
* Return: 0 if success otherwise -EINVAL
*/
typedef int (*qdf_wmi_recv_qmi_cb)(void *cb_ctx, void *buf, int len);
/**
* qdf_wmi_send_over_qmi_callback() - callback to send WMI over QMI
* @buf: WMI buffer
* @len: WMI buffer len
* @cb_ctx: WMI event recv callback context(wmi_handle)
* @wmi_rx_cb: WMI event receive call back
*
* Return: QDF_STATUS_SUCCESS if success otherwise QDF error code
*/
typedef QDF_STATUS (*qdf_wmi_send_over_qmi_callback)(void *buf, uint32_t len,
void *cb_ctx,
qdf_wmi_recv_qmi_cb
wmi_rx_cb);
/**
* qdf_register_wmi_send_recv_qmi_callback() - Register WMI over QMI callback
* @qdf_wmi_send_over_qmi_callback: callback to send recv WMI data over QMI
*
* Return: none
*/
void qdf_register_wmi_send_recv_qmi_callback(qdf_wmi_send_over_qmi_callback
wmi_send_recv_qmi_cb);
/**
* qdf_wmi_send_recv_qmi() - API to send receive WMI data over QMI
* @buf: WMI buffer
* @len: WMI buffer len
* @cb_ctx: WMI event recv callback context(wmi_handle)
* @wmi_rx_cb: WMI event receive call back
*
* Return: QDF STATUS of operation
*/
QDF_STATUS qdf_wmi_send_recv_qmi(void *buf, uint32_t len, void *cb_ctx,
qdf_wmi_recv_qmi_cb wmi_rx_cb);
/** /**
* qdf_register_self_recovery_callback() - register self recovery callback * qdf_register_self_recovery_callback() - register self recovery callback
* @callback: self recovery callback * @callback: self recovery callback

View File

@@ -28,6 +28,7 @@ static qdf_self_recovery_callback self_recovery_cb;
static qdf_is_fw_down_callback is_fw_down_cb; static qdf_is_fw_down_callback is_fw_down_cb;
static qdf_is_recovering_callback is_recovering_cb; static qdf_is_recovering_callback is_recovering_cb;
static qdf_is_drv_connected_callback is_drv_connected_cb; static qdf_is_drv_connected_callback is_drv_connected_cb;
static qdf_wmi_send_over_qmi_callback _wmi_send_recv_qmi_cb;
void qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down) void qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down)
{ {
@@ -46,9 +47,30 @@ bool qdf_is_fw_down(void)
return is_fw_down_cb(); return is_fw_down_cb();
} }
qdf_export_symbol(qdf_is_fw_down); qdf_export_symbol(qdf_is_fw_down);
void qdf_register_wmi_send_recv_qmi_callback(qdf_wmi_send_over_qmi_callback
wmi_send_recv_qmi_cb)
{
_wmi_send_recv_qmi_cb = wmi_send_recv_qmi_cb;
}
qdf_export_symbol(qdf_register_wmi_send_recv_qmi_callback);
QDF_STATUS qdf_wmi_send_recv_qmi(void *buf, uint32_t len, void *cb_ctx,
qdf_wmi_recv_qmi_cb wmi_recv_qmi_cb)
{
if (!_wmi_send_recv_qmi_cb) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"Platform callback for WMI over QMI not registered");
return QDF_STATUS_E_INVAL;
}
return _wmi_send_recv_qmi_cb(buf, len, cb_ctx, wmi_recv_qmi_cb);
}
qdf_export_symbol(qdf_wmi_send_recv_qmi);
void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback) void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback)
{ {
self_recovery_cb = callback; self_recovery_cb = callback;

View File

@@ -276,6 +276,45 @@ wmi_unified_cmd_send_fl(wmi_unified_t wmi_handle, wmi_buf_t buf,
uint32_t buflen, uint32_t cmd_id, uint32_t buflen, uint32_t cmd_id,
const char *func, uint32_t line); const char *func, uint32_t line);
#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
/**
* wmi_unified_cmd_send_over_qmi() - generic function to send unified WMI command
* over QMI
* @wmi_handle: handle to WMI.
* @buf: wmi command buffer
* @buflen: wmi command buffer length
* @cmd_id: WMI cmd id
*
* Return: QDF_STATUS
*/
QDF_STATUS wmi_unified_cmd_send_over_qmi(struct wmi_unified *wmi_handle,
wmi_buf_t buf, uint32_t buflen,
uint32_t cmd_id);
/**
* wmi_process_qmi_fw_event() - Process WMI event received over QMI
* @wmi_cb_ctx: WMI handle received as call back context
* @buf: Pointer to WMI event buffer
* @len: Len of WMI buffer received
*
* Return: None
*/
int wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len);
#else
static inline
QDF_STATUS wmi_unified_cmd_send_over_qmi(struct wmi_unified *wmi_handle,
wmi_buf_t buf, uint32_t buflen,
uint32_t cmd_id)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline int wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len)
{
return -EINVAL;
}
#endif
/** /**
* wmi_unified_register_event() - WMI event handler * wmi_unified_register_event() - WMI event handler
* registration function for converged components * registration function for converged components

View File

@@ -1682,6 +1682,70 @@ static inline void wmi_unified_debug_dump(wmi_unified_t wmi_handle)
"WMI_NON_TLV_TARGET")); "WMI_NON_TLV_TARGET"));
} }
#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
QDF_STATUS wmi_unified_cmd_send_over_qmi(struct wmi_unified *wmi_handle,
wmi_buf_t buf, uint32_t buflen,
uint32_t cmd_id)
{
QDF_STATUS status;
if (!qdf_nbuf_push_head(buf, sizeof(WMI_CMD_HDR))) {
wmi_err("Failed to send cmd %x, no memory", cmd_id);
return QDF_STATUS_E_NOMEM;
}
qdf_mem_zero(qdf_nbuf_data(buf), sizeof(WMI_CMD_HDR));
WMI_SET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID, cmd_id);
wmi_debug("Sending WMI_CMD_ID: %d over qmi", cmd_id);
status = qdf_wmi_send_recv_qmi(qdf_nbuf_data(buf),
buflen + sizeof(WMI_CMD_HDR),
wmi_handle,
wmi_process_qmi_fw_event);
if (QDF_IS_STATUS_ERROR(status)) {
qdf_nbuf_pull_head(buf, sizeof(WMI_CMD_HDR));
wmi_warn("WMI send on QMI failed. Retrying WMI on HTC");
} else {
wmi_buf_free(buf);
}
return status;
}
static int __wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len)
{
struct wmi_unified *wmi_handle = wmi_cb_ctx;
wmi_buf_t evt_buf;
uint32_t evt_id;
if (!wmi_handle || !buf)
return -EINVAL;
evt_buf = wmi_buf_alloc(wmi_handle, len);
if (!evt_buf)
return -ENOMEM;
qdf_mem_copy(qdf_nbuf_data(evt_buf), buf, len);
evt_id = WMI_GET_FIELD(qdf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID);
wmi_debug("Received WMI_EVT_ID: %d over qmi", evt_id);
wmi_process_fw_event(wmi_handle, evt_buf);
return 0;
}
int wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len)
{
struct qdf_op_sync *op_sync;
int ret;
if (qdf_op_protect(&op_sync))
return -EINVAL;
ret = __wmi_process_qmi_fw_event(wmi_cb_ctx, buf, len);
qdf_op_unprotect(op_sync);
return ret;
}
#endif
QDF_STATUS wmi_unified_cmd_send_fl(wmi_unified_t wmi_handle, wmi_buf_t buf, QDF_STATUS wmi_unified_cmd_send_fl(wmi_unified_t wmi_handle, wmi_buf_t buf,
uint32_t len, uint32_t cmd_id, uint32_t len, uint32_t cmd_id,
const char *func, uint32_t line) const char *func, uint32_t line)

View File

@@ -566,9 +566,32 @@ void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data)
qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET,
mtrace_message_id, vdev_id, data); mtrace_message_id, vdev_id, data);
} }
qdf_export_symbol(wmi_mtrace); qdf_export_symbol(wmi_mtrace);
#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
static QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle,
wmi_buf_t buf,
uint32_t buflen, uint32_t cmd_id)
{
if (wmi_is_target_suspended(wmi_handle)) {
if (QDF_IS_STATUS_SUCCESS(
wmi_unified_cmd_send_over_qmi(wmi_handle, buf,
buflen, cmd_id)))
return QDF_STATUS_SUCCESS;
}
return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id);
}
#else
static inline
QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle,
wmi_buf_t buf,
uint32_t buflen, uint32_t cmd_id)
{
return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id);
}
#endif
/** /**
* send_vdev_create_cmd_tlv() - send VDEV create command to fw * send_vdev_create_cmd_tlv() - send VDEV create command to fw
* @wmi_handle: wmi handle * @wmi_handle: wmi handle
@@ -1975,8 +1998,8 @@ static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
cmd->stats_id, cmd->vdev_id, cmd->pdev_id); cmd->stats_id, cmd->vdev_id, cmd->pdev_id);
wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len, ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len,
WMI_REQUEST_STATS_CMDID); WMI_REQUEST_STATS_CMDID);
if (ret) { if (ret) {
WMI_LOGE("Failed to send status request to fw =%d", ret); WMI_LOGE("Failed to send status request to fw =%d", ret);
@@ -4842,8 +4865,8 @@ static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle,
WMI_LOGD("Peer MAC Addr: %pM", get_req->peer_macaddr.bytes); WMI_LOGD("Peer MAC Addr: %pM", get_req->peer_macaddr.bytes);
wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len, ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len,
WMI_REQUEST_LINK_STATS_CMDID); WMI_REQUEST_LINK_STATS_CMDID);
if (ret) { if (ret) {
WMI_LOGE("%s: Failed to send get link stats request", __func__); WMI_LOGE("%s: Failed to send get link stats request", __func__);
wmi_buf_free(buf); wmi_buf_free(buf);
@@ -4922,8 +4945,8 @@ static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle)
(wmi_request_stats_cmd_fixed_param)); (wmi_request_stats_cmd_fixed_param));
cmd->stats_id = WMI_REQUEST_VDEV_STAT; cmd->stats_id = WMI_REQUEST_VDEV_STAT;
wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send if (wmi_unified_cmd_send(wmi_handle, buf, len,
(wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { WMI_REQUEST_STATS_CMDID)) {
WMI_LOGE("Failed to send host stats request to fw"); WMI_LOGE("Failed to send host stats request to fw");
wmi_buf_free(buf); wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;