rt2x00: Split rt2x00lib_write_tx_desc()
authorIvo van Doorn <ivdoorn@gmail.com>
Sat, 10 May 2008 11:46:13 +0000 (13:46 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 22 May 2008 01:47:34 +0000 (21:47 -0400)
Split rt2x00lib_write_tx_desc() up into a TX descriptor initializor
and TX descriptor writer.

This split is required to properly allow mac80211 to move its
tx_control structure into the skb->cb array.
The rt2x00queue_create_tx_descriptor() function will read all tx control
information and convert it into a rt2x00 TX descriptor information structure.
After that function is complete, we have all information we needed from the
tx control structure and are free to start writing into the skb->cb array
for our own purposes.
rt2x00queue_write_tx_descriptor() will be in charge of really sending
the TX descriptor to the hardware and kicking the TX queue.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c

index 2c0cf394c78ebd8424369858c88ecc26f9fc7507..d3d9b189fd831b0a48fde257d48a98a5b44fd417 100644 (file)
@@ -1492,12 +1492,21 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        struct rt2x00_intf *intf = vif_to_intf(control->vif);
        struct queue_entry_priv_pci_tx *priv_tx;
        struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
        u32 reg;
 
        if (unlikely(!intf->beacon))
                return -ENOBUFS;
        priv_tx = intf->beacon->priv_data;
 
+       /*
+        * Copy all TX descriptor information into txdesc,
+        * after that we are free to use the skb->cb array
+        * for our information.
+        */
+       intf->beacon->skb = skb;
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+
        /*
         * Fill in skb descriptor
         */
@@ -1525,8 +1534,8 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * Write entire beacon with descriptor to register,
         * and kick the beacon generator.
         */
-       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
        memcpy(priv_tx->data, skb->data, skb->len);
+       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
        rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
 
        return 0;
index 6c31c5db0ca17a999b21a7943ca046d10ccaef17..7de7980738f1f6f77dc974feb65bfc425f9bb698 100644 (file)
@@ -1808,6 +1808,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        struct rt2x00_intf *intf = vif_to_intf(control->vif);
        struct queue_entry_priv_pci_tx *priv_tx;
        struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
        u32 reg;
 
        if (unlikely(!intf->beacon))
@@ -1815,6 +1816,14 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 
        priv_tx = intf->beacon->priv_data;
 
+       /*
+        * Copy all TX descriptor information into txdesc,
+        * after that we are free to use the skb->cb array
+        * for our information.
+        */
+       intf->beacon->skb = skb;
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+
        /*
         * Fill in skb descriptor
         */
@@ -1842,8 +1851,8 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * Write entire beacon with descriptor to register,
         * and kick the beacon generator.
         */
-       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
        memcpy(priv_tx->data, skb->data, skb->len);
+       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
        rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
 
        return 0;
index 3be4c7ea8dd115ccc56af26dc840669a634409ce..6fe713a1d758b55d9fc308395a9d505412df24b8 100644 (file)
@@ -1676,6 +1676,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
        struct rt2x00_intf *intf = vif_to_intf(control->vif);
        struct queue_entry_priv_usb_bcn *priv_bcn;
        struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
        int pipe = usb_sndbulkpipe(usb_dev, 1);
        int length;
        u16 reg;
@@ -1685,6 +1686,14 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
 
        priv_bcn = intf->beacon->priv_data;
 
+       /*
+        * Copy all TX descriptor information into txdesc,
+        * after that we are free to use the skb->cb array
+        * for our information.
+        */
+       intf->beacon->skb = skb;
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+
        /*
         * Add the descriptor in front of the skb.
         */
@@ -1713,7 +1722,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
        rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
 
-       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
+       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
 
        /*
         * USB devices cannot blindly pass the skb->len as the
index 6f7b34fac16c275aa90b329253fc6580fd5117db..9c186d79c11c082bdf55d930bf5e27bbd2ec944a 100644 (file)
@@ -926,6 +926,41 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate)
        return ((size * 8 * 10) % rate);
 }
 
+/**
+ * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input
+ * @entry: The entry which will be used to transfer the TX frame.
+ * @txdesc: rt2x00 TX descriptor which will be initialized by this function.
+ * @control: mac80211 TX control structure from where we read the information.
+ *
+ * This function will initialize the &struct txentry_desc based on information
+ * from mac80211. This descriptor can then be used by rt2x00lib and the drivers
+ * to correctly initialize the hardware descriptor.
+ * Note that before calling this function the skb->cb array must be untouched
+ * by rt2x00lib. Only after this function completes will it be save to
+ * overwrite the skb->cb information.
+ * The reason for this is that mac80211 writes its own tx information into
+ * the skb->cb array, and this function will use that information to initialize
+ * the &struct txentry_desc structure.
+ */
+void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
+                                     struct txentry_desc *txdesc,
+                                     struct ieee80211_tx_control *control);
+
+/**
+ * rt2x00queue_write_tx_descriptor - Write TX descriptor to hardware
+ * @entry: The entry which will be used to transfer the TX frame.
+ * @txdesc: TX descriptor which will be used to write hardware descriptor
+ *
+ * This function will write a TX descriptor initialized by
+ * &rt2x00queue_create_tx_descriptor to the hardware. After this call
+ * has completed the frame is now owned by the hardware, the hardware
+ * queue will have automatically be kicked unless this frame was generated
+ * by rt2x00lib, in which case the frame is "special" and must be kicked
+ * by the caller.
+ */
+void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
+                                    struct txentry_desc *txdesc);
+
 /**
  * rt2x00queue_get_queue - Convert queue index to queue pointer
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
@@ -963,13 +998,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 void rt2x00lib_rxdone(struct queue_entry *entry,
                      struct rxdone_entry_desc *rxdesc);
 
-/*
- * TX descriptor initializer
- */
-void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                            struct sk_buff *skb,
-                            struct ieee80211_tx_control *control);
-
 /*
  * mac80211 handlers.
  */
