diff --git a/hif/src/sdio/hif_sdio_recv.c b/hif/src/sdio/hif_sdio_recv.c index 8c51cb72efbd..1638c61b4355 100644 --- a/hif/src/sdio/hif_sdio_recv.c +++ b/hif/src/sdio/hif_sdio_recv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,8 @@ #include "regtable_sdio.h" #include "if_sdio.h" +#define NBUF_ALLOC_FAIL_WAIT_TIME 100 + static void hif_dev_dump_registers(struct hif_sdio_device *pdev, struct MBOX_IRQ_PROC_REGISTERS *irq_proc_regs, struct MBOX_IRQ_ENABLE_REGISTERS * @@ -710,6 +713,12 @@ static QDF_STATUS hif_dev_issue_recv_packet_bundle(struct hif_sdio_device *pdev, bundleSpaceRemaining = HTC_MAX_MSG_PER_BUNDLE * target->TargetCreditSize; packet_rx_bundle = allocate_htc_bundle_packet(target); + if (!packet_rx_bundle) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: packet_rx_bundle is NULL\n", __func__)); + qdf_sleep(NBUF_ALLOC_FAIL_WAIT_TIME); /* 100 msec sleep */ + return QDF_STATUS_E_NOMEM; + } bundle_buffer = packet_rx_bundle->pBuffer; for (i = 0; @@ -864,8 +873,22 @@ QDF_STATUS hif_dev_recv_message_pending_handler(struct hif_sdio_device *pdev, mail_box_index, &pkts_fetched, partial_bundle); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_IS_STATUS_ERROR(status)) { + while (!HTC_QUEUE_EMPTY( + &recv_pkt_queue)) { + qdf_nbuf_t netbuf; + + packet = htc_packet_dequeue( + &recv_pkt_queue); + if (packet == NULL) + break; + netbuf = (qdf_nbuf_t) packet-> + pNetBufContext; + if (netbuf) + qdf_nbuf_free(netbuf); + } break; + } if (HTC_PACKET_QUEUE_DEPTH(&recv_pkt_queue) != 0) { diff --git a/htc/htc.c b/htc/htc.c index 1511e2ebbc9a..7a2d74a24d1d 100644 --- a/htc/htc.c +++ b/htc/htc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -31,6 +31,8 @@ #include /* qdf_nbuf_t */ #include /* qdf_print */ +#define MAX_HTC_RX_BUNDLE 2 + #if defined(WLAN_DEBUG) || defined(DEBUG) static ATH_DEBUG_MASK_DESCRIPTION g_htc_debug_description[] = { {ATH_DEBUG_SEND, "Send"}, @@ -499,9 +501,11 @@ A_STATUS htc_wait_target(HTC_HANDLE HTCHandle) HTC_SERVICE_CONNECT_RESP resp; HTC_READY_MSG *rdy_msg; uint16_t htc_rdy_msg_id; + uint8_t i = 0; + HTC_PACKET *rx_bundle_packet, *temp_bundle_packet; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, - ("htc_wait_target - Enter (target:0x%p) \n", HTCHandle)); + ("htc_wait_target - Enter (target:0x%p)\n", HTCHandle)); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n")); do { @@ -561,6 +565,24 @@ A_STATUS htc_wait_target(HTC_HANDLE HTCHandle) status = A_ECOMM; break; } + + /* Allocate expected number of RX bundle buffer allocation */ + if (HTC_RX_BUNDLE_ENABLED(target)) { + temp_bundle_packet = NULL; + for (i = 0; i < MAX_HTC_RX_BUNDLE; i++) { + rx_bundle_packet = + allocate_htc_bundle_packet(target); + if (rx_bundle_packet != NULL) + rx_bundle_packet->ListLink.pNext = + (DL_LIST *)temp_bundle_packet; + else + break; + + temp_bundle_packet = rx_bundle_packet; + } + target->pBundleFreeList = temp_bundle_packet; + } + /* done processing */ target->CtrlResponseProcessing = false;