예제 #1
0
static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data)
{
    struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
    struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
    struct queue_entry_priv_usb *entry_priv = entry->priv_data;
    int status;

    if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
            test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
        return false;

    rt2x00lib_dmastart(entry);

    usb_fill_bulk_urb(entry_priv->urb, usb_dev,
                      usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint),
                      entry->skb->data, entry->skb->len,
                      rt2x00usb_interrupt_rxdone, entry);

    status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
    if (status) {
        if (status == -ENODEV)
            clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
        set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
        rt2x00lib_dmadone(entry);
    }

    return false;
}
예제 #2
0
static void rt2x00usb_interrupt_txdone(struct urb *urb)
{
    struct queue_entry *entry = (struct queue_entry *)urb->context;
    struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;

    if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
        return;
    /*
     * Check if the frame was correctly uploaded
     */
    if (urb->status)
        set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
    /*
     * Report the frame as DMA done
     */
    rt2x00lib_dmadone(entry);

    if (rt2x00dev->ops->lib->tx_dma_done)
        rt2x00dev->ops->lib->tx_dma_done(entry);
    /*
     * Schedule the delayed work for reading the TX status
     * from the device.
     */
    if (!test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags) ||
            !kfifo_is_empty(&rt2x00dev->txstatus_fifo))
        queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
}
예제 #3
0
static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{
    struct queue_entry *entry = (struct queue_entry *)urb->context;
    struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;

    if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
        return;

    /*
     * Report the frame as DMA done
     */
    rt2x00lib_dmadone(entry);

    /*
     * Check if the received data is simply too small
     * to be actually valid, or if the urb is signaling
     * a problem.
     */
    if (urb->actual_length < entry->queue->desc_size || urb->status)
        set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);

    /*
     * Schedule the delayed work for reading the RX status
     * from the device.
     */
    queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work);
}
예제 #4
0
static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
{
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
	u32 length;

	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
		return;

	/*
	 * USB devices cannot blindly pass the skb->len as the
	 * length of the data to usb_fill_bulk_urb. Pass the skb
	 * to the driver to determine what the length should be.
	 */
	length = rt2x00dev->ops->lib->get_tx_data_len(entry);

	usb_fill_bulk_urb(entry_priv->urb, usb_dev,
			  usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
			  entry->skb->data, length,
			  rt2x00usb_interrupt_txdone, entry);

	if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
		rt2x00lib_dmadone(entry);
	}
}
예제 #5
0
static void rt2x00usb_interrupt_txdone(struct urb *urb)
{
	struct queue_entry *entry = (struct queue_entry *)urb->context;
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;

	if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
		return;

	/*
	 * Report the frame as DMA done
	 */
	rt2x00lib_dmadone(entry);

	/*
	 * Check if the frame was correctly uploaded
	 */
	if (urb->status)
		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);

	/*
	 * Schedule the delayed work for reading the TX status
	 * from the device.
	 */
	ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
}
예제 #6
0
파일: rt2x00usb.c 프로젝트: 513855417/linux
static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data)
{
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
	u32 length;
	int status;

	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
		return false;

	/*
	 * USB devices require certain padding at the end of each frame
	 * and urb. Those paddings are not included in skbs. Pass entry
	 * to the driver to determine what the overall length should be.
	 */
	length = rt2x00dev->ops->lib->get_tx_data_len(entry);

	status = skb_padto(entry->skb, length);
	if (unlikely(status)) {
		/* TODO: report something more appropriate than IO_FAILED. */
		rt2x00_warn(rt2x00dev, "TX SKB padding error, out of memory\n");
		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
		rt2x00lib_dmadone(entry);

		return false;
	}

	usb_fill_bulk_urb(entry_priv->urb, usb_dev,
			  usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
			  entry->skb->data, length,
			  rt2x00usb_interrupt_txdone, entry);

	usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor);
	status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
	if (status) {
		usb_unanchor_urb(entry_priv->urb);
		if (status == -ENODEV)
			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
		rt2x00lib_dmadone(entry);
	}

	return false;
}
예제 #7
0
/*
 * Device initialization handlers.
 */
void rt2x00usb_clear_entry(struct queue_entry *entry)
{
	struct usb_device *usb_dev =
	    to_usb_device_intf(entry->queue->rt2x00dev->dev);
	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
	int pipe;

	entry->flags = 0;

	if (entry->queue->qid == QID_RX) {
		pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint);
		usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe,
				entry->skb->data, entry->skb->len,
				rt2x00usb_interrupt_rxdone, entry);

		set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
		if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
			set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
			rt2x00lib_dmadone(entry);
		}
	}
}
예제 #8
0
bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
{
	struct data_queue *queue = rt2x00dev->rx;
	struct queue_entry *entry;
	struct queue_entry_priv_pci *entry_priv;
	struct skb_frame_desc *skbdesc;
	int max_rx = 16;

	while (--max_rx) {
		entry = rt2x00queue_get_entry(queue, Q_INDEX);
		entry_priv = entry->priv_data;

		if (rt2x00dev->ops->lib->get_entry_state(entry))
			break;

		/*
		 * Fill in desc fields of the skb descriptor
		 */
		skbdesc = get_skb_frame_desc(entry->skb);
		skbdesc->desc = entry_priv->desc;
		skbdesc->desc_len = entry->queue->desc_size;

		/*
		 * DMA is already done, notify rt2x00lib that
		 * it finished successfully.
		 */
		rt2x00lib_dmastart(entry);
		rt2x00lib_dmadone(entry);

		/*
		 * Send the frame to rt2x00lib for further processing.
		 */
		rt2x00lib_rxdone(entry);
	}

	return !max_rx;
}