skbdesc->desc_len = queue->desc_size;
skbdesc->entry = entry;
+ memcpy(&priv_tx->control, control, sizeof(priv_tx->control));
rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
/*
* advance.
*/
frame_size = queue->data_size + queue->desc_size;
- skb = dev_alloc_skb(frame_size + 2);
+ skb = dev_alloc_skb(queue->desc_size + frame_size + 2);
if (!skb)
return NULL;
- skb_reserve(skb, 2);
+ skb_reserve(skb, queue->desc_size + 2);
skb_put(skb, frame_size);
return skb;
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))
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
}
}
+ /*
+ * Kill guardian urb (if required by driver).
+ */
+ if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
+ return;
+
for (i = 0; i < rt2x00dev->bcn->limit; i++) {
priv_bcn = rt2x00dev->bcn->entries[i].priv_data;
usb_kill_urb(priv_bcn->urb);