Exemplo n.º 1
0
void HTCFlushRxHoldQueue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint)
{
    HTC_PACKET       *pPacket;
    HTC_PACKET_QUEUE container;

    LOCK_HTC_RX(target);

    while (1) {
        pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBufferHoldQueue);
        if (NULL == pPacket) {
            break;
        }
        UNLOCK_HTC_RX(target);
        pPacket->Status = A_ECANCELED;
        pPacket->ActualLength = 0;
        AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("  Flushing RX packet:%p, length:%d, ep:%d \n",
                pPacket, pPacket->BufferLength, pPacket->Endpoint));
        INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
            /* give the packet back */
        DoRecvCompletion(pEndpoint,&container);
        LOCK_HTC_RX(target);
    }

    UNLOCK_HTC_RX(target);
}
Exemplo n.º 2
0
static void DoRecvCompletion(HTC_ENDPOINT     *pEndpoint,
                             HTC_PACKET_QUEUE *pQueueToIndicate)
{

    do {

        if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
                /* nothing to indicate */
            break;
        }

        if (pEndpoint->EpCallBacks.EpRecvPktMultiple != NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d, recv multiple callback (%d pkts) \n",
                     pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
                /* a recv multiple handler is being used, pass the queue to the handler */
            pEndpoint->EpCallBacks.EpRecvPktMultiple(pEndpoint->EpCallBacks.pContext,
                                                     pQueueToIndicate);
            INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
        } else {
            HTC_PACKET *pPacket;
            /* using legacy EpRecv */
            while (!HTC_QUEUE_EMPTY(pQueueToIndicate)) {
                pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
                AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d recv callback on packet %p \n",
                        pEndpoint->Id, pPacket));
                pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket);
            }
        }

    } while (FALSE);

}
Exemplo n.º 3
0
static void HTCFlushEndpointRX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint)
{
    HTC_PACKET  *pPacket;

    LOCK_HTC_RX(target);

    while (1) {
        pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
        if (NULL == pPacket) {
            break;
        }
        UNLOCK_HTC_RX(target);
        pPacket->Status = A_ECANCELED;
        pPacket->ActualLength = 0;
        AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("  Flushing RX packet:0x%X, length:%d, ep:%d \n",
                (A_UINT32)pPacket, pPacket->BufferLength, pPacket->Endpoint));
            /* give the packet back */
        pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext,
                                      pPacket);
        LOCK_HTC_RX(target);
    }

    UNLOCK_HTC_RX(target);


}
Exemplo n.º 4
0
static struct htc_packet * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo)
{
    struct htc_packet  *pPacket = NULL;
    LOCK_BRIDGE(pHcidevInfo);
    pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
    UNLOCK_BRIDGE(pHcidevInfo);  
    return pPacket;
}
static HTC_PACKET * AllocHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
{
    HTC_PACKET  *pPacket = NULL;
    LOCK_BRIDGE(pHcidevInfo);
    pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
    UNLOCK_BRIDGE(pHcidevInfo);  
    return pPacket;
}
Exemplo n.º 6
0
HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev)
{
    HTC_PACKET *pPacket;

    LOCK_AR6K(pDev);
    pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList);
    UNLOCK_AR6K(pDev);

    return pPacket;
}
Exemplo n.º 7
0
HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target,  HTC_PACKET_QUEUE *pList)
{
    HTC_PACKET *pPacket;

    LOCK_HTC(target);
    pPacket = HTC_PACKET_DEQUEUE(pList);
    UNLOCK_HTC(target);

    return pPacket;
}
Exemplo n.º 8
0
struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev)
{
    struct htc_packet *pPacket;

    LOCK_AR6K(pDev);
    pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList);
    UNLOCK_AR6K(pDev);

    return pPacket;
}
Exemplo n.º 9
0
Arquivo: htc.c Projeto: KHATEEBNSIT/AP
HTC_PACKET *HTCAllocControlTxPacket(HTC_TARGET *target)
{
#ifdef TODO_FIXME
    HTC_PACKET *pPacket;

    LOCK_HTC(target);
    pPacket = HTC_PACKET_DEQUEUE(&target->ControlBufferTXFreeList);
    UNLOCK_HTC(target);

    return pPacket;
#else
    return BuildHTCTxCtrlPacket(target->osdev);
#endif
}
   /*
   * Call netif_stop_queue frequently will impact the mboxping tx t-put.
   * Return HTC_SEND_FULL_KEEP directly in epping_tx_queue_full to avoid.
   */
   return HTC_SEND_FULL_KEEP;
}
#endif /* HIF_SDIO */
void epping_tx_complete_multiple(void *ctx,
   HTC_PACKET_QUEUE *pPacketQueue)
{
   epping_context_t *pEpping_ctx = (epping_context_t *)ctx;
   epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter;
   struct net_device* dev = pAdapter->dev;
   A_STATUS status;
   HTC_ENDPOINT_ID eid;
   adf_nbuf_t pktSkb;
   struct epping_cookie *cookie;
   A_BOOL flushing = FALSE;
   adf_nbuf_queue_t skb_queue;
   HTC_PACKET *htc_pkt;

   adf_nbuf_queue_init(&skb_queue);

   adf_os_spin_lock_bh(&pAdapter->data_lock);

   while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
      htc_pkt = HTC_PACKET_DEQUEUE(pPacketQueue);
      if (htc_pkt == NULL)
         break;
      status=htc_pkt->Status;
      eid=htc_pkt->Endpoint;
      pktSkb=GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
      cookie = htc_pkt->pPktContext;

      if (!pktSkb) {
         EPPING_LOG(VOS_TRACE_LEVEL_ERROR,
            "%s: pktSkb is NULL", __func__);
         ASSERT(0);
      } else {
         if (htc_pkt->pBuffer != adf_nbuf_data(pktSkb)) {
            EPPING_LOG(VOS_TRACE_LEVEL_ERROR,
               "%s: htc_pkt buffer not equal to skb->data", __func__);
            ASSERT(0);
         }

         /* add this to the list, use faster non-lock API */
         adf_nbuf_queue_add(&skb_queue,pktSkb);

         if (A_SUCCESS(status))
            if (htc_pkt->ActualLength != adf_nbuf_len(pktSkb)) {
               EPPING_LOG(VOS_TRACE_LEVEL_ERROR,
                  "%s: htc_pkt length not equal to skb->len", __func__);
               ASSERT(0);
            }
      }

      EPPING_LOG(VOS_TRACE_LEVEL_INFO,
         "%s skb=%p data=%p len=0x%x eid=%d ",
         __func__, pktSkb, htc_pkt->pBuffer,
         htc_pkt->ActualLength, eid);

      if (A_FAILED(status)) {
         if (status == A_ECANCELED) {
            /* a packet was flushed  */
            flushing = TRUE;
         }
         if (status != A_NO_RESOURCE) {
            printk("%s() -TX ERROR, status: 0x%x\n", __func__,
               status);
         }
      } else {
         EPPING_LOG(VOS_TRACE_LEVEL_INFO, "%s: OK\n", __func__);
         flushing = FALSE;
      }

      epping_free_cookie(pAdapter->pEpping_ctx, cookie);
   }

   adf_os_spin_unlock_bh(&pAdapter->data_lock);

   /* free all skbs in our local list */
   while (adf_nbuf_queue_len(&skb_queue)) {
      /* use non-lock version */
      pktSkb = adf_nbuf_queue_remove(&skb_queue);
      if (pktSkb == NULL)
         break;
      adf_nbuf_tx_free(pktSkb, ADF_NBUF_PKT_ERROR);
      pEpping_ctx->total_tx_acks++;
   }

   if (!flushing) {
      netif_wake_queue(dev);
   }
}
Exemplo n.º 11
0
/* callback when device layer or lookahead report parsing detects a pending message */
A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 *LookAhead, A_BOOL *pAsyncProc)
{
    HTC_TARGET      *target = (HTC_TARGET *)Context;
    A_STATUS         status = A_OK;
    HTC_PACKET      *pPacket = NULL;
    HTC_FRAME_HDR   *pHdr = NULL;
    HTC_ENDPOINT    *pEndpoint = NULL;
    A_BOOL          asyncProc = FALSE;

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCRecvMessagePendingHandler LookAhead:0x%X \n", *LookAhead));
    
    if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(&target->Device)) {
            /* We use async mode to get the packets if the device layer supports it.
             * The device layer interfaces with HIF in which HIF may have restrictions on
             * how interrupts are processed */
        asyncProc = TRUE;
    }

    if (pAsyncProc != NULL) {
            /* indicate to caller how we decided to process this */
        *pAsyncProc = asyncProc;
    }

    while (TRUE) {
        pHdr = (HTC_FRAME_HDR *)LookAhead;

        if (pHdr->EndpointID >= ENDPOINT_MAX) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID));
                /* invalid endpoint */
            status = A_EPROTO;
            break;
        }

        if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Payload length %d exceeds max HTC : %d !\n",
                    pHdr->PayloadLen, HTC_MAX_PAYLOAD_LENGTH));
            status = A_EPROTO;
            break;
        }

        pEndpoint = &target->EndPoint[pHdr->EndpointID];

        if (0 == pEndpoint->ServiceID) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Endpoint %d is not connected !\n",pHdr->EndpointID));
                /* endpoint isn't even connected */
            status = A_EPROTO;
            break;
        }

        if (pEndpoint->EpCallBacks.EpRecvAlloc != NULL) {
                /* user is using a per-packet allocation callback */
            pPacket = pEndpoint->EpCallBacks.EpRecvAlloc(pEndpoint->EpCallBacks.pContext,
                                                         (HTC_ENDPOINT_ID) pHdr->EndpointID,
                                                         pHdr->PayloadLen + sizeof(HTC_FRAME_HDR));

                /* lock RX, in case this allocation fails, we need to update internal state below */

            LOCK_HTC_RX(target);

        } else {
                /* user is using a refill handler that can refill multiple HTC buffers */
                /* lock RX to get a buffer */
            LOCK_HTC_RX(target);

                /* get a packet from the endpoint recv queue */
            pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);

            if (NULL == pPacket) {
                    /* check for refill handler */
                if (pEndpoint->EpCallBacks.EpRecvRefill != NULL) {
                    UNLOCK_HTC_RX(target);
                        /* call the re-fill handler */
                    pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
                                                        (HTC_ENDPOINT_ID) pHdr->EndpointID);
                    LOCK_HTC_RX(target);
                        /* check if we have more buffers */
                    pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
                        /* fall through */
                }
            }
        }

        if (NULL == pPacket) {
                /* this is not an error, we simply need to mark that we are waiting for buffers.*/
            target->HTCStateFlags |= HTC_STATE_WAIT_BUFFERS;
            target->EpWaitingForBuffers = (HTC_ENDPOINT_ID) pHdr->EndpointID;
            status = A_NO_MEMORY;
        }

        if (HTC_STOPPING(target)) {
            status = A_ECANCELED;
        }

        UNLOCK_HTC_RX(target);

        if (A_FAILED(status)) {
            /* no buffers or stopping */
            break;
        }

        pPacket->PktInfo.AsRx.IndicationFlags = 0;

        AR_DEBUG_ASSERT(pPacket->Endpoint == pHdr->EndpointID);

            /* make sure this message can fit in the endpoint buffer */
        if ((pHdr->PayloadLen + HTC_HDR_LENGTH) > pPacket->BufferLength) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    ("Payload Length Error : header reports payload of: %d, endpoint buffer size: %d \n",
                    pHdr->PayloadLen, pPacket->BufferLength));
            status = A_EPROTO;
            break;
        }

        pPacket->HTCReserved = *LookAhead; /* set expected look ahead */
            /* set the amount of data to fetch */
        pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;

        if (asyncProc) {
                /* we use async mode to get the packet if the device layer supports it
                 * set our callback and context */
            pPacket->Completion = HTCRecvCompleteHandler;
            pPacket->pContext = target;
        } else {
                /* fully synchronous */
            pPacket->Completion = NULL;
        }

            /* go fetch the packet */
        status = HTCIssueRecv(target, pPacket);

        if (A_FAILED(status)) {
            break;
        }

        if (asyncProc) {
                /* we did this asynchronously so we can get out of the loop, the asynch processing
                 * creates a chain of requests to continue processing pending messages in the
                 * context of callbacks  */
            break;
        }

            /* in the sync case, we process the packet, check lookaheads and then repeat */

        *LookAhead = 0;
        status = HTCProcessRecvHeader(target,pPacket,LookAhead);

        if (A_FAILED(status)) {
            break;
        }

        HTC_RX_STAT_PROFILE(target,pEndpoint,*LookAhead);

            /* check lookahead to see if we can indicate next packet hint to recv callback */
        if (LookAhead != 0) {
            pHdr = (HTC_FRAME_HDR *)&LookAhead;
                /* check to see if the "next" packet is from the same endpoint of the
                   completing packet */
            if (pHdr->EndpointID == pPacket->Endpoint) {
                    /* check that there is a buffer available to actually fetch it
                     * NOTE: no need to lock RX here , since we are synchronously processing RX
                     * and we are only looking at the queue (not modifying it) */
                if (!HTC_QUEUE_EMPTY(&pEndpoint->RxBuffers)) {                        
                        /* provide a hint that there are more RX packets to fetch */
                    pPacket->PktInfo.AsRx.IndicationFlags |= HTC_RX_FLAGS_INDICATE_MORE_PKTS;        
                }             
            }                  
        }
        
        DO_RCV_COMPLETION(target,pPacket,pEndpoint);

        pPacket = NULL;

        if (0 == *LookAhead) {
            break;
        }

        /* check whether other OS contexts have queued any WMI command/data for WLAN. 
         * This check is needed only if WLAN Tx and Rx happens in same thread context */
        A_CHECK_DRV_TX();
    }

    if (A_NO_MEMORY == status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" Endpoint :%d has no buffers, blocking receiver to prevent overrun.. \n",
                (pHdr != NULL) ? pHdr->EndpointID : 0xFFFF));
            /* try to stop receive at the device layer */
        DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
        status = A_OK;
    } else if (A_FAILED(status)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                        ("Failed to get pending message : LookAhead Value: 0x%X (status = %d) \n",
                        *LookAhead, status));
        if (pPacket != NULL) {
                /* clean up packet on error */
            HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
        }
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCRecvMessagePendingHandler \n"));

    return status;
}