qcacld-2.0: SDIO: Throughput Enhancement
Tx improvement achieved by increasing Tx buffers in FW, enable Tx bundling
feature in host.
Rx improvement achieved by introducing Rx completion task/thread which helps
in reducing DSR Handler workload.
Used FW feature which bundles variable size rx packets which helps in
increasing TCP chariot numbers for multiple streams, under define
HIF_BUNDLE_DIFF_BLK_FRAMES
Change-Id: I63118395bf148f53a25304c7fd90e126c1f29270
CRs-Fixed: 2170127
diff --git a/CORE/SERVICES/COMMON/htc.h b/CORE/SERVICES/COMMON/htc.h
index e61555e..bcc980d 100644
--- a/CORE/SERVICES/COMMON/htc.h
+++ b/CORE/SERVICES/COMMON/htc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -82,6 +82,9 @@
*
*/
+#define HIF_RX_THREAD
+#define HIF_BUNDLE_DIFF_BLK_FRAMES 0
+
/* HTC frame header */
typedef PREPACK struct _HTC_FRAME_HDR{
/* do not remove or re-arrange these fields, these are minimally required
@@ -94,7 +97,11 @@
A_UINT32 ControlBytes0 : 8, /* used for CRC check if CRC_CHECK flag set */
ControlBytes1 : 8, /* used for seq check if SEQ_CHECK flag set */
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ TotalLen : 16;
+#else
reserved : 16; /* used by bundle processing in SDIO systems */
+#endif
/* message payload starts after the header */
@@ -417,6 +424,12 @@
LookAhead1 : 8,
LookAhead2 : 8,
LookAhead3 : 8;
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ A_UINT32 LookAhead4 : 8, /* 4 byte lookahead */
+ LookAhead5 : 8,
+ LookAhead6 : 8,
+ LookAhead7 : 8;
+#endif
A_UINT32 PostValid : 8, /* post valid guard */
reserved1 : 24;
diff --git a/CORE/SERVICES/COMMON/htc_packet.h b/CORE/SERVICES/COMMON/htc_packet.h
index ce4532f..1be4fb8 100644
--- a/CORE/SERVICES/COMMON/htc_packet.h
+++ b/CORE/SERVICES/COMMON/htc_packet.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -115,6 +115,7 @@
can pass the network buffer corresponding to the HTC packet
lower layers may optimized the transfer knowing this is
a network buffer */
+ A_UINT8 BundlePktnum;
} HTC_PACKET;
diff --git a/CORE/SERVICES/HIF/sdio/hif_sdio_dev.c b/CORE/SERVICES/HIF/sdio/hif_sdio_dev.c
index 5d9b3b9..fcbad8d 100644
--- a/CORE/SERVICES/HIF/sdio/hif_sdio_dev.c
+++ b/CORE/SERVICES/HIF/sdio/hif_sdio_dev.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014,2016-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -26,6 +26,7 @@
*/
#define ATH_MODULE_NAME hif
+#include <linux/kthread.h>
#include "a_debug.h"
#include <adf_os_types.h>
@@ -48,9 +49,11 @@
#include <a_osapi.h>
#include <hif.h>
#include <htc_services.h>
+#include <htc_internal.h>
#include "hif_sdio_internal.h"
#include "if_ath_sdio.h"
#include "regtable.h"
+#include "vos_sched.h"
/* under HL SDIO, with Interface Memory support, we have the following
* reasons to support 2 mboxs: a) we need place different buffers in different
@@ -162,11 +165,91 @@
return pPacket;
}
+#ifdef HIF_RX_THREAD
+/**
+ * rx_completion_sem_init() - initialize rx completion semaphore
+ * @device: device handle.
+ *
+ * Initialize semaphore for RX completion thread's synchronization.
+ *
+ * Return: None.
+ */
+static inline void rx_completion_sem_init(HIF_SDIO_DEVICE *pDev)
+{
+ spin_lock_init(&pDev->pRecvTask->rx_bundle_lock);
+ spin_lock_init(&pDev->pRecvTask->rx_sync_completion_lock);
+ sema_init(&pDev->pRecvTask->sem_rx_completion, 0);
+}
+extern int rx_completion_task(void *param);
+
+/**
+ * hif_start_tx_completion_thread() - Create and start the RX compl thread
+ * @pDev: pDev handle.
+ *
+ * This function will create the rx completion thread.
+ *
+ * Return: A_OK thread created.
+ * A_ERROR thread not created.
+ */
+static inline int hif_start_rx_completion_thread(HIF_SDIO_DEVICE *pDev)
+{
+#ifdef CONFIG_PERF_NON_QC_PLATFORM
+ struct sched_param param = {.sched_priority = 99};
+#endif
+ if (!pDev->pRecvTask->rx_completion_task) {
+ pDev->pRecvTask->rx_completion_shutdown = 0;
+ pDev->pRecvTask->rx_completion_task = kthread_create(rx_completion_task,
+ (void *)pDev, "AR6K RxCompletion");
+#ifdef CONFIG_PERF_NON_QC_PLATFORM
+ sched_setscheduler(pDev->pRecvTask->rx_completion_task, SCHED_FIFO, ¶m);
+#endif
+ if (IS_ERR(pDev->pRecvTask->rx_completion_task)) {
+ pDev->pRecvTask->rx_completion_shutdown = 1;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: fail to create rx_comple task\n"));
+ pDev->pRecvTask->rx_completion_task = NULL;
+ return A_ERROR;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6000: start rx_comple task\n"));
+ wake_up_process(pDev->pRecvTask->rx_completion_task);
+ }
+ return A_OK;
+}
+
+/*
+ * hif_stop_rx_completion_thread() - Destroy the rx compl thread
+ * @pDev: pDev handle.
+ *
+ * This function will destroy the RX completion thread.
+ *
+ * Return: None.
+ */
+static inline void hif_stop_rx_completion_thread(HIF_SDIO_DEVICE *pDev)
+{
+ HTC_PACKET *pPacket;
+ if (pDev->pRecvTask->rx_completion_task) {
+ init_completion(&pDev->pRecvTask->rx_completion_exit);
+ pDev->pRecvTask->rx_completion_shutdown = 1;
+ up(&pDev->pRecvTask->sem_rx_completion);
+ wait_for_completion(&pDev->pRecvTask->rx_completion_exit);
+ pDev->pRecvTask->rx_completion_task = NULL;
+ sema_init(&pDev->pRecvTask->sem_rx_completion, 0);
+ }
+ while(!HTC_QUEUE_EMPTY(&pDev->pRecvTask->rxAllocQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(&pDev->pRecvTask->rxAllocQueue);
+ if(pPacket == NULL)
+ break;
+ adf_nbuf_free(pPacket->pNetBufContext);
+ }
+}
+struct hif_recv_task gRecvTask;
+#endif
+
HIF_SDIO_DEVICE* HIFDevCreate(HIF_DEVICE *hif_device,
MSG_BASED_HIF_CALLBACKS *callbacks,
void *target)
{
-
A_STATUS status;
HIF_SDIO_DEVICE *pDev;
@@ -183,6 +266,17 @@
pDev->HIFDevice = hif_device;
pDev->pTarget = target;
+#ifdef HIF_RX_THREAD
+ pDev->pRecvTask = &gRecvTask;
+ pDev->pRecvTask->rx_completion_task = NULL;
+ rx_completion_sem_init(pDev);
+ INIT_HTC_PACKET_QUEUE(&pDev->pRecvTask->rxBundleQueue);
+ INIT_HTC_PACKET_QUEUE(&pDev->pRecvTask->rxSyncCompletionQueue);
+ hif_start_rx_completion_thread(pDev);
+ spin_lock_init(&pDev->pRecvTask->rx_alloc_lock);
+ INIT_HTC_PACKET_QUEUE(&pDev->pRecvTask->rxAllocQueue);
+#endif
+
status = HIFConfigureDevice(hif_device,
HIF_DEVICE_SET_HTC_CONTEXT,
(void*) pDev,
@@ -200,7 +294,9 @@
void HIFDevDestroy(HIF_SDIO_DEVICE *pDev)
{
A_STATUS status;
-
+#ifdef HIF_RX_THREAD
+ hif_stop_rx_completion_thread(pDev);
+#endif
status = HIFConfigureDevice(pDev->HIFDevice,
HIF_DEVICE_SET_HTC_CONTEXT,
(void*) NULL,
diff --git a/CORE/SERVICES/HIF/sdio/hif_sdio_internal.h b/CORE/SERVICES/HIF/sdio/hif_sdio_internal.h
index fd200d5..3576db6 100644
--- a/CORE/SERVICES/HIF/sdio/hif_sdio_internal.h
+++ b/CORE/SERVICES/HIF/sdio/hif_sdio_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014,2016-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -55,7 +55,7 @@
#define INVALID_MAILBOX_NUMBER 0xFF
#define MAILBOX_COUNT 4
#define MAILBOX_FOR_BLOCK_SIZE 1
-#define MAILBOX_USED_COUNT 2
+#define MAILBOX_USED_COUNT 1
#if defined(SDIO_3_0)
#define MAILBOX_LOOKAHEAD_SIZE_IN_WORD 2
#else
@@ -111,9 +111,27 @@
int CurrentDSRRecvCount;
int RecheckIRQStatusCnt;
A_UINT32 RecvStateFlags;
- void *pTarget;
+ void *pTarget;
+#ifdef HIF_RX_THREAD
+ struct hif_recv_task* pRecvTask;
+#endif
};
+#ifdef HIF_RX_THREAD
+struct hif_recv_task {
+ struct task_struct *rx_completion_task;
+ struct semaphore sem_rx_completion;
+ int rx_completion_shutdown;
+ struct completion rx_completion_exit;
+ spinlock_t rx_bundle_lock;
+ spinlock_t rx_sync_completion_lock;
+ HTC_PACKET_QUEUE rxBundleQueue;
+ HTC_PACKET_QUEUE rxSyncCompletionQueue;
+ spinlock_t rx_alloc_lock;
+ HTC_PACKET_QUEUE rxAllocQueue;
+};
+#endif
+
#define LOCK_HIF_DEV(device) A_MUTEX_LOCK(&(device)->Lock);
#define UNLOCK_HIF_DEV(device) A_MUTEX_UNLOCK(&(device)->Lock);
#define LOCK_HIF_DEV_RX(t) A_MUTEX_LOCK(&(t)->RxLock);
diff --git a/CORE/SERVICES/HIF/sdio/hif_sdio_recv.c b/CORE/SERVICES/HIF/sdio/hif_sdio_recv.c
index 36682b0..9097859 100644
--- a/CORE/SERVICES/HIF/sdio/hif_sdio_recv.c
+++ b/CORE/SERVICES/HIF/sdio/hif_sdio_recv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014,2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014,2016-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -125,7 +125,11 @@
int numMessages;
int fullLength;
A_BOOL noRecycle;
-
+#ifdef HIF_RX_THREAD
+ unsigned long flags;
+ HTC_TARGET *target = NULL;
+ target = (HTC_TARGET *)pDev->pTarget;
+#endif
/* lock RX while we assemble the packet buffers */
LOCK_HIF_DEV_RX(pDev);
@@ -164,8 +168,14 @@
("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages));
}
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ if(numMessages > 1)
+ fullLength = target->TargetCreditSize;
+ else
+ fullLength = DEV_CALC_RECV_PADDED_LEN(pDev,pHdr->PayloadLen + sizeof(HTC_FRAME_HDR));
+#else
fullLength = DEV_CALC_RECV_PADDED_LEN(pDev,pHdr->PayloadLen + sizeof(HTC_FRAME_HDR));
-
+#endif
/*
all but the last packet have a length of payloadLen + sizeof(HTC_FRAME_HDR)
The last packet in the bundle has an additional 16 byte lookahead information.
@@ -174,6 +184,9 @@
/* get packet buffers for each message, if there was a bundle detected in the header,
* use pHdr as a template to fetch all packets in the bundle */
+#ifdef HIF_RX_THREAD
+ spin_lock_irqsave(&pDev->pRecvTask->rx_alloc_lock, flags);
+#endif
for (j = 0; j < numMessages; j++) {
/* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup,
@@ -181,11 +194,18 @@
noRecycle = FALSE;
/*allocate memory for the last packet*/
- if ((j == (numMessages-1)) && ((pHdr->Flags) & HTC_FLAGS_RECV_1MORE_BLOCK))
+ if ((j == (numMessages-1)) && ((pHdr->Flags) & HTC_FLAGS_RECV_1MORE_BLOCK)) {
fullLength += HIF_MBOX_BLOCK_SIZE;
+ }
+#ifdef HIF_RX_THREAD
+ pPacket = HTC_PACKET_DEQUEUE(&pDev->pRecvTask->rxAllocQueue);
+ if(pPacket == NULL) {
+ pPacket = HIFDevAllocRxBuffer(pDev, fullLength);
+ }
+#else
pPacket = HIFDevAllocRxBuffer(pDev, fullLength);
-
+#endif
if (pPacket == NULL) {
/* this is not an error, we simply need to mark that we are waiting for buffers.*/
@@ -194,7 +214,9 @@
status = A_NO_RESOURCE;
break;
}
-
+#ifdef HIF_RX_THREAD
+ pPacket->BundlePktnum = 0;
+#endif
//AR_DEBUG_ASSERT(pPacket->Endpoint == pEndpoint->Id);
/* clear flags */
pPacket->PktInfo.AsRx.HTCRxFlags = 0;
@@ -235,13 +257,24 @@
pPacket->PktInfo.AsRx.ExpectedHdr = LookAheads[i]; /* set expected look ahead */
}
/* set the amount of data to fetch */
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ if(numMessages > 1)
+ pPacket->ActualLength = target->TargetCreditSize;
+ else
+ pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
+#else
pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
- if ((j == (numMessages-1)) && ((pHdr->Flags) & HTC_FLAGS_RECV_1MORE_BLOCK))
+#endif
+ if ((j == (numMessages-1)) && ((pHdr->Flags) & HTC_FLAGS_RECV_1MORE_BLOCK)) {
pPacket->PktInfo.AsRx.HTCRxFlags |=
HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK;
+ }
pPacket->Endpoint = pHdr->EndpointID;
pPacket->Completion = NULL;
}
+#ifdef HIF_RX_THREAD
+ spin_unlock_irqrestore(&pDev->pRecvTask->rx_alloc_lock, flags);
+#endif
if (A_FAILED(status)) {
if (A_NO_RESOURCE == status) {
@@ -270,6 +303,121 @@
return status;
}
+#ifdef HIF_RX_THREAD
+static INLINE void HIFDevPreprocessTrailer(HIF_SDIO_DEVICE *pDev, HTC_PACKET* pPacket, A_UINT32 LookAheads[], int *pNumLookAheads
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , A_UINT32 lookAhead_part2[])
+#else
+ )
+#endif
+{
+ A_UINT8 *pRecordBuf;
+ HTC_RECORD_HDR *pRecord;
+ HTC_LOOKAHEAD_REPORT *pLookAhead;
+ A_UINT8 *pBuffer, *pLastPktBuffer, *pCur;
+ A_UINT8 lastPktFlag;
+ A_UINT16 lastPktPayloadLength;
+ A_UINT8 lastPktRecordID;
+ int numMessages;
+ A_UINT8 temp;
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ A_UINT32 i;
+#endif
+ A_UINT16 curPayloadLen = 0;
+ A_UINT32 paddedLength, lastPktOffset = 0;
+
+ pBuffer = pPacket->pBuffer;
+ pLastPktBuffer = pBuffer;
+ pCur = pBuffer;
+ numMessages = GET_RECV_BUNDLE_COUNT(pBuffer[1]);
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ for(i = 0; i < numMessages; i++) {
+ curPayloadLen = *((A_UINT16*)(&pCur[2]));
+ paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, curPayloadLen + HTC_HDR_LENGTH);
+ lastPktOffset += paddedLength;
+ pCur += paddedLength;
+ }
+#else
+ curPayloadLen = *((A_UINT16*)(pBuffer + 2));
+ paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, curPayloadLen + HTC_HDR_LENGTH);
+ lastPktOffset = numMessages * paddedLength;
+#endif
+ pLastPktBuffer = pBuffer + lastPktOffset;
+ lastPktFlag = pLastPktBuffer[1];
+ lastPktPayloadLength = ((A_UINT16)(*(A_UINT16*)(pLastPktBuffer + 2)));
+
+ if(lastPktFlag & HTC_FLAGS_RECV_TRAILER) {
+ temp = HTC_GET_FIELD(pLastPktBuffer, HTC_FRAME_HDR, CONTROLBYTES0);
+ if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > lastPktPayloadLength)) {
+ AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
+ ("%s: invalid header (payloadlength should be :%d, CB[0] is:%d) \n", __func__, lastPktPayloadLength, temp));
+ return;
+ }
+ lastPktRecordID = *(A_UINT8*)(pLastPktBuffer + lastPktPayloadLength + 8 - temp);
+ pRecord = (HTC_RECORD_HDR *)(pLastPktBuffer + lastPktPayloadLength + 8 - temp);
+ pRecordBuf = (A_UINT8*)(pLastPktBuffer + lastPktPayloadLength - temp + 12);
+ if(lastPktRecordID == HTC_RECORD_LOOKAHEAD) {
+ pLookAhead = (HTC_LOOKAHEAD_REPORT *) pRecordBuf;
+ if (pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) {
+ ((A_UINT8 *) (&LookAheads[0]))[0] = pLookAhead->LookAhead0;
+ ((A_UINT8 *) (&LookAheads[0]))[1] = pLookAhead->LookAhead1;
+ ((A_UINT8 *) (&LookAheads[0]))[2] = pLookAhead->LookAhead2;
+ ((A_UINT8 *) (&LookAheads[0]))[3] = pLookAhead->LookAhead3;
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ ((A_UINT8 *) (&lookAhead_part2[0]))[0] = pLookAhead->LookAhead4;
+ ((A_UINT8 *) (&lookAhead_part2[0]))[1] = pLookAhead->LookAhead5;
+ ((A_UINT8 *) (&lookAhead_part2[0]))[2] = pLookAhead->LookAhead6;
+ ((A_UINT8 *) (&lookAhead_part2[0]))[3] = pLookAhead->LookAhead7;
+#endif
+ if (pNumLookAheads != NULL) {
+ *pNumLookAheads = 1;
+ }
+ return;
+ }
+ }
+ else if (lastPktRecordID == HTC_RECORD_LOOKAHEAD_BUNDLE) {
+ if(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)) {
+ HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt;
+ int i;
+
+ pBundledLookAheadRpt =
+ (HTC_BUNDLED_LOOKAHEAD_REPORT *) pRecordBuf;
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
+ DebugDumpBytes(pRecordBuf,
+ pRecord->Length,
+ "Bundle LookAhead");
+ }
+
+ if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)))
+ > HTC_MAX_MSG_PER_BUNDLE_RX) {
+ /* this should never happen, the target restricts the number
+ * of messages per bundle configured by the host */
+ A_ASSERT(FALSE);
+ return ;
+ }
+ for (i = 0; i< (int) (pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) {
+ ((A_UINT8 *) (&LookAheads[i]))[0] =
+ pBundledLookAheadRpt->LookAhead0;
+ ((A_UINT8 *) (&LookAheads[i]))[1] =
+ pBundledLookAheadRpt->LookAhead1;
+ ((A_UINT8 *) (&LookAheads[i]))[2] =
+ pBundledLookAheadRpt->LookAhead2;
+ ((A_UINT8 *) (&LookAheads[i]))[3] =
+ pBundledLookAheadRpt->LookAhead3;
+ pBundledLookAheadRpt++;
+ }
+
+ if (pNumLookAheads != NULL) {
+ *pNumLookAheads = i;
+ }
+
+ }
+ }
+ }
+}
+#endif
+
static INLINE A_STATUS HIFDevRecvPacket(HIF_SDIO_DEVICE *pDev,
HTC_PACKET *pPacket,
A_UINT32 RecvLength,
@@ -343,7 +491,12 @@
static INLINE A_STATUS HIFDevProcessTrailer(HIF_SDIO_DEVICE *pDev,
A_UINT8 *pBuffer, int Length, A_UINT32 *pNextLookAheads,
- int *pNumLookAheads, HTC_ENDPOINT_ID FromEndpoint)
+ int *pNumLookAheads, HTC_ENDPOINT_ID FromEndpoint
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , A_UINT32 lookAhead_part2[])
+#else
+ )
+#endif
{
HTC_RECORD_HDR *pRecord;
A_UINT8 *pRecordBuf;
@@ -406,6 +559,13 @@
((A_UINT8 *) (&pNextLookAheads[0]))[2] = pLookAhead->LookAhead2;
((A_UINT8 *) (&pNextLookAheads[0]))[3] = pLookAhead->LookAhead3;
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ ((A_UINT8 *) (&lookAhead_part2[0]))[0] = pLookAhead->LookAhead4;
+ ((A_UINT8 *) (&lookAhead_part2[0]))[1] = pLookAhead->LookAhead5;
+ ((A_UINT8 *) (&lookAhead_part2[0]))[2] = pLookAhead->LookAhead6;
+ ((A_UINT8 *) (&lookAhead_part2[0]))[3] = pLookAhead->LookAhead7;
+#endif
+
if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
DebugDumpBytes((A_UINT8 *) pNextLookAheads,
4,
@@ -482,11 +642,15 @@
}
-
/* process a received message (i.e. strip off header, process any trailer data)
* note : locks must be released when this function is called */
static A_STATUS HIFDevProcessRecvHeader(HIF_SDIO_DEVICE *pDev,
- HTC_PACKET *pPacket, A_UINT32 *pNextLookAheads, int *pNumLookAheads)
+ HTC_PACKET *pPacket, A_UINT32 *pNextLookAheads, int *pNumLookAheads, bool processTrailer
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , A_UINT32 lookAhead_part2[])
+#else
+ )
+#endif
{
A_UINT8 temp;
A_UINT8 *pBuf;
@@ -548,9 +712,9 @@
/* somehow the lookahead that gave us the full read length did not
* reflect the actual header in the pending message */
AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
- ("HIFDevProcessRecvHeader, lookahead mismatch! (pPkt:0x%lX flags:0x%X), 0x%08X != 0x%08X\n",
- (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags,
- lookAhead, pPacket->PktInfo.AsRx.ExpectedHdr));
+ ("HIFDevProcessRecvHeader, lookahead mismatch! (pPkt:%p flags:0x%X), 0x%08X != 0x%08X len %d\n",
+ pPacket, pPacket->PktInfo.AsRx.HTCRxFlags,
+ lookAhead, pPacket->PktInfo.AsRx.ExpectedHdr, payloadLen));
#ifdef ATH_DEBUG_MODULE
DebugDumpBytes((A_UINT8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead");
DebugDumpBytes(pBuf,sizeof(HTC_FRAME_HDR),"Current Frame Header");
@@ -567,42 +731,53 @@
break;
}
- /* get flags */
- temp = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, FLAGS);
+#ifdef HIF_RX_THREAD
+ if(processTrailer == TRUE) {
+#endif
+ /* get flags */
+ temp = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, FLAGS);
- if (temp & HTC_FLAGS_RECV_TRAILER) {
- /* this packet has a trailer */
+ if (temp & HTC_FLAGS_RECV_TRAILER) {
+ /* this packet has a trailer */
- /* extract the trailer length in control byte 0 */
- temp = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, CONTROLBYTES0);
+ /* extract the trailer length in control byte 0 */
+ temp = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, CONTROLBYTES0);
- if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) {
- AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
- ("HIFDevProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n", payloadLen, temp));
- status = A_EPROTO;
- break;
+ if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) {
+ AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
+ ("HIFDevProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n", payloadLen, temp));
+ status = A_EPROTO;
+ break;
+ }
+
+ if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
+ /* this packet was fetched as part of an HTC bundle, the embedded lookahead is
+ * not valid since the next packet may have already been fetched as part of the
+ * bundle */
+ pNextLookAheads = NULL;
+ pNumLookAheads = NULL;
+ }
+
+ /* process trailer data that follows HDR + application payload */
+ status = HIFDevProcessTrailer(pDev,
+ (pBuf + HTC_HDR_LENGTH + payloadLen - temp),
+ temp,
+ pNextLookAheads,
+ pNumLookAheads,
+ pPacket->Endpoint
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , lookAhead_part2);
+#else
+ );
+#endif
+
+ if (A_FAILED(status)) {
+ break;
+ }
}
-
- if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
- /* this packet was fetched as part of an HTC bundle, the embedded lookahead is
- * not valid since the next packet may have already been fetched as part of the
- * bundle */
- pNextLookAheads = NULL;
- pNumLookAheads = NULL;
- }
-
- /* process trailer data that follows HDR + application payload */
- status = HIFDevProcessTrailer(pDev,
- (pBuf + HTC_HDR_LENGTH + payloadLen - temp),
- temp,
- pNextLookAheads,
- pNumLookAheads,
- pPacket->Endpoint);
-
- if (A_FAILED(status)) {
- break;
- }
+#ifdef HIF_RX_THREAD
}
+#endif
}while (FALSE);
if (A_FAILED(status)) {
@@ -621,19 +796,242 @@
return status;
}
+#ifdef HIF_RX_THREAD
+static A_STATUS processHdrAndRxComp(HIF_SDIO_DEVICE *device, HTC_PACKET *pPacket, bool processTrailer)
+{
+ A_UINT8 pipeid;
+ adf_nbuf_t netbuf;
+ int NumLookAheads;
+ A_UINT32 lookAheads[HTC_MAX_MSG_PER_BUNDLE_RX];
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ A_UINT32 lookAhead_part2[HTC_MAX_MSG_PER_BUNDLE_RX];
+#endif
+ A_STATUS status = A_OK;
+
+ NumLookAheads = 0;
+ status = HIFDevProcessRecvHeader(device, pPacket, lookAheads, &NumLookAheads, processTrailer
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , lookAhead_part2);
+#else
+ );
+#endif
+ if (A_FAILED(status)) {
+ return status;
+ }
+
+ netbuf = (adf_nbuf_t) pPacket->pNetBufContext;
+ /* set data length */
+ adf_nbuf_put_tail(netbuf, pPacket->ActualLength);
+
+ if (device->hif_callbacks.rxCompletionHandler) {
+ pipeid = HIFDevMapMailBoxToPipe(device, 0, TRUE);
+ device->hif_callbacks.rxCompletionHandler(device->hif_callbacks.Context,
+ netbuf,
+ pipeid);
+ }
+ return status;
+}
+
+int rx_completion_task(void *param)
+{
+ HIF_SDIO_DEVICE *device;
+ HTC_PACKET *pPacket = NULL;
+ unsigned long flags;
+ HTC_PACKET *pPacketRxBundle;
+ A_UINT32 paddedLength;
+ unsigned char *pBundleBuffer = NULL;
+ unsigned char *pBuffer;
+ HTC_TARGET *target = NULL;
+ A_UINT8 syncQDepth = 0;
+ A_UINT8 nextIsSingle = 0;
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ A_UINT16 curPayloadLen = 0;
+#endif
+ A_STATUS status = A_OK;
+
+ device = (HIF_SDIO_DEVICE *)param;
+ target = (HTC_TARGET *)device->pTarget;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: rx completion task\n"));
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ vos_set_cpus_allowed_ptr(current, 1);
+
+ while (!device->pRecvTask->rx_completion_shutdown) {
+ if (down_interruptible(&device->pRecvTask->sem_rx_completion) != 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("%s: rx completion task interrupted\n",
+ __func__));
+ break;
+ }
+
+ if (device->pRecvTask->rx_completion_shutdown) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("%s: rx completion task stopping\n",
+ __func__));
+ break;
+ }
+
+ //process single packet
+ spin_lock_irqsave(&device->pRecvTask->rx_bundle_lock, flags);
+ if(HTC_QUEUE_EMPTY(&device->pRecvTask->rxBundleQueue)) {
+ spin_lock_irqsave(&device->pRecvTask->rx_sync_completion_lock, flags);
+ while(!HTC_QUEUE_EMPTY(&device->pRecvTask->rxSyncCompletionQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxSyncCompletionQueue);
+ if(pPacket == NULL) {
+ break;
+ }
+ status = processHdrAndRxComp(device, pPacket, FALSE);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&device->pRecvTask->rx_sync_completion_lock, flags);
+ }
+ else {
+ //1. Dequeue from bundle buffer queue, scatter data to sync completion queue
+ while(!HTC_QUEUE_EMPTY(&device->pRecvTask->rxBundleQueue)) {
+ pPacketRxBundle = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxBundleQueue);
+ if(pPacketRxBundle == NULL) {
+ break;
+ }
+ if(pPacketRxBundle->BundlePktnum < 1) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Packets in bundle buffer is < 1"));
+ break;
+ }
+ spin_lock_irqsave(&device->pRecvTask->rx_sync_completion_lock, flags);
+ if(HTC_PACKET_QUEUE_DEPTH(&device->pRecvTask->rxSyncCompletionQueue) < pPacketRxBundle->BundlePktnum) {
+ // corner case: the sync queue depth is not enough for processing this bundle pkt, push it back
+ HTC_PACKET_ENQUEUE_TO_HEAD(&device->pRecvTask->rxBundleQueue, pPacketRxBundle);
+ spin_unlock_irqrestore(&device->pRecvTask->rx_sync_completion_lock, flags);
+ break;
+ }
+ spin_unlock_irqrestore(&device->pRecvTask->rx_sync_completion_lock, flags);
+ pBundleBuffer = pPacketRxBundle->pBuffer;
+ pBuffer = pBundleBuffer;
+ if(pPacketRxBundle == NULL)
+ break;
+
+ spin_lock_irqsave(&device->pRecvTask->rx_sync_completion_lock, flags);
+ //if the next pkt is single, dequeue it and process it, until the bundle pkts
+ while(TRUE) {
+ nextIsSingle = 0;
+ pPacket = HTC_GET_PKT_AT_HEAD(&device->pRecvTask->rxSyncCompletionQueue);
+ if(pPacket == NULL)
+ break;
+ if(pPacket->BundlePktnum == 1) {
+ nextIsSingle = 1;
+ }
+ if(nextIsSingle == 1) {
+ pPacket = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxSyncCompletionQueue);
+ if(pPacket == NULL)
+ break;
+
+ status = processHdrAndRxComp(device, pPacket, FALSE);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+ }
+ else
+ break;
+ }
+
+ //2. Dequeue from sync completion queue for processing header, the trialer info at this point is useless.
+ syncQDepth = 0;
+ while(!HTC_QUEUE_EMPTY(&device->pRecvTask->rxSyncCompletionQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxSyncCompletionQueue);
+ if(pPacket == NULL)
+ break;
+ syncQDepth++;
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ curPayloadLen = *(A_UINT16*)(&pBuffer[2]);
+ pPacket->ActualLength = curPayloadLen + HTC_HDR_LENGTH;
+ paddedLength = DEV_CALC_RECV_PADDED_LEN(device, pPacket->ActualLength);
+#else
+ paddedLength = DEV_CALC_RECV_PADDED_LEN(device, pPacket->ActualLength);
+ if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK){
+ paddedLength += HIF_MBOX_BLOCK_SIZE;
+ }
+#endif
+ A_MEMCPY(pPacket->pBuffer, pBuffer, paddedLength);
+ pBuffer += paddedLength;
+ status = processHdrAndRxComp(device, pPacket, FALSE);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if(syncQDepth > (pPacketRxBundle->BundlePktnum - 1))
+ break;
+ }
+ //if the next pkt is single, dequeue it and process it, until the bundle pkts
+ while(TRUE) {
+ nextIsSingle = 0;
+ pPacket = HTC_GET_PKT_AT_HEAD(&device->pRecvTask->rxSyncCompletionQueue);
+ if(pPacket == NULL)
+ break;
+ if(pPacket->BundlePktnum == 1) {
+ nextIsSingle = 1;
+ }
+ if(nextIsSingle == 1) {
+ pPacket = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxSyncCompletionQueue);
+ if(pPacket == NULL)
+ break;
+ status = processHdrAndRxComp(device, pPacket, FALSE);
+ if (A_FAILED(status)) {
+ break;
+ }
+ }
+ else
+ break;
+ }
+ spin_unlock_irqrestore(&device->pRecvTask->rx_sync_completion_lock, flags);
+ FreeHTCBundleRxPacket(target, pPacketRxBundle);
+ }
+ }
+ spin_unlock_irqrestore(&device->pRecvTask->rx_bundle_lock, flags);
+ //alloc skb for next bundle
+ spin_lock_irqsave(&device->pRecvTask->rx_alloc_lock, flags);
+ while(HTC_PACKET_QUEUE_DEPTH(&device->pRecvTask->rxAllocQueue) < 64) {
+ pPacket = HIFDevAllocRxBuffer(device, 2048);
+ if(pPacket == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Short of mem, alloc failed"));
+ break;
+ }
+ HTC_PACKET_ENQUEUE(&device->pRecvTask->rxAllocQueue, pPacket);
+ }
+ spin_unlock_irqrestore(&device->pRecvTask->rx_alloc_lock, flags);
+ }
+ complete_and_exit(&device->pRecvTask->rx_completion_exit, 0);
+ return 0;
+}
+#endif
+
static A_STATUS HIFDevIssueRecvPacketBundle(HIF_SDIO_DEVICE *pDev,
HTC_PACKET_QUEUE *pRecvPktQueue,
HTC_PACKET_QUEUE *pSyncCompletionQueue,
A_UINT8 MailBoxIndex,
int *pNumPacketsFetched,
- A_BOOL PartialBundle)
+ A_BOOL PartialBundle
+#ifdef HIF_RX_THREAD
+ , int *pNumLookAheads
+ , A_UINT32 LookAheads[]
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , A_UINT32 lookAhead_part2[]
+#endif
+#endif
+ )
{ A_STATUS status = A_OK;
int i, totalLength = 0;
unsigned char *pBundleBuffer = NULL;
HTC_PACKET *pPacket, *pPacketRxBundle;
HTC_TARGET *target = NULL;
A_UINT32 paddedLength;
-
+#ifdef HIF_RX_THREAD
+ unsigned long flags;
+#else
+ unsigned char *pBuffer = NULL;
+#endif
int bundleSpaceRemaining = 0;
target = (HTC_TARGET *)pDev->pTarget;
@@ -685,6 +1083,9 @@
totalLength += paddedLength;
}
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ totalLength = (A_UINT16)((lookAhead_part2[0] & 0xffff0000) >> 16);
+#endif
#if DEBUG_BUNDLE
adf_os_print("Recv bundle count %d, length %d.\n",
HTC_PACKET_QUEUE_DEPTH(pSyncCompletionQueue), totalLength);
@@ -715,37 +1116,77 @@
if(status != A_OK){
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s, HIFSend Failed status:%d \n",__FUNCTION__, status));
}else{
- unsigned char *pBuffer = pBundleBuffer;
+#ifdef HIF_RX_THREAD
+ HIFDevPreprocessTrailer(pDev, pPacketRxBundle, LookAheads, pNumLookAheads
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , lookAhead_part2);
+#else
+ );
+#endif
*pNumPacketsFetched = i;
+#ifdef HIF_RX_THREAD
+ pPacketRxBundle->BundlePktnum = i;
+#endif
+ spin_lock_irqsave(&pDev->pRecvTask->rx_bundle_lock, flags);
+ HTC_PACKET_ENQUEUE(&pDev->pRecvTask->rxBundleQueue, pPacketRxBundle);
+ spin_unlock_irqrestore(&pDev->pRecvTask->rx_bundle_lock, flags);
+
+ spin_lock_irqsave(&pDev->pRecvTask->rx_sync_completion_lock, flags);
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pDev->pRecvTask->rxSyncCompletionQueue, pSyncCompletionQueue);
+ spin_unlock_irqrestore(&pDev->pRecvTask->rx_sync_completion_lock, flags);
+#else
+ *pNumPacketsFetched = i;
+ pBuffer = pBundleBuffer;
HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pSyncCompletionQueue, pPacket){
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ curPayloadLen = *(A_UINT16*)(&pBuffer[2]);
+ pPacket->ActualLength = curPayloadLen + HTC_HDR_LENGTH;
+ paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, pPacket->ActualLength);
+#else
paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, pPacket->ActualLength);
if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK){
paddedLength += HIF_MBOX_BLOCK_SIZE;
}
+#endif
A_MEMCPY(pPacket->pBuffer, pBuffer, paddedLength);
pBuffer += paddedLength;
}HTC_PACKET_QUEUE_ITERATE_END;
+#endif
}
+#ifndef HIF_RX_THREAD
/* free bundle space under Sync mode */
FreeHTCBundleRxPacket(target, pPacketRxBundle);
+#endif
return status;
}
+
A_STATUS HIFDevRecvMessagePendingHandler(HIF_SDIO_DEVICE *pDev,
A_UINT8 MailBoxIndex,
A_UINT32 MsgLookAheads[],
int NumLookAheads,
A_BOOL *pAsyncProc,
- int *pNumPktsFetched)
+ int *pNumPktsFetched
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , A_UINT32 LookAhead_Part2[])
+#else
+ )
+#endif
{
A_STATUS status = A_OK;
HTC_PACKET *pPacket;
A_BOOL asyncProc = FALSE;
A_UINT32 lookAheads[HTC_MAX_MSG_PER_BUNDLE_RX];
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ A_UINT32 lookAhead_part2[HTC_MAX_MSG_PER_BUNDLE_RX];
+#endif
int pktsFetched;
HTC_PACKET_QUEUE recvPktQueue, syncCompletedPktsQueue;
A_BOOL partialBundle;
HTC_ENDPOINT_ID id;
int totalFetched = 0;
+#ifdef HIF_RX_THREAD
+ unsigned long flags;
+#endif
HTC_TARGET *target = NULL;
@@ -772,6 +1213,9 @@
return A_EPROTO;
}
A_MEMCPY(lookAheads, MsgLookAheads, (sizeof(A_UINT32)) * NumLookAheads);
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ A_MEMCPY(lookAhead_part2, LookAhead_Part2, (sizeof(A_UINT32)) * NumLookAheads);
+#endif
target = (HTC_TARGET *)pDev->pTarget;
id = ((HTC_FRAME_HDR *) &lookAheads[0])->EndpointID;
@@ -783,7 +1227,6 @@
#endif
-
while (TRUE) {
/* reset packets queues */
@@ -794,7 +1237,6 @@
A_ASSERT(FALSE);
break;
}
-
/* first lookahead sets the expected endpoint IDs for all packets in a bundle */
id = ((HTC_FRAME_HDR *) &lookAheads[0])->EndpointID;
@@ -822,16 +1264,23 @@
/* now go fetch the list of HTC packets */
while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
-
pktsFetched = 0;
if ((HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 1)) {
/* there are enough packets to attempt a bundle transfer and recv bundling is allowed */
- status = HIFDevIssueRecvPacketBundle(pDev,
- &recvPktQueue,
- asyncProc ? NULL : &syncCompletedPktsQueue,
- MailBoxIndex,
- &pktsFetched,
- partialBundle);
+ status = HIFDevIssueRecvPacketBundle(pDev,
+ &recvPktQueue,
+ asyncProc ? NULL : &syncCompletedPktsQueue,
+ MailBoxIndex,
+ &pktsFetched,
+ partialBundle
+#ifdef HIF_RX_THREAD
+ , &NumLookAheads
+ , lookAheads
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , lookAhead_part2
+#endif
+#endif
+ );
if (A_FAILED(status)) {
while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
adf_nbuf_t netbuf;
@@ -901,7 +1350,21 @@
break;
}
/* sent synchronously, queue this packet for synchronous completion */
+#ifdef HIF_RX_THREAD
+ NumLookAheads = 0;
+ HIFDevPreprocessTrailer(pDev, pPacket, lookAheads, &NumLookAheads
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , lookAhead_part2);
+#else
+ );
+#endif
+ pPacket->BundlePktnum = 1;
+ spin_lock_irqsave(&pDev->pRecvTask->rx_sync_completion_lock, flags);
+ HTC_PACKET_ENQUEUE(&pDev->pRecvTask->rxSyncCompletionQueue, pPacket);
+ spin_unlock_irqrestore(&pDev->pRecvTask->rx_sync_completion_lock, flags);
+#else
HTC_PACKET_ENQUEUE(&syncCompletedPktsQueue, pPacket);
+#endif
}
}
@@ -913,7 +1376,9 @@
/* in the sync case, all packet buffers are now filled,
* we can process each packet, check lookaheads and then repeat */
-
+#ifdef HIF_RX_THREAD
+ up(&pDev->pRecvTask->sem_rx_completion);
+#else
/* unload sync completion queue */
while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
A_UINT8 pipeid;
@@ -924,8 +1389,12 @@
break;
NumLookAheads = 0;
- status = HIFDevProcessRecvHeader(pDev, pPacket, lookAheads,
- &NumLookAheads);
+ status = HIFDevProcessRecvHeader(pDev, pPacket, lookAheads, &NumLookAheads, TRUE
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , lookAhead_part2);
+#else
+ );
+#endif
if (A_FAILED(status)) {
HTC_PACKET_ENQUEUE_TO_HEAD(&syncCompletedPktsQueue, pPacket);
break;
@@ -942,7 +1411,7 @@
pipeid);
}
}
-
+#endif
if (A_FAILED(status)) {
while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
adf_nbuf_t netbuf;
@@ -1130,6 +1599,9 @@
A_STATUS status = A_OK;
A_UINT8 host_int_status = 0;
A_UINT32 lookAhead[MAILBOX_USED_COUNT];
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ A_UINT32 lookAhead_part2[MAILBOX_USED_COUNT];
+#endif
int i;
A_MEMZERO(&lookAhead, sizeof(lookAhead));
@@ -1150,7 +1622,6 @@
break;
}
-
#ifdef HIF_SYNC_READ
status = HIFSyncRead(pDev->HIFDevice,
HOST_INT_STATUS_ADDRESS,
@@ -1193,9 +1664,18 @@
if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << i)) {
/* mailbox has a message and the look ahead is valid */
lookAhead[i] = pDev->IrqProcRegisters.rx_lookahead[MAILBOX_LOOKAHEAD_SIZE_IN_WORD*i];
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ lookAhead_part2[i] = pDev->IrqProcRegisters.rx_lookahead[MAILBOX_LOOKAHEAD_SIZE_IN_WORD*i + 1];
+#endif
}
}
} /*end of for loop*/
+#ifdef HIF_RX_THREAD
+ if (((HTC_FRAME_HDR *) &lookAhead[0])->EndpointID >= ENDPOINT_MAX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Endpoint id in register invalid"
+ " %d\n", ((HTC_FRAME_HDR *) &lookAhead[0])->EndpointID));
+ }
+#endif
} while (FALSE);
do {
@@ -1236,7 +1716,12 @@
&lookAhead[i],
1,
pASyncProcessing,
- &fetched);
+ &fetched
+#if HIF_BUNDLE_DIFF_BLK_FRAMES
+ , lookAhead_part2);
+#else
+ );
+#endif
if (A_FAILED(status)) {
break;
}
diff --git a/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c b/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c
index 416a682..0174a60 100644
--- a/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c
+++ b/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -882,12 +882,18 @@
*/
static inline int hif_start_tx_completion_thread(HIF_DEVICE *device)
{
+#ifdef CONFIG_PERF_NON_QC_PLATFORM
+ struct sched_param param = {.sched_priority = 99};
+#endif
if (!device->tx_completion_task) {
device->tx_completion_req = NULL;
device->last_tx_completion = &device->tx_completion_req;
device->tx_completion_shutdown = 0;
device->tx_completion_task = kthread_create(tx_completion_task,
(void *)device, "AR6K TxCompletion");
+#ifdef CONFIG_PERF_NON_QC_PLATFORM
+ sched_setscheduler(device->tx_completion_task, SCHED_FIFO, ¶m);
+#endif
if (IS_ERR(device->tx_completion_task)) {
device->tx_completion_shutdown = 1;
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
@@ -2030,7 +2036,9 @@
static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func)
{
int ret = A_OK;
-
+#ifdef CONFIG_PERF_NON_QC_PLATFORM
+ struct sched_param param = {.sched_priority = 99};
+#endif
ENTER("sdio_func 0x%pK", func);
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n"));
@@ -2142,6 +2150,9 @@
device->async_task = kthread_create(async_task,
(void *)device,
"AR6K Async");
+#ifdef CONFIG_PERF_NON_QC_PLATFORM
+ sched_setscheduler(device->async_task, SCHED_FIFO, ¶m);
+#endif
if (IS_ERR(device->async_task)) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
device->async_task = NULL;
diff --git a/CORE/SERVICES/HTC/htc_send.c b/CORE/SERVICES/HTC/htc_send.c
index ad47adc..bc26d7e 100644
--- a/CORE/SERVICES/HTC/htc_send.c
+++ b/CORE/SERVICES/HTC/htc_send.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -412,8 +412,8 @@
adf_os_print(" Send bundle EP%d buffer size:0x%x, total:0x%x, count:%d.\n",
pEndpoint->Id,
pEndpoint->TxCreditSize,
- data_len,
- data_len / pEndpoint->TxCreditSize);
+ (int)data_len,
+ (int)data_len / pEndpoint->TxCreditSize);
#endif
#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
@@ -526,8 +526,10 @@
HTC_WRITE32((A_UINT32 *)pHtcHdr + 1,
SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1) |
SM(creditPad, HTC_FRAME_HDR_RESERVED));
+#if !HIF_BUNDLE_DIFF_BLK_FRAMES
pHtcHdr->reserved = creditPad;
#endif
+#endif
frag_count = adf_nbuf_get_num_frags(netbuf);
nbytes = pPacket->ActualLength + HTC_HDR_LENGTH;
for (i = 0; i < frag_count && nbytes > 0; i ++){
@@ -668,7 +670,7 @@
adf_os_print(" Send single EP%d buffer size:0x%x, total:0x%x.\n",
pEndpoint->Id,
pEndpoint->TxCreditSize,
- HTC_HDR_LENGTH + pPacket->ActualLength);
+ (int)HTC_HDR_LENGTH + pPacket->ActualLength);
#endif
#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
@@ -1538,7 +1540,7 @@
adf_os_print(" Send single EP%d buffer size:0x%x, total:0x%x.\n",
pEndpoint->Id,
pEndpoint->TxCreditSize,
- HTC_HDR_LENGTH + pPacket->ActualLength);
+ (int)HTC_HDR_LENGTH + pPacket->ActualLength);
#endif
#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
diff --git a/CORE/VOSS/src/vos_sched.c b/CORE/VOSS/src/vos_sched.c
index 3f24b92..cb5787e 100644
--- a/CORE/VOSS/src/vos_sched.c
+++ b/CORE/VOSS/src/vos_sched.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -501,6 +501,9 @@
)
{
VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
+#ifdef CONFIG_PERF_NON_QC_PLATFORM
+ struct sched_param param = {.sched_priority = 99};
+#endif
/*-------------------------------------------------------------------------*/
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
"%s: Opening the VOSS Scheduler",__func__);
@@ -589,6 +592,9 @@
pSchedContext->TlshimRxThread = kthread_create(VosTlshimRxThread,
pSchedContext,
"VosTlshimRxThread");
+#ifdef CONFIG_PERF_NON_QC_PLATFORM
+ sched_setscheduler(pSchedContext->TlshimRxThread, SCHED_FIFO, ¶m);
+#endif
if (IS_ERR(pSchedContext->TlshimRxThread))
{