qcacmn: Unmap the htc connect buffer after connect failure
The htc connect message buffer is not unmapped, if the firmware does not send wmi ready event to the host. Scenario: - Host sends htc init command. - The command is queued into the src ring. - The firmware has crashed before the Copy Engine could copy the message to the destination ring - Due to the above point, no copy completion interrupt is received. - The host times out during its wait for the wmi ready event. - Hence the htc init command buffer stays unmapped and unfreed. As a part of the wma ready event missing cleanup, the htc connect buffer is not unmapped. Fix this to avoid missing to unmap the buffer. To avoid a side effect of sending a completion for HTC connect command, all the commands are freed in the htc completion handler in case of SSR. CRs-Fixed: 2512344 Change-Id: I05026b3cbb764197e6df85c41634002d271a50e5
This commit is contained in:

committad av
nshrivas

förälder
dc29b1f9d7
incheckning
4863352e53
@@ -2129,8 +2129,6 @@ hif_pci_ce_send_done(struct CE_handle *copyeng, void *ce_context,
|
||||
{
|
||||
struct HIF_CE_pipe_info *pipe_info =
|
||||
(struct HIF_CE_pipe_info *)ce_context;
|
||||
struct HIF_CE_state *hif_state = pipe_info->HIF_CE_state;
|
||||
struct hif_softc *scn = HIF_GET_SOFTC(hif_state);
|
||||
unsigned int sw_idx = sw_index, hw_idx = hw_index;
|
||||
struct hif_msg_callbacks *msg_callbacks =
|
||||
&pipe_info->pipe_callbacks;
|
||||
@@ -2140,19 +2138,11 @@ hif_pci_ce_send_done(struct CE_handle *copyeng, void *ce_context,
|
||||
* The upper layer callback will be triggered
|
||||
* when last fragment is complteted.
|
||||
*/
|
||||
if (transfer_context != CE_SENDLIST_ITEM_CTXT) {
|
||||
if (scn->target_status == TARGET_STATUS_RESET) {
|
||||
|
||||
qdf_nbuf_unmap_single(scn->qdf_dev,
|
||||
transfer_context,
|
||||
QDF_DMA_TO_DEVICE);
|
||||
qdf_nbuf_free(transfer_context);
|
||||
} else
|
||||
msg_callbacks->txCompletionHandler(
|
||||
msg_callbacks->Context,
|
||||
transfer_context, transfer_id,
|
||||
toeplitz_hash_result);
|
||||
}
|
||||
if (transfer_context != CE_SENDLIST_ITEM_CTXT)
|
||||
msg_callbacks->txCompletionHandler(
|
||||
msg_callbacks->Context,
|
||||
transfer_context, transfer_id,
|
||||
toeplitz_hash_result);
|
||||
|
||||
qdf_spin_lock_bh(&pipe_info->completion_freeq_lock);
|
||||
pipe_info->num_sends_allowed++;
|
||||
|
24
htc/htc.c
24
htc/htc.c
@@ -821,7 +821,7 @@ void htc_stop(HTC_HANDLE HTCHandle)
|
||||
{
|
||||
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
|
||||
int i;
|
||||
HTC_ENDPOINT *pEndpoint;
|
||||
HTC_ENDPOINT *endpoint;
|
||||
#ifdef RX_SG_SUPPORT
|
||||
qdf_nbuf_t netbuf;
|
||||
qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
|
||||
@@ -832,12 +832,12 @@ void htc_stop(HTC_HANDLE HTCHandle)
|
||||
HTC_INFO("%s: endpoints cleanup\n", __func__);
|
||||
/* cleanup endpoints */
|
||||
for (i = 0; i < ENDPOINT_MAX; i++) {
|
||||
pEndpoint = &target->endpoint[i];
|
||||
htc_flush_rx_hold_queue(target, pEndpoint);
|
||||
htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
|
||||
if (pEndpoint->ul_is_polled) {
|
||||
qdf_timer_stop(&pEndpoint->ul_poll_timer);
|
||||
qdf_timer_free(&pEndpoint->ul_poll_timer);
|
||||
endpoint = &target->endpoint[i];
|
||||
htc_flush_rx_hold_queue(target, endpoint);
|
||||
htc_flush_endpoint_tx(target, endpoint, HTC_TX_PACKET_TAG_ALL);
|
||||
if (endpoint->ul_is_polled) {
|
||||
qdf_timer_stop(&endpoint->ul_poll_timer);
|
||||
qdf_timer_free(&endpoint->ul_poll_timer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -863,12 +863,18 @@ void htc_stop(HTC_HANDLE HTCHandle)
|
||||
* In SSR case, HTC tx completion callback for wmi will be blocked
|
||||
* by TARGET_STATUS_RESET and HTC packets will be left unfreed on
|
||||
* lookup queue.
|
||||
*
|
||||
* In case of target failing to send wmi_ready_event, the htc connect
|
||||
* msg buffer will be left unmapped and not freed. So calling the
|
||||
* completion handler for this buffer will handle this scenario.
|
||||
*/
|
||||
HTC_INFO("%s: flush endpoints Tx lookup queue\n", __func__);
|
||||
for (i = 0; i < ENDPOINT_MAX; i++) {
|
||||
pEndpoint = &target->endpoint[i];
|
||||
if (pEndpoint->service_id == WMI_CONTROL_SVC)
|
||||
endpoint = &target->endpoint[i];
|
||||
if (endpoint->service_id == WMI_CONTROL_SVC)
|
||||
htc_flush_endpoint_txlookupQ(target, i, false);
|
||||
else if (endpoint->service_id == HTC_CTRL_RSVD_SVC)
|
||||
htc_flush_endpoint_txlookupQ(target, i, true);
|
||||
}
|
||||
HTC_INFO("%s: resetting endpoints state\n", __func__);
|
||||
|
||||
|
@@ -125,6 +125,15 @@ static void send_packet_completion(HTC_TARGET *target, HTC_PACKET *pPacket)
|
||||
|
||||
restore_tx_packet(target, pPacket);
|
||||
|
||||
/*
|
||||
* In case of SSR, we cannot call the upper layer completion
|
||||
* callbacks, hence just free the nbuf and HTC packet here.
|
||||
*/
|
||||
if (hif_get_target_status(target->hif_dev)) {
|
||||
htc_free_control_tx_packet(target, pPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
/* do completion */
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
|
||||
("HTC calling ep %d send complete callback on packet %pK\n",
|
||||
|
Referens i nytt ärende
Block a user