Beispiel #1
0
static void RefillRecvBuffers(struct ar6k_hci_bridge_info      *pHcidevInfo, 
                              HCI_TRANSPORT_PACKET_TYPE Type, 
                              int                       NumBuffers)
{
    int                 length, i;
    void                *osBuf = NULL;
    struct htc_packet_queue    queue;
    struct htc_packet          *pPacket;

    INIT_HTC_PACKET_QUEUE(&queue);
    
    if (Type == HCI_ACL_TYPE) {     
        if (pHcidevInfo->HciNormalMode) {  
            length = HCI_MAX_FRAME_SIZE;
        } else {
            length = MAX_ACL_RECV_LENGTH;    
        }
    } else {
        length = MAX_EVT_RECV_LENGTH;
    }
    
        /* add on transport head and tail room */ 
    length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom;
        /* round up to the required I/O padding */      
    length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad);
             
    for (i = 0; i < NumBuffers; i++) {   
           
        if (pHcidevInfo->HciNormalMode) {   
            osBuf = bt_alloc_buffer(pHcidevInfo,length);       
        } else {
            osBuf = A_NETBUF_ALLOC(length);  
        }
          
        if (NULL == osBuf) {
            break;    
        }            
         
        pPacket = AllocHTCStruct(pHcidevInfo);
        if (NULL == pPacket) {
            FreeBtOsBuf(pHcidevInfo,osBuf);
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
            break;    
        }     
        
        SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type);
            /* add to queue */
        HTC_PACKET_ENQUEUE(&queue,pPacket);
    }
    
    if (i > 0) {
        HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);    
    }
}
Beispiel #2
0
/*  Custom_Api_Send - Entry point for MQX driver interface to send a packet.
 *	 This is specific to MQX. This function is NOT called from within the
 *	 driver.
 *      QCA_CONTEXT_STRUCT_PTR  qca_ptr - the MQX driver context.
 *		PCB_PTR              pcb_ptr - the MQX packet object.
 *		uint32_t              size - the length in bytes of pcb_ptr.
 *		uint32_t              frags - the number of fragments in pcb_ptr.
 *		uint32_t              flags - optional flags for transmit.
 *****************************************************************************/
uint32_t Custom_Api_Send(QCA_CONTEXT_STRUCT_PTR qca_ptr,
                         /* [IN] the Ethernet state structure */
                         PCB_PTR pcb_ptr,
                         /* [IN] the packet to send */
                         uint32_t size,
                         /* [IN] total size of the packet */
                         uint32_t frags,
                         /* [IN] total fragments in the packet */
                         uint32_t flags
                         /* [IN] optional flags, zero = default */
                         )
{
    uint32_t error = QCA_OK;
    A_NETBUF *a_netbuf_ptr;
    UNUSED_ARGUMENT(flags);
    UNUSED_ARGUMENT(size);
#if 0    
if(g_sampleTotAlloc != g_totAlloc){
	A_PRINTF("send alloc: %d\n", g_totAlloc);
	g_sampleTotAlloc = g_totAlloc;
}
#endif
    /* create an atheros pcb and continue or fail. */
    do
    {
        /* provide enough space in the top buffer to store the 14 byte
         * header which will be copied from its position in the original
         * buffer. this will allow wmi_dix_2_dot3() to function properly.
         */
        if ((a_netbuf_ptr = (A_NETBUF *)A_NETBUF_ALLOC(sizeof(ATH_MAC_HDR))) == NULL)
        {
            error = ENETERR_ALLOC_PCB;
            break;
        }

        a_netbuf_ptr->num_frags = (uint8_t)frags;
        /* HACK: copy the first part of the fragment to the new buf in order to allow
         * wmi_dix_2_dot3() to function properly. */
        A_ASSERT(pcb_ptr->FRAG[0].LENGTH >= sizeof(ATH_MAC_HDR));
        A_NETBUF_PUT_DATA(a_netbuf_ptr, (uint8_t *)pcb_ptr->FRAG[0].FRAGMENT, sizeof(ATH_MAC_HDR));
        /*(char*)pcb_ptr->FRAG[0].FRAGMENT += sizeof(ATH_MAC_HDR);*/
        pcb_ptr->FRAG[0].FRAGMENT = (uint8_t *)((uint32_t)pcb_ptr->FRAG[0].FRAGMENT + sizeof(ATH_MAC_HDR));
        pcb_ptr->FRAG[0].LENGTH -= sizeof(ATH_MAC_HDR);

        // ensure there is enough headroom to complete the tx operation
        if (A_NETBUF_HEADROOM(a_netbuf_ptr) <
            sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HDR_LENGTH + WMI_MAX_TX_META_SZ)
        {
            error = ENETERR_ALLOC_PCB;
            break;
        }
        // carry the original around until completion.
        // it is freed by A_NETBUF_FREE
        a_netbuf_ptr->native_orig = pcb_ptr;

        if (A_OK != Api_DataTxStart((void *)qca_ptr->MAC_CONTEXT_PTR, (void *)a_netbuf_ptr))
        {
            error = QCA_ERROR;
            break;
        }

    } while (0);

    if (error != QCA_OK)
    {
        /* in the event of api failure, the original pcb should be returned to the caller un-touched
         * and the a_netbuf_ptr should be freed */
        a_netbuf_ptr->native_orig = NULL;
        A_NETBUF_FREE((void *)a_netbuf_ptr);
    }

    return error;
}