TWD/FW_Transfer/RxXfer.c
changeset 0 10c42ec6c05f
equal deleted inserted replaced
-1:000000000000 0:10c42ec6c05f
       
     1 /*
       
     2  * RxXfer.c
       
     3  *
       
     4  * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.      
       
     5  * All rights reserved.      
       
     6  * 
       
     7  * This program and the accompanying materials are made available under the 
       
     8  * terms of the Eclipse Public License v1.0 or BSD License which accompanies
       
     9  * this distribution. The Eclipse Public License is available at
       
    10  * http://www.eclipse.org/legal/epl-v10.html and the BSD License is as below.                                   
       
    11  *                                                                       
       
    12  * Redistribution and use in source and binary forms, with or without    
       
    13  * modification, are permitted provided that the following conditions    
       
    14  * are met:                                                              
       
    15  *                                                                       
       
    16  *  * Redistributions of source code must retain the above copyright     
       
    17  *    notice, this list of conditions and the following disclaimer.      
       
    18  *  * Redistributions in binary form must reproduce the above copyright  
       
    19  *    notice, this list of conditions and the following disclaimer in    
       
    20  *    the documentation and/or other materials provided with the         
       
    21  *    distribution.                                                      
       
    22  *  * Neither the name Texas Instruments nor the names of its            
       
    23  *    contributors may be used to endorse or promote products derived    
       
    24  *    from this software without specific prior written permission.      
       
    25  *                                                                       
       
    26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   
       
    27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     
       
    28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
       
    29  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  
       
    30  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
       
    31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      
       
    32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
       
    33  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
       
    34  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   
       
    35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
       
    36  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    37  */
       
    38 
       
    39 
       
    40 /****************************************************************************
       
    41  *
       
    42  *   MODULE:  rxXfer.c
       
    43  *
       
    44  *   PURPOSE: Rx Xfer module implementation.Responsible for reading Rx from the FW
       
    45  *              and forward it to the upper layers.
       
    46  * 
       
    47  ****************************************************************************/
       
    48 
       
    49 #define __FILE_ID__  FILE_ID_106
       
    50 #include "tidef.h"
       
    51 #include "osApi.h"
       
    52 #include "report.h"
       
    53 #include "RxXfer.h"
       
    54 #include "FwEvent_api.h"
       
    55 #include "TWDriverInternal.h"
       
    56 #include "RxQueue_api.h"
       
    57 #include "TwIf.h"
       
    58 #include "public_host_int.h"
       
    59 
       
    60 #define RX_DRIVER_COUNTER_ADDRESS 0x300538
       
    61 #define RX_DRIVER_DUMMY_WRITE_ADDRESS 0x300534
       
    62 #define PLCP_HEADER_LENGTH 8
       
    63 #define WORD_SIZE   4
       
    64 #define UNALIGNED_PAYLOAD   0x1
       
    65 
       
    66 #define SLV_MEM_ADDR_VALUE(desc, offset)((RX_DESC_GET_MEM_BLK(desc)<<8)+ offset + 4)
       
    67 #define SLV_MEM_CP_VALUE(desc, offset)  (((RX_DESC_GET_MEM_BLK(desc)<<8)+ offset))
       
    68 /* Add an extra word for alignment the MAC payload in case of QoS MSDU */
       
    69 #define ALIGNMENT_SIZE(desc)            ((RX_DESC_GET_UNALIGNED(desc) & UNALIGNED_PAYLOAD)? 2 : 0)
       
    70 /*QOS definitions*/
       
    71 #define QOS_HW_ADDRESS		0x14FDA
       
    72 #define QOS_SHIF_BACK_BUFFER	2
       
    73 #define QOS_LENGTH_DIFF		2
       
    74 #define QOS_SHIF_IN_BUFFER	4
       
    75 /************************ static function declaration *****************************/
       
    76 
       
    77 static void rxXfer_TxnDoneCb (TI_HANDLE hRxXfer, TTxnStruct* pTxn);
       
    78 static void rxXfer_IssueTxn (TI_HANDLE hRxXfer, TI_UINT32 uRxDesc, TI_UINT8 *pHostBuf, TI_UINT32 uBuffSize, TI_BOOL bDropPacket);
       
    79 static void rxXfer_ForwardPacket (RxXfer_t* pRxXfer, TTxnStruct* pTxn);
       
    80 
       
    81 /****************************************************************************
       
    82  *                      RxXfer_Create()
       
    83  ****************************************************************************
       
    84  * DESCRIPTION: Create the RxXfer module object 
       
    85  * 
       
    86  * INPUTS:  None
       
    87  * 
       
    88  * OUTPUT:  None
       
    89  * 
       
    90  * RETURNS: The Created object
       
    91  ****************************************************************************/
       
    92 TI_HANDLE rxXfer_Create (TI_HANDLE hOs)
       
    93 {
       
    94     RxXfer_t *pRxXfer;
       
    95     int i;
       
    96 
       
    97     pRxXfer = os_memoryAlloc (hOs, sizeof(RxXfer_t),MemoryNormal);
       
    98     if (pRxXfer == NULL)
       
    99         return NULL;
       
   100 
       
   101     /* For all the counters */
       
   102     os_memoryZero (hOs, pRxXfer, sizeof(RxXfer_t));
       
   103 
       
   104     pRxXfer->pTempBuffer = os_memoryAlloc (hOs, MAX_PACKET_SIZE + WSPI_PAD_LEN_READ,MemoryDMA);
       
   105     if (pRxXfer->pTempBuffer == NULL) 
       
   106     {
       
   107         return NULL;
       
   108     }
       
   109     os_memoryZero (hOs, pRxXfer->pTempBuffer, MAX_PACKET_SIZE + WSPI_PAD_LEN_READ);
       
   110     pRxXfer->pTempBuffer += WSPI_PAD_LEN_READ;
       
   111 
       
   112     for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++) 
       
   113     {
       
   114         pRxXfer->aSlaveRegTxn[i].pRegData = os_memoryAlloc (hOs, 2*REGISTER_SIZE + WSPI_PAD_LEN_READ,MemoryDMA);
       
   115         if (pRxXfer->aSlaveRegTxn[i].pRegData == NULL) 
       
   116         {
       
   117             return NULL;
       
   118         }
       
   119         os_memoryZero (hOs, pRxXfer->aSlaveRegTxn[i].pRegData, 2*REGISTER_SIZE + WSPI_PAD_LEN_READ);
       
   120         pRxXfer->aSlaveRegTxn[i].pRegData += WSPI_PAD_LEN_READ;
       
   121     }
       
   122 
       
   123     for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++) 
       
   124     {
       
   125         pRxXfer->aCounterTxn[i].pCounter = os_memoryAlloc (hOs, REGISTER_SIZE + WSPI_PAD_LEN_READ,MemoryDMA);
       
   126         if (pRxXfer->aCounterTxn[i].pCounter == NULL) 
       
   127         {
       
   128             return NULL;
       
   129         }
       
   130         os_memoryZero (hOs, pRxXfer->aCounterTxn[i].pCounter, REGISTER_SIZE + WSPI_PAD_LEN_READ);
       
   131         pRxXfer->aCounterTxn[i].pCounter += WSPI_PAD_LEN_READ;
       
   132     }
       
   133 
       
   134     for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++) 
       
   135     {
       
   136         pRxXfer->aDummyTxn[i].pData = os_memoryAlloc (hOs, REGISTER_SIZE + WSPI_PAD_LEN_READ,MemoryDMA);
       
   137         if (pRxXfer->aDummyTxn[i].pData == NULL) 
       
   138         {
       
   139             return NULL;
       
   140         }
       
   141         os_memoryZero (hOs, pRxXfer->aDummyTxn[i].pData, REGISTER_SIZE + WSPI_PAD_LEN_READ);
       
   142         pRxXfer->aDummyTxn[i].pData += WSPI_PAD_LEN_READ;
       
   143     }
       
   144     
       
   145 
       
   146     pRxXfer->hOs = hOs;
       
   147 
       
   148     return (TI_HANDLE)pRxXfer;
       
   149 }
       
   150 
       
   151 
       
   152 /****************************************************************************
       
   153  *                      RxXfer_Destroy()
       
   154  ****************************************************************************
       
   155  * DESCRIPTION: Destroy the RxXfer module object 
       
   156  * 
       
   157  * INPUTS:  hRxXfer - The object to free
       
   158  * 
       
   159  * OUTPUT:  None
       
   160  * 
       
   161  * RETURNS: 
       
   162  ****************************************************************************/
       
   163 void rxXfer_Destroy (TI_HANDLE hRxXfer)
       
   164 {
       
   165     RxXfer_t *pRxXfer = (RxXfer_t *)hRxXfer;
       
   166     int i;
       
   167 
       
   168     if (pRxXfer)
       
   169     {
       
   170         if (pRxXfer->pTempBuffer) 
       
   171         {
       
   172             os_memoryFree (pRxXfer->hOs, pRxXfer->pTempBuffer - WSPI_PAD_LEN_READ, MAX_PACKET_SIZE + WSPI_PAD_LEN_READ);
       
   173         }
       
   174 
       
   175         for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++) 
       
   176         {
       
   177             if (pRxXfer->aSlaveRegTxn[i].pRegData) 
       
   178             {
       
   179                 os_memoryFree (pRxXfer->hOs, pRxXfer->aSlaveRegTxn[i].pRegData - WSPI_PAD_LEN_READ, 2*REGISTER_SIZE + WSPI_PAD_LEN_READ);
       
   180             }
       
   181         }
       
   182     
       
   183         for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++) 
       
   184         {
       
   185             if (pRxXfer->aCounterTxn[i].pCounter) 
       
   186             {
       
   187                 os_memoryFree (pRxXfer->hOs, pRxXfer->aCounterTxn[i].pCounter - WSPI_PAD_LEN_READ, REGISTER_SIZE + WSPI_PAD_LEN_READ);
       
   188             }
       
   189         }
       
   190     
       
   191         for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++) 
       
   192         {
       
   193             if (pRxXfer->aDummyTxn[i].pData) 
       
   194             {
       
   195                 os_memoryFree (pRxXfer->hOs, pRxXfer->aDummyTxn[i].pData - WSPI_PAD_LEN_READ, REGISTER_SIZE + WSPI_PAD_LEN_READ);
       
   196             }
       
   197         }
       
   198     
       
   199         os_memoryFree (pRxXfer->hOs, pRxXfer, sizeof(RxXfer_t));
       
   200     }
       
   201 }
       
   202 
       
   203 
       
   204 /****************************************************************************
       
   205  *                      rxXfer_init()
       
   206  ****************************************************************************
       
   207  * DESCRIPTION: Init the FwEvent module object 
       
   208  * 
       
   209  * INPUTS:      hRxXfer       - FwEvent handle;
       
   210  * 
       
   211  * OUTPUT:  None
       
   212  * 
       
   213  * RETURNS: None
       
   214  ****************************************************************************/
       
   215 void rxXfer_Init(TI_HANDLE hRxXfer,
       
   216                  TI_HANDLE hFwEvent, 
       
   217                  TI_HANDLE hReport,
       
   218                  TI_HANDLE hTwIf,
       
   219                  TI_HANDLE hRxQueue)
       
   220 {
       
   221     RxXfer_t  *pRxXfer      = (RxXfer_t *)hRxXfer;
       
   222 
       
   223     pRxXfer->hFwEvent       = hFwEvent;
       
   224     pRxXfer->hReport        = hReport;
       
   225     pRxXfer->hTwIf          = hTwIf;
       
   226     pRxXfer->hRxQueue       = hRxQueue;
       
   227     pRxXfer->uDrvRxCntr     = 0;
       
   228 
       
   229     RxXfer_ReStart (hRxXfer);
       
   230 
       
   231 #ifdef TI_DBG   
       
   232     rxXfer_ClearStats (pRxXfer);
       
   233 #endif
       
   234 }
       
   235 
       
   236 
       
   237 /****************************************************************************
       
   238  *                      rxXfer_Register_CB()
       
   239  ****************************************************************************
       
   240  * DESCRIPTION: Register the function to be called for request for buffer.
       
   241  * 
       
   242  * INPUTS:      hRxXfer       - RxXfer handle;
       
   243  * 
       
   244  * OUTPUT:  None
       
   245  * 
       
   246  * RETURNS: None
       
   247  ****************************************************************************/
       
   248 void rxXfer_Register_CB (TI_HANDLE hRxXfer, TI_UINT32 CallBackID, void *CBFunc, TI_HANDLE CBObj)
       
   249 {
       
   250     RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
       
   251 
       
   252     TRACE1(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , "rxXfer_Register_CB (Value = 0x%x)\n", CallBackID);
       
   253 
       
   254     switch(CallBackID)
       
   255     {
       
   256     case TWD_INT_REQUEST_FOR_BUFFER:       
       
   257         pRxXfer->RequestForBufferCB = (TRequestForBufferCb)CBFunc;
       
   258         pRxXfer->RequestForBufferCB_handle = CBObj;
       
   259         break;
       
   260 
       
   261     default:
       
   262         TRACE0(pRxXfer->hReport, REPORT_SEVERITY_ERROR, "rxXfer_Register_CB - Illegal value\n");
       
   263         return;
       
   264     }
       
   265 }
       
   266 
       
   267 
       
   268 /****************************************************************************
       
   269  *                      rxXfer_ForwardPacket()
       
   270  ****************************************************************************
       
   271  * DESCRIPTION:  Forward received packet to the upper layers.
       
   272  *
       
   273  * INPUTS:      
       
   274  * 
       
   275  * OUTPUT:      
       
   276  * 
       
   277  * RETURNS:     
       
   278  ****************************************************************************/
       
   279 static void rxXfer_ForwardPacket (RxXfer_t* pRxXfer, TTxnStruct* pTxn)
       
   280 {
       
   281 	RxIfDescriptor_t *pRxInfo;
       
   282     TI_UINT16        uLenFromRxInfo;
       
   283 
       
   284 	if (pTxn->uHwAddr == QOS_HW_ADDRESS)/*in case of QOS*/
       
   285 	{
       
   286 		pTxn->aBuf[0]-= QOS_SHIF_BACK_BUFFER;
       
   287 		pRxInfo  = (RxIfDescriptor_t*)(pTxn->aBuf[0]);
       
   288 		/*in case of QOS we ask to read the data with 2 bytes shift so the packet will be alignd.
       
   289 		as a result we asked to read 2 bytes less,
       
   290 		since we are adding the mising 2 bytes (length)
       
   291 		we need to add those 2 bytes to the length*/
       
   292 		pTxn->aLen[0]+= QOS_LENGTH_DIFF;
       
   293 		/*devide by 4 to have the value in word (from byte)*/
       
   294 		pRxInfo->length = pTxn->aLen[0] >> 2;
       
   295 		/*fix back the endianaty and setting the missing value from the shor descriptor*/
       
   296 		pRxInfo->length = ENDIAN_HANDLE_WORD(pRxInfo->length);
       
   297 		/*now we have the a regular Rx info with all parameters */
       
   298 		pRxInfo  = (RxIfDescriptor_t*)(pTxn->aBuf[0]);
       
   299 		
       
   300 	}
       
   301 	else
       
   302 	{
       
   303 		/*in case of regular packet*/
       
   304 		pRxInfo  = (RxIfDescriptor_t*)(pTxn->aBuf[0]);	
       
   305 	}
       
   306 
       
   307 
       
   308 #ifdef TI_DBG   /* packet sanity check */
       
   309     /* Get length from RxInfo, handle endianess and convert to length in bytes */
       
   310     uLenFromRxInfo = ENDIAN_HANDLE_WORD(pRxInfo->length) << 2;
       
   311 
       
   312     /* If the length in the RxInfo is different than in the short descriptor, set error status */
       
   313     if (pTxn->aLen[0] != uLenFromRxInfo) 
       
   314     {
       
   315         TRACE3(pRxXfer->hReport, REPORT_SEVERITY_ERROR , ": Bad Length!! RxInfoLength=%d, ShortDescLen=%d, RxInfoStatus=0x%x\n", uLenFromRxInfo, pTxn->aLen[0], pRxInfo->status);
       
   316         report_PrintDump(pTxn->aBuf[0], pTxn->aLen[0]);
       
   317         pRxInfo->status &= ~RX_DESC_STATUS_MASK;
       
   318         pRxInfo->status |= RX_DESC_STATUS_DRIVER_RX_Q_FAIL;
       
   319         pRxInfo->length = ENDIAN_HANDLE_WORD(pTxn->aLen[0] >> 2);
       
   320     }
       
   321 #endif
       
   322 
       
   323     /* Forward received packet to the upper layers */
       
   324     RxQueue_ReceivePacket (pRxXfer->hRxQueue, (const void *)pTxn->aBuf[0]);
       
   325 
       
   326     /* reset the aBuf field for clean on recovery purpose */
       
   327     pTxn->aBuf[0] = 0;
       
   328 }
       
   329 
       
   330 
       
   331 /****************************************************************************
       
   332  *                      rxXfer_RxEvent()
       
   333  ****************************************************************************
       
   334  * DESCRIPTION: Called upon Rx event from the FW.calls the SM  
       
   335  * 
       
   336  * INPUTS:      hRxXfer       - RxXfer handle;
       
   337  * 
       
   338  * OUTPUT:  None
       
   339  * 
       
   340  * RETURNS: TWIF_OK in case of Synch mode, or TWIF_PENDING in case of Asynch mode
       
   341  *          (when returning TWIF_PENDING, FwEvent module expects the FwEvent_EventComplete()
       
   342  *          function call to finish the Rx Client handling 
       
   343  *
       
   344  ****************************************************************************/
       
   345 TI_STATUS rxXfer_RxEvent (TI_HANDLE hRxXfer, FwStatus_t *pFwStatus)
       
   346 {
       
   347     RxXfer_t       *pRxXfer = (RxXfer_t *)hRxXfer;
       
   348     TI_UINT32      uTempCounters;
       
   349     FwStatCntrs_t  *pFwStatusCounters;
       
   350     TI_UINT32       i;
       
   351     TI_STATUS   rc;
       
   352     
       
   353 
       
   354     uTempCounters = ENDIAN_HANDLE_LONG (pFwStatus->counters);
       
   355 #ifdef TI_DBG
       
   356 	pRxXfer->DbgStats.counters = uTempCounters;
       
   357 #endif
       
   358     pFwStatusCounters = (FwStatCntrs_t*)(&uTempCounters);
       
   359 
       
   360     TRACE2(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , ": NewFwCntr=%d, OldFwCntr=%d\n", pFwStatusCounters->fwRxCntr, pRxXfer->uFwRxCntr);
       
   361 
       
   362     if (pFwStatusCounters->fwRxCntr%8 == pRxXfer->uFwRxCntr%8)
       
   363     {
       
   364         return TI_OK;
       
   365     }
       
   366     pRxXfer->uFwRxCntr = pFwStatusCounters->fwRxCntr;
       
   367 
       
   368     for (i = 0; i < NUM_RX_PKT_DESC; i++)
       
   369     {
       
   370         pRxXfer->aRxPktsDesc[i] = ENDIAN_HANDLE_LONG (pFwStatus->rxPktsDesc[i]); 
       
   371     }
       
   372 
       
   373     rc = rxXfer_Handle (pRxXfer);
       
   374 
       
   375     return rc;
       
   376 }
       
   377 
       
   378 
       
   379 /****************************************************************************
       
   380  *                      rxXfer_Handle()
       
   381  ****************************************************************************
       
   382  * DESCRIPTION: 
       
   383  *
       
   384  * INPUTS:      hRxXfer       - RxXfer handle;
       
   385  * 
       
   386  * OUTPUT:      
       
   387  * 
       
   388  * RETURNS:     
       
   389  ****************************************************************************/
       
   390 TI_STATUS rxXfer_Handle(TI_HANDLE hRxXfer)
       
   391 {
       
   392 #ifndef _VLCT_
       
   393     RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
       
   394     TI_UINT32   uRxDesc, uPacketIndex, uBuffSize, uSecurity;
       
   395     TI_UINT8 *pHostBuf;
       
   396     ERxBufferStatus  eBufStatus;
       
   397 
       
   398 
       
   399     if (pRxXfer->uAvailableTxn == 0 )
       
   400     {
       
   401         TRACE0(pRxXfer->hReport, REPORT_SEVERITY_ERROR, "(): No available Txn structures left!\n");
       
   402         return TI_NOK;
       
   403     }
       
   404 
       
   405     while (pRxXfer->uFwRxCntr%8 != pRxXfer->uDrvRxCntr%8)
       
   406     {
       
   407         uPacketIndex = pRxXfer->uDrvRxCntr % NUM_RX_PKT_DESC;
       
   408 
       
   409         uRxDesc =  pRxXfer->aRxPktsDesc[uPacketIndex];
       
   410         
       
   411         uBuffSize = RX_DESC_GET_LENGTH(uRxDesc) << 2;
       
   412 
       
   413         uSecurity = RX_DESC_GET_SECURITY(uRxDesc);
       
   414 
       
   415         /* prepare the read buffer */
       
   416         /* the RxBufAlloc() add an extra word for alignment the MAC payload in case of QoS MSDU */
       
   417         eBufStatus = pRxXfer->RequestForBufferCB(pRxXfer->RequestForBufferCB_handle, 
       
   418                                                  (void**)&pHostBuf,
       
   419                                                  uBuffSize,
       
   420                                                  uSecurity);
       
   421 
       
   422         TRACE6(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , ": Index=%d, RxDesc=0x%x, DrvCntr=%d, FwCntr=%d, BufStatus=%d, BuffSize=%d\n", uPacketIndex, uRxDesc, pRxXfer->uDrvRxCntr, pRxXfer->uFwRxCntr, eBufStatus, uBuffSize);
       
   423 
       
   424         switch (eBufStatus)
       
   425         {
       
   426             case RX_BUF_ALLOC_PENDING:
       
   427                 return TI_OK;
       
   428 
       
   429             case RX_BUF_ALLOC_COMPLETE:
       
   430                 rxXfer_IssueTxn (pRxXfer, uRxDesc, pHostBuf, uBuffSize, TI_FALSE);
       
   431                 break;
       
   432 
       
   433             case RX_BUF_ALLOC_OUT_OF_MEM:
       
   434                 /* In case the allocation failed, we read the packet to a temporary buffer and ignore it */
       
   435                 rxXfer_IssueTxn (pRxXfer, uRxDesc, pRxXfer->pTempBuffer, uBuffSize, TI_TRUE);
       
   436                 break;
       
   437         }
       
   438 
       
   439     /* End of while */
       
   440     }
       
   441 #endif
       
   442     return TI_OK;
       
   443 /* End of rxXfer_Handle() */
       
   444 }
       
   445 
       
   446 
       
   447 /****************************************************************************
       
   448  *                      rxXfer_IssueTxn()
       
   449  ****************************************************************************
       
   450  * DESCRIPTION: 
       
   451  *
       
   452  * INPUTS:      
       
   453  * 
       
   454  * OUTPUT:      
       
   455  * 
       
   456  * RETURNS:     
       
   457  ****************************************************************************/
       
   458 static void rxXfer_IssueTxn (TI_HANDLE hRxXfer, TI_UINT32 uRxDesc, TI_UINT8 *pHostBuf, TI_UINT32 uBuffSize, TI_BOOL bDropPacket)
       
   459 {
       
   460     RxXfer_t   *pRxXfer = (RxXfer_t *)hRxXfer;
       
   461     TI_UINT32   uIndex = pRxXfer->uDrvRxCntr % MAX_CONSECUTIVE_READ_TXN;
       
   462     TTxnStruct *pTxn;
       
   463     ETxnStatus  eStatus;
       
   464 
       
   465     /* Write the next mem block that we want to read */
       
   466     pRxXfer->aSlaveRegTxn[uIndex].tTxnStruct.uHwAddr = SLV_REG_DATA;
       
   467     ((TI_UINT32*)(pRxXfer->aSlaveRegTxn[uIndex].pRegData))[0] = SLV_MEM_CP_VALUE(uRxDesc, pRxXfer->uPacketMemoryPoolStart);
       
   468     ((TI_UINT32*)(pRxXfer->aSlaveRegTxn[uIndex].pRegData))[1] = SLV_MEM_ADDR_VALUE(uRxDesc, pRxXfer->uPacketMemoryPoolStart);
       
   469     twIf_Transact(pRxXfer->hTwIf, &pRxXfer->aSlaveRegTxn[uIndex].tTxnStruct);
       
   470 
       
   471     /* prepare the read transaction */ 
       
   472     pTxn = (TTxnStruct*)&pRxXfer->aTxnStruct[uIndex];
       
   473 
       
   474     if (!bDropPacket)
       
   475     {
       
   476 		
       
   477         if (ALIGNMENT_SIZE(uRxDesc))
       
   478 		{
       
   479 			/*because the DMA requiers a 4 bytes alingned buffer and in the case of QOS we have 
       
   480 			2 more bytes in the WLAN header,we will give a 4 byte shifted buffer for the read.
       
   481 			in addition we will ask to read the data with 2 bytes shift, in this way we will
       
   482 			packet aligned. because of this 2 bytes shif the lenght for the read should be 2
       
   483 			bytes shorter.
       
   484 			we will loose the first 2 bytes in the read (length in the RX info),
       
   485 			*/
       
   486 			BUILD_TTxnStruct(pTxn, SLV_MEM_QOS_DATA, pHostBuf +QOS_SHIF_IN_BUFFER , uBuffSize-QOS_LENGTH_DIFF, (TTxnDoneCb)rxXfer_TxnDoneCb, hRxXfer)
       
   487 		}
       
   488 		else
       
   489 		{
       
   490         BUILD_TTxnStruct(pTxn, SLV_MEM_DATA, pHostBuf, uBuffSize, (TTxnDoneCb)rxXfer_TxnDoneCb, hRxXfer)
       
   491     }
       
   492 			
       
   493     }
       
   494     else
       
   495     {
       
   496         TRACE0(pRxXfer->hReport, REPORT_SEVERITY_WARNING, "Request for Rx buffer failed! \n");
       
   497         BUILD_TTxnStruct(pTxn, SLV_MEM_DATA, pHostBuf, uBuffSize, NULL, NULL)
       
   498     }
       
   499 
       
   500     eStatus = twIf_Transact(pRxXfer->hTwIf, pTxn);
       
   501 
       
   502     pRxXfer->uDrvRxCntr++;
       
   503 
       
   504     
       
   505 
       
   506     pTxn = &pRxXfer->aCounterTxn[uIndex].tTxnStruct;
       
   507     *((TI_UINT32*)(pRxXfer->aCounterTxn[uIndex].pCounter)) = ENDIAN_HANDLE_LONG(pRxXfer->uDrvRxCntr);
       
   508     TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
       
   509     BUILD_TTxnStruct(pTxn, RX_DRIVER_COUNTER_ADDRESS, pRxXfer->aCounterTxn[uIndex].pCounter, REGISTER_SIZE, NULL, NULL)
       
   510     twIf_Transact(pRxXfer->hTwIf, pTxn);
       
   511 
       
   512     TRACE6(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , ": Counter-Txn: HwAddr=0x%x, Len0=%d, Data0=%d, DrvCount=%d, TxnParams=0x%x, RxDesc=0x%x\n", pTxn->uHwAddr, pTxn->aLen[0], *(TI_UINT32 *)(pTxn->aBuf[0]), pRxXfer->uDrvRxCntr, pTxn->uTxnParams, uRxDesc);
       
   513     
       
   514 
       
   515     if (!bDropPacket)
       
   516     {
       
   517         if (eStatus == TXN_STATUS_COMPLETE)
       
   518         {
       
   519             /* Forward received packet to the upper layers */
       
   520             rxXfer_ForwardPacket (pRxXfer, &(pRxXfer->aTxnStruct[uIndex]));
       
   521         }
       
   522         else if (eStatus == TXN_STATUS_PENDING) 
       
   523         {
       
   524             /* Decrease the number of available txn structures */
       
   525             pRxXfer->uAvailableTxn--;
       
   526         }
       
   527         else 
       
   528         {
       
   529             TRACE3(pRxXfer->hReport, REPORT_SEVERITY_ERROR , ": Status=%d, DrvCntr=%d, RxDesc=0x%x\n", eStatus, pRxXfer->uDrvRxCntr, uRxDesc);
       
   530         }
       
   531     }
       
   532 }
       
   533   
       
   534 
       
   535 /****************************************************************************
       
   536  *                      rxXfer_SetRxDirectAccessParams()
       
   537  ****************************************************************************
       
   538  * DESCRIPTION: 
       
   539  *
       
   540  * INPUTS:      
       
   541  * 
       
   542  * OUTPUT:      
       
   543  * 
       
   544  * RETURNS:     
       
   545  ****************************************************************************/
       
   546 void rxXfer_SetRxDirectAccessParams (TI_HANDLE hRxXfer, TDmaParams *pDmaParams)
       
   547 {
       
   548     RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
       
   549 
       
   550     pRxXfer->uPacketMemoryPoolStart = pDmaParams->PacketMemoryPoolStart;
       
   551 }
       
   552 
       
   553 
       
   554 /****************************************************************************
       
   555  *                      rxXfer_TxnDoneCb()
       
   556  ****************************************************************************
       
   557  * DESCRIPTION: Forward the packet to the registered CB
       
   558  *
       
   559  * INPUTS:      
       
   560  * 
       
   561  * OUTPUT:      
       
   562  * 
       
   563  * RETURNS:     
       
   564  ****************************************************************************/
       
   565 static void rxXfer_TxnDoneCb (TI_HANDLE hRxXfer, TTxnStruct* pTxn)
       
   566 {
       
   567     RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
       
   568     
       
   569     /* Increase the number of available txn structures */
       
   570     pRxXfer->uAvailableTxn++;
       
   571 
       
   572     /* Forward received packet to the upper layers */
       
   573     rxXfer_ForwardPacket (pRxXfer, pTxn);
       
   574 
       
   575     /* Handle further packets if any */
       
   576     rxXfer_Handle(hRxXfer);
       
   577 }
       
   578 
       
   579 
       
   580 /****************************************************************************
       
   581  *                      RxXfer_ReStart()
       
   582  ****************************************************************************
       
   583  * DESCRIPTION:	RxXfer_ReStart the RxXfer module object (called by the recovery)
       
   584  * 
       
   585  * INPUTS:	hRxXfer - The object to free
       
   586  * 
       
   587  * OUTPUT:	None
       
   588  * 
       
   589  * RETURNS:	NONE 
       
   590  ****************************************************************************/
       
   591 void RxXfer_ReStart(TI_HANDLE hRxXfer)
       
   592 {
       
   593 	RxXfer_t *pRxXfer = (RxXfer_t *)hRxXfer;
       
   594     TTxnStruct* pTxn;
       
   595     TI_UINT8    i;
       
   596 
       
   597     pRxXfer->uFwRxCntr = 0;
       
   598     pRxXfer->uDrvRxCntr = 0;
       
   599     pRxXfer->uAvailableTxn = MAX_CONSECUTIVE_READ_TXN - 1;
       
   600 
       
   601     /* Scan all transaction array and release only pending transaction */
       
   602     for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
       
   603     {
       
   604         pTxn = &(pRxXfer->aSlaveRegTxn[i].tTxnStruct);
       
   605         /* Check if buffer allocated and not the local one (signed by no callback) */
       
   606         if ((pTxn->hCbHandle != NULL) && (pTxn->aBuf[0] != 0))
       
   607         {
       
   608             RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pTxn->aBuf[0];
       
   609 
       
   610             WLAN_OS_REPORT (("RxXfer_ReStart: clean, in loop call RxQueue_ReceivePacket with TAG_CLASS_UNKNOWN\n"));
       
   611             /* Set TAG_CLASS_UNKNOWN and call upper layer only to release the allocated buffer */
       
   612             pRxParams->packet_class_tag = TAG_CLASS_UNKNOWN;
       
   613             RxQueue_ReceivePacket (pRxXfer->hRxQueue, (const void *)pTxn->aBuf[0]);
       
   614             pTxn->aBuf[0] = 0;
       
   615         }
       
   616     }
       
   617 
       
   618     for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
       
   619     {
       
   620         pTxn = &(pRxXfer->aSlaveRegTxn[i].tTxnStruct);
       
   621         TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
       
   622         BUILD_TTxnStruct(pTxn, SLV_REG_DATA, pRxXfer->aSlaveRegTxn[i].pRegData, REGISTER_SIZE*2, NULL, NULL)
       
   623 
       
   624         pTxn = &pRxXfer->aTxnStruct[i];
       
   625         TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_READ, TXN_FIXED_ADDR)
       
   626     }
       
   627 	
       
   628 } /* RxXfer_ReStart() */
       
   629 
       
   630 
       
   631 #ifdef TI_DBG
       
   632 /****************************************************************************
       
   633  *                      rxXfer_ClearStats()
       
   634  ****************************************************************************
       
   635  * DESCRIPTION: 
       
   636  *
       
   637  * INPUTS:  
       
   638  *          pRxXfer The object
       
   639  * 
       
   640  * OUTPUT:  None
       
   641  * 
       
   642  * RETURNS: TI_OK. 
       
   643  ****************************************************************************/
       
   644 void rxXfer_ClearStats (TI_HANDLE hRxXfer)
       
   645 {
       
   646     RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer;
       
   647 
       
   648     os_memoryZero (pRxXfer->hOs, &pRxXfer->DbgStats, sizeof(RxXferStats_T));
       
   649 }
       
   650 
       
   651 
       
   652 /****************************************************************************
       
   653  *                      rxXfer_PrintStats()
       
   654  ****************************************************************************
       
   655  * DESCRIPTION: .
       
   656  *
       
   657  * INPUTS:  
       
   658  *          pRxXfer The object
       
   659  * 
       
   660  * OUTPUT:  None
       
   661  * 
       
   662  * RETURNS: TI_OK. 
       
   663  ****************************************************************************/
       
   664 void rxXfer_PrintStats (TI_HANDLE hRxXfer)
       
   665 {
       
   666     RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer;
       
   667     
       
   668     WLAN_OS_REPORT(("Print RX Xfer module info\n"));
       
   669     WLAN_OS_REPORT(("=========================\n"));
       
   670     WLAN_OS_REPORT(("Rx counter   = 0x%x\n", pRxXfer->uFwRxCntr));
       
   671     WLAN_OS_REPORT(("Drv counter  = 0x%x\n", pRxXfer->uDrvRxCntr));
       
   672     WLAN_OS_REPORT(("Fw Counters  = 0x%x\n", pRxXfer->DbgStats.counters));
       
   673     WLAN_OS_REPORT(("AvailableTxn = 0x%x\n", pRxXfer->uAvailableTxn));
       
   674 }
       
   675 #endif
       
   676 
       
   677