예제 #1
0
/*
 * RX data handlers.
 */
static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{
	struct queue_entry *entry = (struct queue_entry *)urb->context;
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
	u8 rxd[32];

	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
	    !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
		return;

	/*
	 * 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_OWNER_DEVICE_DATA, &entry->flags);
		usb_submit_urb(urb, GFP_ATOMIC);
		return;
	}

	/*
	 * Fill in desc fields of the skb descriptor
	 */
	skbdesc->desc = rxd;
	skbdesc->desc_len = entry->queue->desc_size;

	/*
	 * Send the frame to rt2x00lib for further processing.
	 */
	rt2x00lib_rxdone(rt2x00dev, entry);
}
예제 #2
0
/*
 * RX data handlers.
 */
static void rt2x00usb_work_rxdone(struct work_struct *work)
{
    struct rt2x00_dev *rt2x00dev =
        container_of(work, struct rt2x00_dev, rxdone_work);
    struct queue_entry *entry;
    struct skb_frame_desc *skbdesc;
    u8 rxd[32];

    while (!rt2x00queue_empty(rt2x00dev->rx)) {
        entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);

        if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
                !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
            break;

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

        /*
         * Send the frame to rt2x00lib for further processing.
         */
        rt2x00lib_rxdone(entry, GFP_KERNEL);
    }
}
예제 #3
0
void 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;

	while (1) {
		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;

		/*
		 * Send the frame to rt2x00lib for further processing.
		 */
		rt2x00lib_rxdone(entry);
	}
}
예제 #4
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;
	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
	u8 rxd[32];

	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
	    !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
		return;

	
	if (urb->actual_length < entry->queue->desc_size || urb->status) {
		set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
		usb_submit_urb(urb, GFP_ATOMIC);
		return;
	}

	
	skbdesc->desc = rxd;
	skbdesc->desc_len = entry->queue->desc_size;

	
	rt2x00lib_rxdone(rt2x00dev, entry);
}
예제 #5
0
void 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;

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

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

		
		skbdesc = get_skb_frame_desc(entry->skb);
		skbdesc->desc = entry_priv->desc;
		skbdesc->desc_len = entry->queue->desc_size;

		
		rt2x00lib_rxdone(rt2x00dev, entry);
	}
}
예제 #6
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;
}
예제 #7
0
파일: rt2x00usb.c 프로젝트: DINKIN/tuo
static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{
	struct queue_entry *entry = (struct queue_entry *)urb->context;
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct sk_buff *skb;
	struct skb_frame_desc *skbdesc;
	struct rxdone_entry_desc rxdesc;
	int header_size;

	if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
	    !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
		return;

	/*
	 * 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)
		goto skip_entry;

	/*
	 * Fill in skb descriptor
	 */
	skbdesc = get_skb_frame_desc(entry->skb);
	memset(skbdesc, 0, sizeof(*skbdesc));
	skbdesc->entry = entry;

	memset(&rxdesc, 0, sizeof(rxdesc));
	rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);

	/*
	 * The data behind the ieee80211 header must be
	 * aligned on a 4 byte boundary.
	 */
	header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
	if (header_size % 4 == 0) {
		skb_push(entry->skb, 2);
		memmove(entry->skb->data, entry->skb->data + 2,
			entry->skb->len - 2);
		skbdesc->data = entry->skb->data;
		skb_trim(entry->skb,entry->skb->len - 2);
	}

	/*
	 * Allocate a new sk buffer to replace the current one.
	 * If allocation fails, we should drop the current frame
	 * so we can recycle the existing sk buffer for the new frame.
	 */
	skb = rt2x00usb_alloc_rxskb(entry->queue);
	if (!skb)
		goto skip_entry;

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

	/*
	 * Replace current entry's skb with the newly allocated one,
	 * and reinitialize the urb.
	 */
	entry->skb = skb;
	urb->transfer_buffer = entry->skb->data;
	urb->transfer_buffer_length = entry->skb->len;

skip_entry:
	if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) {
		__set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
		usb_submit_urb(urb, GFP_ATOMIC);
	}

	rt2x00queue_index_inc(entry->queue, Q_INDEX);
}