b43legacy: use frame control helpers
[safe/jmp/linux-2.6] / drivers / net / wireless / rt2x00 / rt2x00dev.c
index d341764..9ea6773 100644 (file)
@@ -112,6 +112,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
        if (status)
                return status;
 
+       rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_ON);
+
        rt2x00leds_led_radio(rt2x00dev, true);
        rt2x00led_led_activity(rt2x00dev, true);
 
@@ -157,6 +159,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
         * Disable radio.
         */
        rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF);
+       rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_OFF);
        rt2x00led_led_activity(rt2x00dev, false);
        rt2x00leds_led_radio(rt2x00dev, false);
 }
@@ -415,7 +418,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
        struct rt2x00_dev *rt2x00dev = data;
        struct rt2x00_intf *intf = vif_to_intf(vif);
        struct sk_buff *skb;
-       struct ieee80211_tx_control control;
        struct ieee80211_bss_conf conf;
        int delayed_flags;
 
@@ -433,9 +435,9 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
        spin_unlock(&intf->lock);
 
        if (delayed_flags & DELAYED_UPDATE_BEACON) {
-               skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control);
-               if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
-                                                            skb, &control))
+               skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
+               if (skb &&
+                   rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb))
                        dev_kfree_skb(skb);
        }
 
@@ -482,9 +484,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
        if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
                return;
 
-       ieee80211_iterate_active_interfaces(rt2x00dev->hw,
-                                           rt2x00lib_beacondone_iter,
-                                           rt2x00dev);
+       ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw,
+                                                  rt2x00lib_beacondone_iter,
+                                                  rt2x00dev);
 
        queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
 }
@@ -494,8 +496,13 @@ void rt2x00lib_txdone(struct queue_entry *entry,
                      struct txdone_entry_desc *txdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-       struct skb_frame_desc *skbdesc;
-       struct ieee80211_tx_status tx_status;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+
+       /*
+        * Send frame to debugfs immediately, after this call is completed
+        * we are going to overwrite the skb->cb array.
+        */
+       rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
 
        /*
         * Update TX statistics.
@@ -503,26 +510,25 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        rt2x00dev->link.qual.tx_success +=
            test_bit(TXDONE_SUCCESS, &txdesc->flags);
        rt2x00dev->link.qual.tx_failed +=
-           txdesc->retry + !!test_bit(TXDONE_FAILURE, &txdesc->flags);
+           test_bit(TXDONE_FAILURE, &txdesc->flags);
 
        /*
         * Initialize TX status
         */
-       tx_status.flags = 0;
-       tx_status.ack_signal = 0;
-       tx_status.excessive_retries =
+       memset(&tx_info->status, 0, sizeof(tx_info->status));
+       tx_info->status.ack_signal = 0;
+       tx_info->status.excessive_retries =
            test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags);
-       tx_status.retry_count = txdesc->retry;
-       memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control));
+       tx_info->status.retry_count = txdesc->retry;
 
-       if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+       if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
-                       tx_status.flags |= IEEE80211_TX_STATUS_ACK;
+                       tx_info->flags |= IEEE80211_TX_STAT_ACK;
                else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
                        rt2x00dev->low_level_stats.dot11ACKFailureCount++;
        }
 
-       if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) {
+       if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
                if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
                        rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
                else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
@@ -530,19 +536,13 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        }
 
        /*
-        * Send the tx_status to debugfs. Only send the status report
-        * to mac80211 when the frame originated from there. If this was
-        * a extra frame coming through a mac80211 library call (RTS/CTS)
-        * then we should not send the status report back.
-        * If send to mac80211, mac80211 will clean up the skb structure,
-        * otherwise we have to do it ourself.
+        * Only send the status report to mac80211 when TX status was
+        * requested by it. If this was a extra frame coming through
+        * a mac80211 library call (RTS/CTS) then we should not send the
+        * status report back.
         */
-       rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
-
-       skbdesc = get_skb_frame_desc(entry->skb);
-       if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))
-               ieee80211_tx_status_irqsafe(rt2x00dev->hw,
-                                           entry->skb, &tx_status);
+       if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
+               ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
        else
                dev_kfree_skb_irq(entry->skb);
        entry->skb = NULL;
@@ -554,14 +554,32 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
+       unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
        struct ieee80211_supported_band *sband;
        struct ieee80211_hdr *hdr;
        const struct rt2x00_rate *rate;
+       unsigned int align;
        unsigned int i;
        int idx = -1;
        u16 fc;
 
        /*
+        * The data behind the ieee80211 header must be
+        * aligned on a 4 byte boundary.
+        */
+       align = ((unsigned long)(entry->skb->data + header_size)) & 3;
+
+       if (align) {
+               skb_push(entry->skb, align);
+               /* Move entire frame in 1 command */
+               memmove(entry->skb->data, entry->skb->data + align,
+                       rxdesc->size);
+       }
+
+       /* Update data pointers, trim buffer to correct size */
+       skb_trim(entry->skb, rxdesc->size);
+
+       /*
         * Update RX statistics.
         */
        sband = &rt2x00dev->bands[rt2x00dev->curr_band];