atheros_wifi/custom_src/stack_custom/cust_api_stack_txrx.c
A_STATUS custom_receive_tcpip(QOSAL_VOID *pCxt, QOSAL_VOID *pReq)
{
    A_NETBUF* a_netbuf_ptr = (A_NETBUF*)pReq;	
    QOSAL_INT32 index = 0, handle=0;
    QOSAL_UINT8* data;
    SOCKET_CONTEXT_PTR pcustctxt = NULL;

    if(a_netbuf_ptr) {        
  	
		data = (QOSAL_UINT8*)A_NETBUF_DATA(a_netbuf_ptr);
	
    	/*Extract socket handle from custom header*/
    	handle = A_CPU2LE32(*((QOSAL_UINT32*)data));
    	
    	/*Get index*/
    	index = find_socket_context(handle, TRUE);
	if(index < 0 || index > MAX_SOCKETS_SUPPORTED)
	{
		last_driver_error = A_SOCKCXT_NOT_FOUND;
		A_NETBUF_FREE(pReq);
		return A_ERROR;
	}

        if(custom_sock_is_pending(ath_sock_context[index]) != 0){
            /* socket is pending a socket event so it cannot 
             * receive data packets */
            last_driver_error = A_SOCK_UNAVAILABLE;
            A_NETBUF_FREE(pReq);
            return A_ERROR;
        }
						
		UNBLOCK_SELECT(pCxt);
		pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]);

		//if(!IS_SOCKET_BLOCKED(ath_sock_context[index]))
		/*To-Do- Remove this once drop ligic is implemented in firmware*/ 
              /* For Mutiple Socket TCP Rx , there is a limitaion. In tcp rx , once tcp connection is established, fw will recevie data and send to host 
                *  without considering host have enough buffer or blocked.
                * if host buffers are all occupied by rx data from fw sometime, the tcp accept wmi event will be blocked in the driver layer.
                * and the api_accept will be blocked which will cause app layer qcom_recv can't  extract data from buffer and free buffer.
                * this lead deadlock . so we reserve one buffer for mutiple socket RX. This handle will solve the deadlock issue and also may lead
                * some pakcet dropped.
                */		
           /*more than 2 different socket has data that be buffered, be different origianl two single traffic */
	 if(get_holding_buffer()>= 2)	
		{
		   if(get_total_pkts_buffered() >= BSP_CONFIG_ATHEROS_PCB - 1)
		   	{
		   	   A_PRINTF("%s dropping packets for %x\n", __FUNCTION__, handle);
			   A_NETBUF_FREE(pReq);
		   	}else
		     {
			   A_NETBUF_ENQUEUE(&(pcustctxt->rxqueue), a_netbuf_ptr);
			   UNBLOCK(ath_sock_context[index], RX_DIRECTION);  
		     }	   
		}
		else 
		{
		  if(get_total_pkts_buffered() >= BSP_CONFIG_ATHEROS_PCB )
		  {
			A_PRINTF("%s dropping packets for %x\n", __FUNCTION__, handle);
			A_NETBUF_FREE(pReq);
		  }else
		   {
			A_NETBUF_ENQUEUE(&(pcustctxt->rxqueue), a_netbuf_ptr);
			UNBLOCK(ath_sock_context[index], RX_DIRECTION);  
		   }
		   
		}

    }
    return A_OK;
}
/*****************************************************************************/
/*  custom_receive_tcpip - Called by Custom_DeliverFrameToNetworkStack to 
 *   deliver a data frame to the application thread. It unblocks a waiting 
 *   application thread and queues the packet in the queue of the corresponding 
 *   socket. If socket is not valid, the packet is dropped.
 *      QOSAL_VOID *pCxt - the driver context. 
 *      QOSAL_VOID *pReq - the packet.
 *****************************************************************************/