index 46c377873f163ac2af548213b5509008ae514904..171f445962dbd21178d4ef9b32d3e01b6c4c6abf 100644 (file)
@@ -611,154 +611,6 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
 
-/*
- * TX descriptor initializer
- */
-void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                            struct sk_buff *skb,
-                            struct ieee80211_tx_control *control)
-{
-       struct txentry_desc txdesc;
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skbdesc->data;
-       const struct rt2x00_rate *rate;
-       int tx_rate;
-       int length;
-       int duration;
-       int residual;
-       u16 frame_control;
-       u16 seq_ctrl;
-
-       memset(&txdesc, 0, sizeof(txdesc));
-
-       txdesc.queue = skbdesc->entry->queue->qid;
-       txdesc.cw_min = skbdesc->entry->queue->cw_min;
-       txdesc.cw_max = skbdesc->entry->queue->cw_max;
-       txdesc.aifs = skbdesc->entry->queue->aifs;
-
-       /*
-        * Read required fields from ieee80211 header.
-        */
-       frame_control = le16_to_cpu(hdr->frame_control);
-       seq_ctrl = le16_to_cpu(hdr->seq_ctrl);
-
-       tx_rate = control->tx_rate->hw_value;
-
-       /*
-        * Check whether this frame is to be acked
-        */
-       if (!(control->flags & IEEE80211_TXCTL_NO_ACK))
-               __set_bit(ENTRY_TXD_ACK, &txdesc.flags);
-
-       /*
-        * Check if this is a RTS/CTS frame
-        */
-       if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) {
-               __set_bit(ENTRY_TXD_BURST, &txdesc.flags);
-               if (is_rts_frame(frame_control)) {
-                       __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags);
-                       __set_bit(ENTRY_TXD_ACK, &txdesc.flags);
-               } else
-                       __clear_bit(ENTRY_TXD_ACK, &txdesc.flags);
-               if (control->rts_cts_rate)
-                       tx_rate = control->rts_cts_rate->hw_value;
-       }
-
-       /*
-        * Determine retry information.
-        */
-       txdesc.retry_limit = control->retry_limit;
-       if (control->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
-               __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc.flags);
-
-       /*
-        * Check if more fragments are pending
-        */
-       if (ieee80211_get_morefrag(hdr)) {
-               __set_bit(ENTRY_TXD_BURST, &txdesc.flags);
-               __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags);
-       }
-
-       /*
-        * Beacons and probe responses require the tsf timestamp
-        * to be inserted into the frame.
-        */
-       if (txdesc.queue == QID_BEACON || is_probe_resp(frame_control))
-               __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags);
-
-       /*
-        * Determine with what IFS priority this frame should be send.
-        * Set ifs to IFS_SIFS when the this is not the first fragment,
-        * or this fragment came after RTS/CTS.
-        */
-       if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags)) {
-               txdesc.ifs = IFS_SIFS;
-       } else if (control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT) {
-               __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc.flags);
-               txdesc.ifs = IFS_BACKOFF;
-       } else {
-               txdesc.ifs = IFS_SIFS;
-       }
-
-       /*
-        * PLCP setup
-        * Length calculation depends on OFDM/CCK rate.
-        */
-       rate = rt2x00_get_rate(tx_rate);
-       txdesc.signal = rate->plcp;
-       txdesc.service = 0x04;
-
-       length = skbdesc->data_len + FCS_LEN;
-       if (rate->flags & DEV_RATE_OFDM) {
-               __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags);
-
-               txdesc.length_high = (length >> 6) & 0x3f;
-               txdesc.length_low = length & 0x3f;
-       } else {
-               /*
-                * Convert length to microseconds.
-                */
-               residual = get_duration_res(length, rate->bitrate);
-               duration = get_duration(length, rate->bitrate);
-
-               if (residual != 0) {
-                       duration++;
-
-                       /*
-                        * Check if we need to set the Length Extension
-                        */
-                       if (rate->bitrate == 110 && residual <= 30)
-                               txdesc.service |= 0x80;
-               }
-
-               txdesc.length_high = (duration >> 8) & 0xff;
-               txdesc.length_low = duration & 0xff;
-
-               /*
-                * When preamble is enabled we should set the
-                * preamble bit for the signal.
-                */
-               if (rt2x00_get_rate_preamble(tx_rate))
-                       txdesc.signal |= 0x08;
-       }
-
-       rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc);
-
-       /*
-        * Update queue entry.
-        */
-       skbdesc->entry->skb = skb;
-
-       /*
-        * The frame has been completely initialized and ready
-        * for sending to the device. The caller will push the
-        * frame to the device, but we are going to push the
-        * frame to debugfs here.
-        */
-       rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, skb);
-}
-EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);
-
 /*
  * Driver initialization handlers.
  */
