示例#1
0
/**
 *  @brief This function sets up the data to receive
 *
 *  @param ctx		Pointer to urb_context structure
 *  @param size	        Skb size
 *
 *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
woal_usb_submit_rx_urb(urb_context * ctx, int size)
{
    moal_handle *handle = ctx->handle;
    struct usb_card_rec *cardp = (struct usb_card_rec *) handle->card;
    mlan_status ret = MLAN_STATUS_FAILURE;

    ENTER();

    if (cardp->rx_cmd_ep != ctx->ep) {
        if (!(ctx->pmbuf = woal_alloc_mlan_buffer(handle, size))) {
            PRINTM(MERROR, "Fail to submit Rx URB due to no memory/skb\n");
            goto rx_ret;
        }
    }
    ctx->pmbuf->data_offset = MLAN_NET_IP_ALIGN + MLAN_RX_HEADER_LEN;

    usb_fill_bulk_urb(ctx->urb, cardp->udev,
                      usb_rcvbulkpipe(cardp->udev, ctx->ep),
                      ctx->pmbuf->pbuf + ctx->pmbuf->data_offset,
                      size - ctx->pmbuf->data_offset, woal_usb_receive,
                      (void *) ctx);
    if (cardp->rx_cmd_ep == ctx->ep)
        atomic_inc(&cardp->rx_cmd_urb_pending);
    else
        atomic_inc(&cardp->rx_data_urb_pending);
    if (usb_submit_urb(ctx->urb, GFP_ATOMIC)) {
        /* Submit URB failure */
        PRINTM(MERROR, "Submit Rx URB failed: %d\n", ret);
        woal_free_mlan_buffer(handle, ctx->pmbuf);
        if (cardp->rx_cmd_ep == ctx->ep)
            atomic_dec(&cardp->rx_cmd_urb_pending);
        else
            atomic_dec(&cardp->rx_data_urb_pending);
        ctx->pmbuf = NULL;
        ret = MLAN_STATUS_FAILURE;
    } else {
        ret = MLAN_STATUS_SUCCESS;
    }
  rx_ret:
    LEAVE();
    return ret;
}
/**
 *  @brief This function sets up the data to receive
 *
 *  @param ctx		Pointer to urb_context structure
 *  @param size	        Skb size
 *
 *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
woal_usb_submit_rx_urb(urb_context * ctx, int size)
{
    moal_handle *handle = ctx->handle;
    struct usb_card_rec *cardp = (struct usb_card_rec *) handle->card;
    struct sk_buff *skb = NULL;
    mlan_status ret = MLAN_STATUS_FAILURE;

    ENTER();

    if (cardp->rx_cmd_ep != ctx->ep) {
        if (!(ctx->pmbuf = woal_alloc_mlan_buffer(size))) {
            PRINTM(ERROR, "No free skb\n");
            goto rx_ret;
        }
    }

    skb = (struct sk_buff *) ctx->pmbuf->pdesc;
    ctx->pmbuf->data_offset = MLAN_NET_IP_ALIGN;
    usb_fill_bulk_urb(ctx->urb, cardp->udev,
                      usb_rcvbulkpipe(cardp->udev, ctx->ep),
                      skb->tail + MLAN_NET_IP_ALIGN,
                      size - MLAN_NET_IP_ALIGN, woal_usb_receive, (void *) ctx);
    if (cardp->rx_cmd_ep == ctx->ep)
        atomic_inc(&cardp->rx_cmd_urb_pending);
    else
        atomic_inc(&cardp->rx_data_urb_pending);
    if ((ret = usb_submit_urb(ctx->urb, GFP_ATOMIC))) {
        /* Submit URB failure */
        PRINTM(ERROR, "Submit Rx URB failed: %d\n", ret);
        woal_free_mlan_buffer(ctx->pmbuf);
        if (cardp->rx_cmd_ep == ctx->ep)
            atomic_dec(&cardp->rx_cmd_urb_pending);
        else
            atomic_dec(&cardp->rx_data_urb_pending);
        ctx->pmbuf = NULL;
    } else {
        ret = MLAN_STATUS_SUCCESS;
    }
  rx_ret:
    LEAVE();
    return ret;
}
示例#3
0
/**
 * @brief This function receive packet of the data/cmd/event packet
 *         and pass to MLAN 
 *
 *  @param urb		Pointer to struct urb
 *
 *  @return 	   	N/A
 */
static void
woal_usb_receive(struct urb *urb)
#endif
{
    urb_context *context = (urb_context *) urb->context;
    moal_handle *handle = context->handle;
    mlan_buffer *pmbuf = context->pmbuf;
    struct usb_card_rec *cardp = NULL;
    int recv_length = urb->actual_length;
    int size;
    mlan_status status;

    ENTER();

    if (!handle || !handle->card) {
        PRINTM(MERROR, "moal handle or card structure is not valid\n");
        LEAVE();
        return;
    }
    cardp = (struct usb_card_rec *) handle->card;
    if (cardp->rx_cmd_ep == context->ep)
        atomic_dec(&cardp->rx_cmd_urb_pending);
    else
        atomic_dec(&cardp->rx_data_urb_pending);

    if (recv_length) {
        if (urb->status || (handle->surprise_removed == MTRUE)) {
            PRINTM(MERROR, "URB status is failed: %d\n", urb->status);
            /* Do not free mlan_buffer in case of command ep */
            if (cardp->rx_cmd_ep != context->ep)
                woal_free_mlan_buffer(handle, pmbuf);
            goto setup_for_next;
        }
        /* Send packet to MLAN */
        pmbuf->data_len = recv_length;
        atomic_inc(&handle->rx_pending);
        status = mlan_recv(handle->pmlan_adapter, pmbuf, context->ep);
        PRINTM(MINFO, "Receive length = 0x%x, status=%d\n", recv_length,
               status);
        if (status == MLAN_STATUS_PENDING) {
            queue_work(handle->workqueue, &handle->main_work);
            /* urb for data_ep is re-submitted now */
            /* urb for cmd_ep will be re-submitted in callback
               moal_recv_complete */
            if (cardp->rx_cmd_ep == context->ep)
                goto rx_exit;
        } else {
            atomic_dec(&handle->rx_pending);
            if (status == MLAN_STATUS_FAILURE)
                PRINTM(MERROR, "MLAN fail to process the receive data\n");
            /* Do not free mlan_buffer in case of command ep */
            if (cardp->rx_cmd_ep != context->ep)
                woal_free_mlan_buffer(handle, pmbuf);
        }
    } else if (urb->status) {
        if (!handle->is_suspended) {
            PRINTM(MMSG, "Card is removed: %d\n", urb->status);
            handle->surprise_removed = MTRUE;
        }
        woal_free_mlan_buffer(handle, pmbuf);
        context->pmbuf = NULL;
        goto rx_exit;
    } else {
        /* Do not free mlan_buffer in case of command ep */
        if (cardp->rx_cmd_ep != context->ep)
            woal_free_mlan_buffer(handle, pmbuf);
        goto setup_for_next;
    }
  setup_for_next:
    if (cardp->rx_cmd_ep == context->ep)
        size = MLAN_RX_CMD_BUF_SIZE;
    else
        size = MLAN_RX_DATA_BUF_SIZE;
    woal_usb_submit_rx_urb(context, size);
  rx_exit:

    LEAVE();
    return;
}