/**
 *  @brief This function initialize the rx URBs and submit them
 *
 *  @param handle 	Pointer to moal_handle structure
 *
 *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
woal_usb_rx_init(moal_handle * handle)
{
    struct usb_card_rec *cardp = (struct usb_card_rec *) handle->card;
    int i;
    mlan_status ret = MLAN_STATUS_SUCCESS;

    ENTER();

    cardp->rx_cmd.handle = handle;
    cardp->rx_cmd.ep = cardp->rx_cmd_ep;
    /* Allocate URB for command/event */
    if (!(cardp->rx_cmd.urb = usb_alloc_urb(0, GFP_ATOMIC))) {
        PRINTM(ERROR, "Rx command URB allocation failed\n");
        ret = MLAN_STATUS_FAILURE;
        goto init_exit;
    }

    if ((cardp->rx_cmd.pmbuf = woal_alloc_mlan_buffer(MLAN_RX_CMD_BUF_SIZE))) {
        /* Submit Rx command URB */
        if (woal_usb_submit_rx_urb(&cardp->rx_cmd, MLAN_RX_CMD_BUF_SIZE) < 0) {
            ret = MLAN_STATUS_FAILURE;
            goto init_exit;
        }
    }
    for (i = 0; i < MVUSB_RX_DATA_URB; i++) {
        cardp->rx_data_list[i].handle = handle;
        cardp->rx_data_list[i].ep = cardp->rx_data_ep;
        /* Allocate URB for data */
        if (!(cardp->rx_data_list[i].urb = usb_alloc_urb(0, GFP_ATOMIC))) {
            PRINTM(ERROR, "Rx data URB allocation failed\n");
            ret = MLAN_STATUS_FAILURE;
            goto init_exit;
        }
        /* Submit Rx data URB */
        if (woal_usb_submit_rx_urb
            (&cardp->rx_data_list[i], MLAN_RX_DATA_BUF_SIZE) < 0) {
            ret = MLAN_STATUS_FAILURE;
            goto init_exit;
        }
    }

  init_exit:
    LEAVE();
    return ret;
}
Example #2
0
/**
 *  @brief This function will submit rx urb.
 *
 *  @param handle   Pointer to moal_handle
 *  @param ep       Endpoint to re-submit urb
 *
 *  @return 	   	N/A
 */
void
woal_submit_rx_urb(moal_handle * handle, t_u8 ep)
{
    struct usb_card_rec *cardp = (struct usb_card_rec *) handle->card;

    ENTER();

    if ((ep == cardp->rx_cmd_ep) && (!atomic_read(&cardp->rx_cmd_urb_pending))) {
        woal_usb_submit_rx_urb(&cardp->rx_cmd, MLAN_RX_CMD_BUF_SIZE);
    }

    LEAVE();
    return;
}
Example #3
0
/**
 *  @brief This function submits the rx data URBs
 *
 *  @param handle 	Pointer to moal_handle structure
 *
 *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
woal_usb_submit_rx_data_urbs(moal_handle * handle)
{
    struct usb_card_rec *cardp = (struct usb_card_rec *) handle->card;
    int i;
    mlan_status ret = MLAN_STATUS_FAILURE;

    ENTER();

    for (i = 0; i < MVUSB_RX_DATA_URB; i++) {
        /* Submit Rx data URB */
        if (!cardp->rx_data_list[i].pmbuf) {
            if (woal_usb_submit_rx_urb
                (&cardp->rx_data_list[i], MLAN_RX_DATA_BUF_SIZE))
                continue;
        }
        ret = MLAN_STATUS_SUCCESS;
    }
    LEAVE();
    return ret;
}
Example #4
0
/**
 *  @brief Handle resume
 *
 *  @param intf		  Pointer to usb_interface
 *  
 *  @return 	   	  MLAN_STATUS_SUCCESS
 */
static int
woal_usb_resume(struct usb_interface *intf)
{
    struct usb_card_rec *cardp = usb_get_intfdata(intf);
    moal_handle *handle = NULL;
    int i;

    ENTER();

    if (!cardp || !cardp->phandle) {
        PRINTM(MERROR, "Card or adapter structure is not valid\n");
        LEAVE();
        return MLAN_STATUS_SUCCESS;
    }
    handle = cardp->phandle;

    if (handle->is_suspended == MFALSE) {
        PRINTM(MWARN, "Device already resumed\n");
        LEAVE();
        return MLAN_STATUS_SUCCESS;
    }

    /* Indicate device resumed. The netdev queue will be resumed only after
       the urbs have been resubmitted */
    handle->is_suspended = MFALSE;

    if (!atomic_read(&cardp->rx_data_urb_pending)) {
        /* Submit multiple Rx data URBs */
        woal_usb_submit_rx_data_urbs(handle);
    }
    if (!atomic_read(&cardp->rx_cmd_urb_pending)) {
        if ((cardp->rx_cmd.pmbuf =
             woal_alloc_mlan_buffer(handle, MLAN_RX_CMD_BUF_SIZE)))
            woal_usb_submit_rx_urb(&cardp->rx_cmd, MLAN_RX_CMD_BUF_SIZE);
    }

    for (i = 0; i < handle->priv_num; i++)
        if (handle->priv[i]->media_connected == MTRUE)
            netif_carrier_on(handle->priv[i]->netdev);

    /* Disable Host Sleep */
    if (handle->hs_activated)
        woal_cancel_hs(woal_get_priv(handle, MLAN_BSS_ROLE_ANY), MOAL_NO_WAIT);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
#ifdef CONFIG_PM
    /* Resume handler may be called due to remote wakeup, force to exit suspend 
       anyway */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
    cardp->udev->autosuspend_disabled = 1;
#else
    cardp->udev->dev.power.runtime_auto = 0;
#endif /* < 2.6.35 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
    cardp->udev->autoresume_disabled = 0;
#endif /* < 2.6.33 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
    atomic_inc(&(cardp->udev)->dev.power.usage_count);
#endif /* >= 2.6.34 */
#endif /* CONFIG_PM */
#endif /* >= 2.6.24 */

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Example #5
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;
}