Pārlūkot izejas kodu

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
Rakesh Pillai 5 gadi atpakaļ
vecāks
revīzija
4863352e53
3 mainītis faili ar 29 papildinājumiem un 24 dzēšanām
  1. 5 15
      hif/src/ce/ce_main.c
  2. 15 9
      htc/htc.c
  3. 9 0
      htc/htc_send.c

+ 5 - 15
hif/src/ce/ce_main.c

@@ -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 *pipe_info =
 		(struct HIF_CE_pipe_info *)ce_context;
 		(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;
 	unsigned int sw_idx = sw_index, hw_idx = hw_index;
 	struct hif_msg_callbacks *msg_callbacks =
 	struct hif_msg_callbacks *msg_callbacks =
 		&pipe_info->pipe_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
 		 * The upper layer callback will be triggered
 		 * when last fragment is complteted.
 		 * 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);
 		qdf_spin_lock_bh(&pipe_info->completion_freeq_lock);
 		pipe_info->num_sends_allowed++;
 		pipe_info->num_sends_allowed++;

+ 15 - 9
htc/htc.c

@@ -821,7 +821,7 @@ void htc_stop(HTC_HANDLE HTCHandle)
 {
 {
 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
 	int i;
 	int i;
-	HTC_ENDPOINT *pEndpoint;
+	HTC_ENDPOINT *endpoint;
 #ifdef RX_SG_SUPPORT
 #ifdef RX_SG_SUPPORT
 	qdf_nbuf_t netbuf;
 	qdf_nbuf_t netbuf;
 	qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
 	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__);
 	HTC_INFO("%s: endpoints cleanup\n", __func__);
 	/* cleanup endpoints */
 	/* cleanup endpoints */
 	for (i = 0; i < ENDPOINT_MAX; i++) {
 	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
 	 * In SSR case, HTC tx completion callback for wmi will be blocked
 	 * by TARGET_STATUS_RESET and HTC packets will be left unfreed on
 	 * by TARGET_STATUS_RESET and HTC packets will be left unfreed on
 	 * lookup queue.
 	 * 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__);
 	HTC_INFO("%s: flush endpoints Tx lookup queue\n", __func__);
 	for (i = 0; i < ENDPOINT_MAX; i++) {
 	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);
 			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__);
 	HTC_INFO("%s: resetting endpoints state\n", __func__);
 
 

+ 9 - 0
htc/htc_send.c

@@ -125,6 +125,15 @@ static void send_packet_completion(HTC_TARGET *target, HTC_PACKET *pPacket)
 
 
 	restore_tx_packet(target, 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 */
 	/* do completion */
 	AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
 	AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
 			("HTC calling ep %d send complete callback on packet %pK\n",
 			("HTC calling ep %d send complete callback on packet %pK\n",