Пример #1
0
void usb_hif_start_recv_pipes(HIF_DEVICE_USB *device)
{
	device->pipes[HIF_RX_DATA_PIPE].urb_cnt_thresh =
	    device->pipes[HIF_RX_DATA_PIPE].urb_alloc / 2;

	if (!htc_bundle_recv) {
		usb_hif_post_recv_transfers(&device->pipes[HIF_RX_DATA_PIPE],
					    HIF_USB_RX_BUFFER_SIZE);
	} else {
		usb_hif_post_recv_bundle_transfers(&device->pipes
					   [HIF_RX_DATA_PIPE],
					   HIF_USB_RX_BUNDLE_BUFFER_SIZE);
	}

	if (!hif_usb_disable_rxdata2) {
		device->pipes[HIF_RX_DATA2_PIPE].urb_cnt_thresh =
		    device->pipes[HIF_RX_DATA2_PIPE].urb_alloc / 2;
		usb_hif_post_recv_transfers(&device->pipes[HIF_RX_DATA2_PIPE],
					    HIF_USB_RX_BUFFER_SIZE);
	}
#ifdef USB_HIF_TEST_INTERRUPT_IN
	device->pipes[HIF_RX_INT_PIPE].urb_cnt_thresh =
	    device->pipes[HIF_RX_INT_PIPE].urb_alloc / 2;
	usb_hif_post_recv_transfers(&device->pipes[HIF_RX_INT_PIPE],
				    HIF_USB_RX_BUFFER_SIZE);
#endif
}
static int hif_usb_resume(struct usb_interface *interface)
{
	HIF_DEVICE_USB *device = usb_get_intfdata(interface);
	struct hif_usb_softc *sc = device->sc;
	void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
	v_VOID_t * temp_module;

	if (vos == NULL)
		return 0;
	/* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */
	temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos);
	if (!temp_module) {
		printk("%s: WDA module is NULL\n", __func__);
		return (-1);
	}

	if (wma_check_scan_in_progress(temp_module)) {
		printk("%s: Scan in progress. Aborting suspend\n", __func__);
		return (-1);
	}
	sc->local_state.event = 0;
	usb_hif_start_recv_pipes(device);

#ifdef USB_HIF_TEST_INTERRUPT_IN
	usb_hif_post_recv_transfers(&device->pipes[HIF_RX_INT_PIPE],
				    HIF_USB_RX_BUFFER_SIZE);
#endif
	/* No need to send WMI_PDEV_RESUME_CMDID to FW if WOW is enabled */
	if (!wma_is_wow_mode_selected(temp_module)) {
		wma_resume_target(temp_module, 0);
	} else if (wma_disable_wow_in_fw(temp_module, 0)) {
		pr_warn("%s[%d]: fail\n", __func__, __LINE__);
		return (-1);
	}

	return 0;
}
Пример #3
0
static void usb_hif_usb_recv_complete(struct urb *urb)
{
	HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context;
	A_STATUS status = A_OK;
	adf_nbuf_t buf = NULL;
	HIF_USB_PIPE *pipe = urb_context->pipe;

	AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, (
			 "+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p\n",
			 __func__,
			 pipe->logical_pipe_num,
			 urb->status, urb->actual_length,
			 urb));

	/* this urb is not pending anymore */
	usb_hif_remove_pending_transfer(urb_context);

	do {

		if (urb->status != 0) {
			status = A_ECOMM;
			switch (urb->status) {
#ifdef RX_SG_SUPPORT
			case -EOVERFLOW:
				urb->actual_length = HIF_USB_RX_BUFFER_SIZE;
				status = A_OK;
				break;
#endif
			case -ECONNRESET:
			case -ENOENT:
			case -ESHUTDOWN:
				/* NOTE: no need to spew these errors when
				 * device is removed
				 * or urb is killed due to driver shutdown
				 */
				status = A_ECANCELED;
				break;
			default:
				AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (
						 "%s recv pipe: %d (ep:0x%2.2X), failed:%d\n",
						 __func__,
						 pipe->logical_pipe_num,
						 pipe->ep_address,
						 urb->status));
				break;
			}
			break;
		}

		if (urb->actual_length == 0)
			break;

		buf = urb_context->buf;
		/* we are going to pass it up */
		urb_context->buf = NULL;
		adf_nbuf_put_tail(buf, urb->actual_length);
		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
			A_UINT8 *data;
			A_UINT32 len;
			adf_nbuf_peek_header(buf, &data, &len);
			DebugDumpBytes(data, len, "hif recv data");
		}

		/* note: queue implements a lock */
		skb_queue_tail(&pipe->io_comp_queue, buf);
		schedule_work(&pipe->io_complete_work);

	} while (FALSE);

	usb_hif_cleanup_recv_urb(urb_context);

	if (A_SUCCESS(status)) {
		if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
			/* our free urbs are piling up, post more transfers */
			usb_hif_post_recv_transfers(pipe,
						    HIF_USB_RX_BUFFER_SIZE);
		}
	}

	AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, ("-%s\n", __func__));
}