.eeprom_size            = EEPROM_SIZE,
        .rf_size                = RF_SIZE,
        .tx_queues              = NUM_TX_QUEUES,
-       .extra_tx_headroom      = 0,
        .queue_init             = rt2400pci_queue_init,
        .lib                    = &rt2400pci_rt2x00_ops,
        .hw                     = &rt2400pci_mac80211_ops,
 
        .eeprom_size            = EEPROM_SIZE,
        .rf_size                = RF_SIZE,
        .tx_queues              = NUM_TX_QUEUES,
-       .extra_tx_headroom      = 0,
        .queue_init             = rt2500pci_queue_init,
        .lib                    = &rt2500pci_rt2x00_ops,
        .hw                     = &rt2500pci_mac80211_ops,
 
        .eeprom_size            = EEPROM_SIZE,
        .rf_size                = RF_SIZE,
        .tx_queues              = NUM_TX_QUEUES,
-       .extra_tx_headroom      = TXD_DESC_SIZE,
        .queue_init             = rt2500usb_queue_init,
        .lib                    = &rt2500usb_rt2x00_ops,
        .hw                     = &rt2500usb_mac80211_ops,
 
        .eeprom_size            = EEPROM_SIZE,
        .rf_size                = RF_SIZE,
        .tx_queues              = NUM_TX_QUEUES,
-       .extra_tx_headroom      = TXWI_DESC_SIZE,
        .queue_init             = rt2800pci_queue_init,
        .lib                    = &rt2800pci_rt2x00_ops,
        .drv                    = &rt2800pci_rt2800_ops,
 
        .eeprom_size            = EEPROM_SIZE,
        .rf_size                = RF_SIZE,
        .tx_queues              = NUM_TX_QUEUES,
-       .extra_tx_headroom      = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
        .queue_init             = rt2800usb_queue_init,
        .lib                    = &rt2800usb_rt2x00_ops,
        .drv                    = &rt2800usb_rt2800_ops,
        .eeprom_size            = EEPROM_SIZE,
        .rf_size                = RF_SIZE,
        .tx_queues              = NUM_TX_QUEUES,
-       .extra_tx_headroom      = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592,
        .queue_init             = rt2800usb_queue_init,
        .lib                    = &rt2800usb_rt2x00_ops,
        .drv                    = &rt2800usb_rt2800_ops,
 
        const unsigned int eeprom_size;
        const unsigned int rf_size;
        const unsigned int tx_queues;
-       const unsigned int extra_tx_headroom;
        void (*queue_init)(struct data_queue *queue);
        const struct rt2x00lib_ops *lib;
        const void *drv;
         */
        struct list_head bar_list;
        spinlock_t bar_list_lock;
+
+       /* Extra TX headroom required for alignment purposes. */
+       unsigned int extra_tx_headroom;
 };
 
 struct rt2x00_bar_list_entry {
 
        /*
         * Remove the extra tx headroom from the skb.
         */
-       skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom);
+       skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);
 
        /*
         * Signal that the TX descriptor is no longer in the skb.
         */
        rt2x00dev->hw->extra_tx_headroom =
                max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
-                     rt2x00dev->ops->extra_tx_headroom);
+                     rt2x00dev->extra_tx_headroom);
 
        /*
         * Take TX headroom required for alignment into account.
        rt2x00dev->hw->wiphy->n_iface_combinations = 1;
 }
 
+static unsigned int rt2x00dev_extra_tx_headroom(struct rt2x00_dev *rt2x00dev)
+{
+       if (WARN_ON(!rt2x00dev->tx))
+               return 0;
+
+       if (rt2x00_is_usb(rt2x00dev))
+               return rt2x00dev->tx[0].winfo_size + rt2x00dev->tx[0].desc_size;
+
+       return rt2x00dev->tx[0].winfo_size;
+}
+
 /*
  * driver allocation handlers.
  */
        if (retval)
                goto exit;
 
+       /* Cache TX headroom value */
+       rt2x00dev->extra_tx_headroom = rt2x00dev_extra_tx_headroom(rt2x00dev);
+
        /*
         * Determine which operating modes are supported, all modes
         * which require beaconing, depend on the availability of
 
        /*
         * Add the requested extra tx headroom in front of the skb.
         */
-       skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom);
-       memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom);
+       skb_push(entry->skb, rt2x00dev->extra_tx_headroom);
+       memset(entry->skb->data, 0, rt2x00dev->extra_tx_headroom);
 
        /*
         * Call the driver's write_tx_data function, if it exists.
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct ieee80211_bar *bar = (void *) (entry->skb->data +
-                                   rt2x00dev->ops->extra_tx_headroom);
+                                   rt2x00dev->extra_tx_headroom);
        struct rt2x00_bar_list_entry *bar_entry;
 
        if (likely(!ieee80211_is_back_req(bar->frame_control)))
 
        .eeprom_size            = EEPROM_SIZE,
        .rf_size                = RF_SIZE,
        .tx_queues              = NUM_TX_QUEUES,
-       .extra_tx_headroom      = 0,
        .queue_init             = rt61pci_queue_init,
        .lib                    = &rt61pci_rt2x00_ops,
        .hw                     = &rt61pci_mac80211_ops,
 
        .eeprom_size            = EEPROM_SIZE,
        .rf_size                = RF_SIZE,
        .tx_queues              = NUM_TX_QUEUES,
-       .extra_tx_headroom      = TXD_DESC_SIZE,
        .queue_init             = rt73usb_queue_init,
        .lib                    = &rt73usb_rt2x00_ops,
        .hw                     = &rt73usb_mac80211_ops,