Called by Custom_DeliverFrameToNetworkStack to
deliver a data frame to the application thread. It unblocks a waiting
application thread and queues the packet in the queue of the corresponding
socket. If socket is not valid, the packet is dropped.
QOSAL_VOID *pCxt - the driver context.
QOSAL_VOID *pReq - the packet.
Called by Custom_DeliverFrameToNetworkStack to deliver a data frame to the application thread . It unblocks a waiting application thread and queues the packet in the queue of the corresponding socket . If socket is not valid the packet is dropped . QOSAL_VOID * pCxt - the driver context . QOSAL_VOID * pReq - the packet .
A_STATUS custom_receive_tcpip(QOSAL_VOID *pCxt, QOSAL_VOID *pReq)
{
    A_NETBUF* a_netbuf_ptr = (A_NETBUF*)pReq;	
    QOSAL_INT32 index = 0, handle=0;
    QOSAL_UINT8* data;
    SOCKET_CONTEXT_PTR pcustctxt = NULL;
    if(a_netbuf_ptr) {        
		data = (QOSAL_UINT8*)A_NETBUF_DATA(a_netbuf_ptr);
    	handle = A_CPU2LE32(*((QOSAL_UINT32*)data));
    	index = find_socket_context(handle, TRUE);
	if(index < 0 || index > MAX_SOCKETS_SUPPORTED)
	{
		last_driver_error = A_SOCKCXT_NOT_FOUND;
		A_NETBUF_FREE(pReq);
		return A_ERROR;
	}
        if(custom_sock_is_pending(ath_sock_context[index]) != 0){
            last_driver_error = A_SOCK_UNAVAILABLE;
            A_NETBUF_FREE(pReq);
            return A_ERROR;
        }
		UNBLOCK_SELECT(pCxt);
		pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]);
	 if(get_holding_buffer()>= 2)	
		{
		   if(get_total_pkts_buffered() >= BSP_CONFIG_ATHEROS_PCB - 1)
		   	{
		   	   A_PRINTF("%s dropping packets for %x\n", __FUNCTION__, handle);
			   A_NETBUF_FREE(pReq);
		   	}else
		     {
			   A_NETBUF_ENQUEUE(&(pcustctxt->rxqueue), a_netbuf_ptr);
			   UNBLOCK(ath_sock_context[index], RX_DIRECTION);  
		     }	   
		}
		else 
		{
		  if(get_total_pkts_buffered() >= BSP_CONFIG_ATHEROS_PCB )
		  {
			A_PRINTF("%s dropping packets for %x\n", __FUNCTION__, handle);
			A_NETBUF_FREE(pReq);
		  }else
		   {
			A_NETBUF_ENQUEUE(&(pcustctxt->rxqueue), a_netbuf_ptr);
			UNBLOCK(ath_sock_context[index], RX_DIRECTION);  
		   }
		}
    }
    return A_OK;
}
A_STATUS custom_receive_tcpip ( QOSAL_VOID * pCxt , QOSAL_VOID * pReq ) { A_NETBUF * a_netbuf_ptr = ( A_NETBUF * ) pReq ; QOSAL_INT32 index = 0 , handle = 0 ; QOSAL_UINT8 * data ; SOCKET_CONTEXT_PTR pcustctxt = NULL ; if ( a_netbuf_ptr ) { data = ( QOSAL_UINT8 * ) A_NETBUF_DATA ( a_netbuf_ptr ) ; handle = A_CPU2LE32 ( * ( ( QOSAL_UINT32 * ) data ) ) ; index = find_socket_context ( handle , TRUE ) ; if ( index < 0 || index > MAX_SOCKETS_SUPPORTED ) { last_driver_error = A_SOCKCXT_NOT_FOUND ; A_NETBUF_FREE ( pReq ) ; return A_ERROR ; } if ( custom_sock_is_pending ( ath_sock_context [ index ] ) != 0 ) { last_driver_error = A_SOCK_UNAVAILABLE ; A_NETBUF_FREE ( pReq ) ; return A_ERROR ; } UNBLOCK_SELECT ( pCxt ) ; pcustctxt = GET_SOCKET_CONTEXT ( ath_sock_context [ index ] ) ; if ( get_holding_buffer ( ) >= 2 ) { if ( get_total_pkts_buffered ( ) >= BSP_CONFIG_ATHEROS_PCB - 1 ) { A_PRINTF ( " \n " , __FUNCTION__ , handle ) ; A_NETBUF_FREE ( pReq ) ; } else { A_NETBUF_ENQUEUE ( & ( pcustctxt -> rxqueue ) , a_netbuf_ptr ) ; UNBLOCK ( ath_sock_context [ index ] , RX_DIRECTION ) ; } } else { if ( get_total_pkts_buffered ( ) >= BSP_CONFIG_ATHEROS_PCB ) { A_PRINTF ( " \n " , __FUNCTION__ , handle ) ; A_NETBUF_FREE ( pReq ) ; } else { A_NETBUF_ENQUEUE ( & ( pcustctxt -> rxqueue ) , a_netbuf_ptr ) ; UNBLOCK ( ath_sock_context [ index ] , RX_DIRECTION ) ; } } } return A_OK ; }
custom_receive_tcpip - Called by Custom_DeliverFrameToNetworkStack to
   deliver a data frame to the application thread.
custom_receive_tcpip - Called by Custom_DeliverFrameToNetworkStack to deliver a data frame to the application thread .
/*Extract socket handle from custom header*/ /*Get index*/ /* socket is pending a socket event so it cannot 
             * receive data packets */ //if(!IS_SOCKET_BLOCKED(ath_sock_context[index])) /*To-Do- Remove this once drop ligic is implemented in firmware*/ /* For Mutiple Socket TCP Rx , there is a limitaion. In tcp rx , once tcp connection is established, fw will recevie data and send to host 
                *  without considering host have enough buffer or blocked.
                * if host buffers are all occupied by rx data from fw sometime, the tcp accept wmi event will be blocked in the driver layer.
                * and the api_accept will be blocked which will cause app layer qcom_recv can't  extract data from buffer and free buffer.
                * this lead deadlock . so we reserve one buffer for mutiple socket RX. This handle will solve the deadlock issue and also may lead
                * some pakcet dropped.
                */ /*more than 2 different socket has data that be buffered, be different origianl two single traffic */