qcacmn: Do RTPM put during cleanup when HTT ver resp is not received
For HTT h2t message which has a response from FW, runtime get is done in HTC layer and the corresponding runtime_put is done as part of the HTT response processing. In a scenario where the HTT response is not received from FW or not processed by host, runtime_put is not done as part of cleanup and panic is triggered due to get/put imbalance. Fix is to do RTPM put as part of htc cleanup when the HTT response from FW is not received or processed. Change-Id: I17ccb7c3e2293c95f5f233d36c6ef38a75733cce CRs-Fixed: 2779113
This commit is contained in:

committed by
snandini

parent
3213f64df6
commit
478749a365
@@ -793,7 +793,7 @@ static int htt_h2t_ver_req_msg(struct htt_soc *soc)
|
|||||||
SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
|
SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
|
||||||
dp_htt_h2t_send_complete_free_netbuf, qdf_nbuf_data(msg),
|
dp_htt_h2t_send_complete_free_netbuf, qdf_nbuf_data(msg),
|
||||||
qdf_nbuf_len(msg), soc->htc_endpoint,
|
qdf_nbuf_len(msg), soc->htc_endpoint,
|
||||||
1); /* tag - not relevant here */
|
HTC_TX_PACKET_TAG_RTPM_PUT_RC);
|
||||||
|
|
||||||
SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
|
SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
|
||||||
status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_VERSION_REQ,
|
status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_VERSION_REQ,
|
||||||
@@ -4562,7 +4562,15 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
|
|||||||
|
|
||||||
case HTT_T2H_MSG_TYPE_VERSION_CONF:
|
case HTT_T2H_MSG_TYPE_VERSION_CONF:
|
||||||
{
|
{
|
||||||
htc_pm_runtime_put(soc->htc_soc);
|
/*
|
||||||
|
* HTC maintains runtime pm count for H2T messages that
|
||||||
|
* have a response msg from FW. This count ensures that
|
||||||
|
* in the case FW does not sent out the response or host
|
||||||
|
* did not process this indication runtime_put happens
|
||||||
|
* properly in the cleanup path.
|
||||||
|
*/
|
||||||
|
if (htc_dec_return_runtime_cnt(soc->htc_soc) >= 0)
|
||||||
|
htc_pm_runtime_put(soc->htc_soc);
|
||||||
soc->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word);
|
soc->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word);
|
||||||
soc->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word);
|
soc->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word);
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
|
||||||
|
27
htc/htc.c
27
htc/htc.c
@@ -154,6 +154,9 @@ static void htc_cleanup(HTC_TARGET *target)
|
|||||||
HTC_PACKET_QUEUE *pkt_queue;
|
HTC_PACKET_QUEUE *pkt_queue;
|
||||||
qdf_nbuf_t netbuf;
|
qdf_nbuf_t netbuf;
|
||||||
|
|
||||||
|
while (htc_dec_return_runtime_cnt((void *)target) >= 0)
|
||||||
|
hif_pm_runtime_put(target->hif_dev, RTPM_ID_HTC);
|
||||||
|
|
||||||
if (target->hif_dev) {
|
if (target->hif_dev) {
|
||||||
hif_detach_htc(target->hif_dev);
|
hif_detach_htc(target->hif_dev);
|
||||||
hif_mask_interrupt_call(target->hif_dev);
|
hif_mask_interrupt_call(target->hif_dev);
|
||||||
@@ -271,9 +274,32 @@ static void htc_runtime_pm_deinit(HTC_TARGET *target)
|
|||||||
qdf_destroy_work(0, &target->queue_kicker);
|
qdf_destroy_work(0, &target->queue_kicker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc)
|
||||||
|
{
|
||||||
|
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc);
|
||||||
|
|
||||||
|
return qdf_atomic_dec_return(&target->htc_runtime_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* htc_init_runtime_cnt: Initialize htc runtime count
|
||||||
|
* @htc: HTC handle
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void htc_init_runtime_cnt(HTC_TARGET *target)
|
||||||
|
{
|
||||||
|
qdf_atomic_init(&target->htc_runtime_cnt);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static inline void htc_runtime_pm_init(HTC_TARGET *target) { }
|
static inline void htc_runtime_pm_init(HTC_TARGET *target) { }
|
||||||
static inline void htc_runtime_pm_deinit(HTC_TARGET *target) { }
|
static inline void htc_runtime_pm_deinit(HTC_TARGET *target) { }
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void htc_init_runtime_cnt(HTC_TARGET *target)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
|
#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
|
||||||
@@ -378,6 +404,7 @@ HTC_HANDLE htc_create(void *ol_sc, struct htc_init_info *pInfo,
|
|||||||
} while (false);
|
} while (false);
|
||||||
|
|
||||||
htc_recv_init(target);
|
htc_recv_init(target);
|
||||||
|
htc_init_runtime_cnt(target);
|
||||||
|
|
||||||
HTC_TRACE("-htc_create: (0x%pK)", target);
|
HTC_TRACE("-htc_create: (0x%pK)", target);
|
||||||
|
|
||||||
|
@@ -790,9 +790,23 @@ void htc_clear_bundle_stats(HTC_HANDLE HTCHandle);
|
|||||||
#ifdef FEATURE_RUNTIME_PM
|
#ifdef FEATURE_RUNTIME_PM
|
||||||
int htc_pm_runtime_get(HTC_HANDLE htc_handle);
|
int htc_pm_runtime_get(HTC_HANDLE htc_handle);
|
||||||
int htc_pm_runtime_put(HTC_HANDLE htc_handle);
|
int htc_pm_runtime_put(HTC_HANDLE htc_handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* htc_dec_return_runtime_cnt: Decrement htc runtime count
|
||||||
|
* @htc: HTC handle
|
||||||
|
*
|
||||||
|
* Return: value of runtime count after decrement
|
||||||
|
*/
|
||||||
|
int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc);
|
||||||
#else
|
#else
|
||||||
static inline int htc_pm_runtime_get(HTC_HANDLE htc_handle) { return 0; }
|
static inline int htc_pm_runtime_get(HTC_HANDLE htc_handle) { return 0; }
|
||||||
static inline int htc_pm_runtime_put(HTC_HANDLE htc_handle) { return 0; }
|
static inline int htc_pm_runtime_put(HTC_HANDLE htc_handle) { return 0; }
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -260,6 +260,10 @@ typedef struct _HTC_TARGET {
|
|||||||
/* flag to enable packet send debug */
|
/* flag to enable packet send debug */
|
||||||
bool htc_pkt_dbg;
|
bool htc_pkt_dbg;
|
||||||
|
|
||||||
|
#ifdef FEATURE_RUNTIME_PM
|
||||||
|
/* Runtime count for H2T msg with response */
|
||||||
|
qdf_atomic_t htc_runtime_cnt;
|
||||||
|
#endif
|
||||||
} HTC_TARGET;
|
} HTC_TARGET;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2014, 2016-2017, 2019 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2013-2014, 2016-2017, 2019-2020 The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -76,6 +76,8 @@ struct htc_tx_packet_info {
|
|||||||
/* Tag packet for runtime put after sending */
|
/* Tag packet for runtime put after sending */
|
||||||
#define HTC_TX_PACKET_TAG_RUNTIME_PUT (HTC_TX_PACKET_TAG_USER_DEFINED + 3)
|
#define HTC_TX_PACKET_TAG_RUNTIME_PUT (HTC_TX_PACKET_TAG_USER_DEFINED + 3)
|
||||||
|
|
||||||
|
/*Tag packet for runtime put in response or cleanup */
|
||||||
|
#define HTC_TX_PACKET_TAG_RTPM_PUT_RC (HTC_TX_PACKET_TAG_USER_DEFINED + 4)
|
||||||
|
|
||||||
#define HTC_TX_PACKET_FLAG_FIXUP_NETBUF (1 << 0)
|
#define HTC_TX_PACKET_FLAG_FIXUP_NETBUF (1 << 0)
|
||||||
#define HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA (1 << 1)
|
#define HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA (1 << 1)
|
||||||
|
@@ -176,10 +176,27 @@ static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket)
|
|||||||
qdf_nbuf_push_head(netbuf, sizeof(HTC_FRAME_HDR));
|
qdf_nbuf_push_head(netbuf, sizeof(HTC_FRAME_HDR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* htc_inc_runtime_cnt: Increment htc runtime count
|
||||||
|
* @target: handle of HTC context
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void htc_inc_runtime_cnt(HTC_TARGET *target)
|
||||||
|
{
|
||||||
|
qdf_atomic_inc(&target->htc_runtime_cnt);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket)
|
static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void htc_inc_runtime_cnt(HTC_TARGET *target)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void htc_send_complete_check_cleanup(void *context)
|
void htc_send_complete_check_cleanup(void *context)
|
||||||
@@ -716,6 +733,7 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target,
|
|||||||
uint8_t *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
int (*update_ep_padding_credit)(void *, int);
|
int (*update_ep_padding_credit)(void *, int);
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
|
bool rt_put_in_resp;
|
||||||
|
|
||||||
update_ep_padding_credit =
|
update_ep_padding_credit =
|
||||||
pEndpoint->EpCallBacks.ep_padding_credit_update;
|
pEndpoint->EpCallBacks.ep_padding_credit_update;
|
||||||
@@ -726,6 +744,7 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target,
|
|||||||
("+htc_issue_packets: Queue: %pK, Pkts %d\n", pPktQueue,
|
("+htc_issue_packets: Queue: %pK, Pkts %d\n", pPktQueue,
|
||||||
HTC_PACKET_QUEUE_DEPTH(pPktQueue)));
|
HTC_PACKET_QUEUE_DEPTH(pPktQueue)));
|
||||||
while (true) {
|
while (true) {
|
||||||
|
rt_put_in_resp = false;
|
||||||
if (HTC_TX_BUNDLE_ENABLED(target) &&
|
if (HTC_TX_BUNDLE_ENABLED(target) &&
|
||||||
HTC_PACKET_QUEUE_DEPTH(pPktQueue) >=
|
HTC_PACKET_QUEUE_DEPTH(pPktQueue) >=
|
||||||
HTC_MIN_MSG_PER_BUNDLE) {
|
HTC_MIN_MSG_PER_BUNDLE) {
|
||||||
@@ -837,6 +856,10 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target,
|
|||||||
*/
|
*/
|
||||||
if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_RUNTIME_PUT)
|
if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_RUNTIME_PUT)
|
||||||
rt_put = true;
|
rt_put = true;
|
||||||
|
else if (pPacket->PktInfo.AsTx.Tag ==
|
||||||
|
HTC_TX_PACKET_TAG_RTPM_PUT_RC)
|
||||||
|
rt_put_in_resp = true;
|
||||||
|
|
||||||
#if DEBUG_BUNDLE
|
#if DEBUG_BUNDLE
|
||||||
qdf_print(" Send single EP%d buffer size:0x%x, total:0x%x.",
|
qdf_print(" Send single EP%d buffer size:0x%x, total:0x%x.",
|
||||||
pEndpoint->Id,
|
pEndpoint->Id,
|
||||||
@@ -922,6 +945,9 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target,
|
|||||||
RTPM_ID_HTC);
|
RTPM_ID_HTC);
|
||||||
rt_put = false;
|
rt_put = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rt_put_in_resp)
|
||||||
|
htc_inc_runtime_cnt(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) {
|
if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) {
|
||||||
|
Reference in New Issue
Block a user