index c17078eac197f2dec40c605eb36683aa2e443ab3..a056b12fbd1c2df694fc6c723d602d6dc3322e1a 100644 (file)
@@ -41,6 +41,7 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
        struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data;
        struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
        u32 word;
 
        if (rt2x00queue_full(queue))
@@ -57,6 +58,14 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
                return -EINVAL;
        }
 
+       /*
+        * Copy all TX descriptor information into txdesc,
+        * after that we are free to use the skb->cb array
+        * for our information.
+        */
+       entry->skb = skb;
+       rt2x00queue_create_tx_descriptor(entry, &txdesc, control);
+
        /*
         * Fill in skb descriptor
         */
@@ -69,8 +78,8 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
 
        memcpy(&priv_tx->control, control, sizeof(priv_tx->control));
        memcpy(priv_tx->data, skb->data, skb->len);
-       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
+       rt2x00queue_write_tx_descriptor(entry, &txdesc);
        rt2x00queue_index_inc(queue, Q_INDEX);
 
        return 0;
index 95f8dd3462f6f9c191760c8ca721da767b7e8913..19c10629c767513ca510e66c82732ce5e91584da 100644 (file)
 #include "rt2x00.h"
 #include "rt2x00lib.h"
 
+void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
+                                     struct txentry_desc *txdesc,
+                                     struct ieee80211_tx_control *control)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+       struct ieee80211_rate *rate = control->tx_rate;
+       const struct rt2x00_rate *hwrate;
+       unsigned int data_length;
+       unsigned int duration;
+       unsigned int residual;
+       u16 frame_control;
+
+       memset(txdesc, 0, sizeof(*txdesc));
+
+       /*
+        * Initialize information from queue
+        */
+       txdesc->queue = entry->queue->qid;
+       txdesc->cw_min = entry->queue->cw_min;
+       txdesc->cw_max = entry->queue->cw_max;
+       txdesc->aifs = entry->queue->aifs;
+
+       /* Data length should be extended with 4 bytes for CRC */
+       data_length = entry->skb->len + 4;
+
+       /*
+        * Read required fields from ieee80211 header.
+        */
+       frame_control = le16_to_cpu(hdr->frame_control);
+
+       /*
+        * Check whether this frame is to be acked.
+        */
+       if (!(control->flags & IEEE80211_TXCTL_NO_ACK))
+               __set_bit(ENTRY_TXD_ACK, &txdesc->flags);
+
+       /*
+        * Check if this is a RTS/CTS frame
+        */
+       if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) {
+               __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
+               if (is_rts_frame(frame_control)) {
+                       __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags);
+                       __set_bit(ENTRY_TXD_ACK, &txdesc->flags);
+               } else {
+                       __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags);
+                       __clear_bit(ENTRY_TXD_ACK, &txdesc->flags);
+               }
+               if (control->rts_cts_rate)
+                       rate = control->rts_cts_rate;
+       }
+
+       /*
+        * Determine retry information.
+        */
+       txdesc->retry_limit = control->retry_limit;
+       if (control->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+               __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags);
+
+       /*
+        * Check if more fragments are pending
+        */
+       if (ieee80211_get_morefrag(hdr)) {
+               __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
+               __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags);
+       }
+
+       /*
+        * Beacons and probe responses require the tsf timestamp
+        * to be inserted into the frame.
+        */
+       if (txdesc->queue == QID_BEACON || is_probe_resp(frame_control))
+               __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags);
+
+       /*
+        * Determine with what IFS priority this frame should be send.
+        * Set ifs to IFS_SIFS when the this is not the first fragment,
+        * or this fragment came after RTS/CTS.
+        */
+       if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
+               txdesc->ifs = IFS_SIFS;
+       } else if (control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT) {
+               __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags);
+               txdesc->ifs = IFS_BACKOFF;
+       } else {
+               txdesc->ifs = IFS_SIFS;
+       }
+
+       /*
+        * PLCP setup
+        * Length calculation depends on OFDM/CCK rate.
+        */
+       hwrate = rt2x00_get_rate(rate->hw_value);
+       txdesc->signal = hwrate->plcp;
+       txdesc->service = 0x04;
+
+       if (hwrate->flags & DEV_RATE_OFDM) {
+               __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags);
+
+               txdesc->length_high = (data_length >> 6) & 0x3f;
+               txdesc->length_low = data_length & 0x3f;
+       } else {
+               /*
+                * Convert length to microseconds.
+                */
+               residual = get_duration_res(data_length, hwrate->bitrate);
+               duration = get_duration(data_length, hwrate->bitrate);
+
+               if (residual != 0) {
+                       duration++;
+
+                       /*
+                        * Check if we need to set the Length Extension
+                        */
+                       if (hwrate->bitrate == 110 && residual <= 30)
+                               txdesc->service |= 0x80;
+               }
+
+               txdesc->length_high = (duration >> 8) & 0xff;
+               txdesc->length_low = duration & 0xff;
+
+               /*
+                * When preamble is enabled we should set the
+                * preamble bit for the signal.
+                */
+               if (rt2x00_get_rate_preamble(rate->hw_value))
+                       txdesc->signal |= 0x08;
+       }
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor);
+
+void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
+                                    struct txentry_desc *txdesc)
+{
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+
+       rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
+
+       /*
+        * All processing on the frame has been completed, this means
+        * it is now ready to be dumped to userspace through debugfs.
+        */
+       rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
+
+       /*
+        * We are done writing the frame to the queue entry,
+        * if this entry is a RTS of CTS-to-self frame we are done,
+        * otherwise we need to kick the queue.
+        */
+       if (rt2x00dev->ops->lib->kick_tx_queue &&
+           !(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))
+               rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev,
+                                                  entry->queue->qid);
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor);
+
 struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
                                         const enum data_queue_qid queue)
 {
index 4bde98ba3c601889024355542e5942162fecdd49..c6edc52873c4f86d1c98797a0791474026eb5c85 100644 (file)
@@ -203,6 +203,7 @@ struct txdone_entry_desc {
  * enum txentry_desc_flags: Status flags for TX entry descriptor
  *
  * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame.
+ * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame.
  * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate.
  * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame.
  * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment.
@@ -213,6 +214,7 @@ struct txdone_entry_desc {
  */
 enum txentry_desc_flags {
        ENTRY_TXD_RTS_FRAME,
+       ENTRY_TXD_CTS_FRAME,
        ENTRY_TXD_OFDM_RATE,
        ENTRY_TXD_FIRST_FRAGMENT,
        ENTRY_TXD_MORE_FRAG,
index f72b3d07a42d1037e25827ab5005d222fcbd8eae..df6621025f4b2dd6d4d81605836120bab729b37c 100644 (file)
@@ -186,6 +186,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
        struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data;
        struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
        u32 length;
 
        if (rt2x00queue_full(queue))
@@ -199,6 +200,14 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
                return -EINVAL;
        }
 
+       /*
+        * Copy all TX descriptor information into txdesc,
+        * after that we are free to use the skb->cb array
+        * for our information.
+        */
+       entry->skb = skb;
+       rt2x00queue_create_tx_descriptor(entry, &txdesc, control);
+
        /*
         * Add the descriptor in front of the skb.
         */
@@ -216,7 +225,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
        skbdesc->entry = entry;
 
        memcpy(&priv_tx->control, control, sizeof(priv_tx->control));
-       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
+       rt2x00queue_write_tx_descriptor(entry, &txdesc);
 
        /*
         * USB devices cannot blindly pass the skb->len as the
index d8e681ec4bb04077a1b60b57997d33bb07b490e2..d01d5f16bbce9beba6d9b42d555198f470dc51ea 100644 (file)
@@ -2361,18 +2361,27 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw)
 }
 
 static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                         struct ieee80211_tx_control *control)
+                                struct ieee80211_tx_control *control)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct rt2x00_intf *intf = vif_to_intf(control->vif);
        struct queue_entry_priv_pci_tx *priv_tx;
        struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
        unsigned int beacon_base;
        u32 reg;
 
        if (unlikely(!intf->beacon))
                return -ENOBUFS;
 
+       /*
+        * Copy all TX descriptor information into txdesc,
+        * after that we are free to use the skb->cb array
+        * for our information.
+        */
+       intf->beacon->skb = skb;
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+
        priv_tx = intf->beacon->priv_data;
        memset(priv_tx->desc, 0, intf->beacon->queue->desc_size);
 
@@ -2402,7 +2411,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * Write entire beacon with descriptor to register,
         * and kick the beacon generator.
         */
-       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
+       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
        beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
        rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
                                      skbdesc->desc, skbdesc->desc_len);
index 1bcf8c132cdc357ab5f3e97e520bace24ac4b172..bc44116a8a3e2b702ee07474ced6b60155e20172 100644 (file)
@@ -1956,12 +1956,21 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct rt2x00_intf *intf = vif_to_intf(control->vif);
        struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
        unsigned int beacon_base;
        u32 reg;
 
        if (unlikely(!intf->beacon))
                return -ENOBUFS;
 
+       /*
+        * Copy all TX descriptor information into txdesc,
+        * after that we are free to use the skb->cb array
+        * for our information.
+        */
+       intf->beacon->skb = skb;
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+
        /*
         * Add the descriptor in front of the skb.
         */
@@ -1994,7 +2003,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * Write entire beacon with descriptor to register,
         * and kick the beacon generator.
         */
-       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
+       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
        beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
        rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
                                 USB_VENDOR_REQUEST_OUT, beacon_base, 0,