queue->cw_max = 10; /* cw_min: 2^10 = 1024. */
 
        queue->aifs = params->aifs;
+       queue->txop = params->txop;
 
        INFO(rt2x00dev,
-            "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n",
-            queue_idx, queue->cw_min, queue->cw_max, queue->aifs);
+            "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d.\n",
+            queue_idx, queue->cw_min, queue->cw_max, queue->aifs, queue->txop);
 
        return 0;
 }
 
 
        queue->rt2x00dev = rt2x00dev;
        queue->qid = qid;
+       queue->txop = 0;
        queue->aifs = 2;
        queue->cw_min = 5;
        queue->cw_max = 10;
 
  * @length: Number of frames in queue.
  * @index: Index pointers to entry positions in the queue,
  *     use &enum queue_index to get a specific index field.
+ * @txop: maximum burst time.
  * @aifs: The aifs value for outgoing frames (field ignored in RX queue).
  * @cw_min: The cw min value for outgoing frames (field ignored in RX queue).
  * @cw_max: The cw max value for outgoing frames (field ignored in RX queue).
        unsigned short length;
        unsigned short index[Q_INDEX_MAX];
 
+       unsigned short txop;
        unsigned short aifs;
        unsigned short cw_min;
        unsigned short cw_max;
 
 
        rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff);
 
-       rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, ®);
-       rt2x00_set_field32(®, AC_TXOP_CSR0_AC0_TX_OP, 0);
-       rt2x00_set_field32(®, AC_TXOP_CSR0_AC1_TX_OP, 0);
-       rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
-
-       rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, ®);
-       rt2x00_set_field32(®, AC_TXOP_CSR1_AC2_TX_OP, 192);
-       rt2x00_set_field32(®, AC_TXOP_CSR1_AC3_TX_OP, 48);
-       rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
-
        /*
         * Clear all beacons
         * For the Beacon base registers we only need to clear
        return 0;
 }
 
+static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
+                          const struct ieee80211_tx_queue_params *params)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct data_queue *queue;
+       struct rt2x00_field32 field;
+       int retval;
+       u32 reg;
+
+       /*
+        * First pass the configuration through rt2x00lib, that will
+        * update the queue settings and validate the input. After that
+        * we are free to update the registers based on the value
+        * in the queue parameter.
+        */
+       retval = rt2x00mac_conf_tx(hw, queue_idx, params);
+       if (retval)
+               return retval;
+
+       queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
+
+       /* Update WMM TXOP register */
+       if (queue_idx < 2) {
+               field.bit_offset = queue_idx * 16;
+               field.bit_mask = 0xffff << field.bit_offset;
+
+               rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, ®);
+               rt2x00_set_field32(®, field, queue->txop);
+               rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
+       } else if (queue_idx < 4) {
+               field.bit_offset = (queue_idx - 2) * 16;
+               field.bit_mask = 0xffff << field.bit_offset;
+
+               rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, ®);
+               rt2x00_set_field32(®, field, queue->txop);
+               rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
+       }
+
+       /* Update WMM registers */
+       field.bit_offset = queue_idx * 4;
+       field.bit_mask = 0xf << field.bit_offset;
+
+       rt2x00pci_register_read(rt2x00dev, AIFSN_CSR, ®);
+       rt2x00_set_field32(®, field, queue->aifs);
+       rt2x00pci_register_write(rt2x00dev, AIFSN_CSR, reg);
+
+       rt2x00pci_register_read(rt2x00dev, CWMIN_CSR, ®);
+       rt2x00_set_field32(®, field, queue->cw_min);
+       rt2x00pci_register_write(rt2x00dev, CWMIN_CSR, reg);
+
+       rt2x00pci_register_read(rt2x00dev, CWMAX_CSR, ®);
+       rt2x00_set_field32(®, field, queue->cw_max);
+       rt2x00pci_register_write(rt2x00dev, CWMAX_CSR, reg);
+
+       return 0;
+}
+
 static u64 rt61pci_get_tsf(struct ieee80211_hw *hw)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        .get_stats              = rt2x00mac_get_stats,
        .set_retry_limit        = rt61pci_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
-       .conf_tx                = rt2x00mac_conf_tx,
+       .conf_tx                = rt61pci_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt61pci_get_tsf,
 };
 
        rt73usb_register_write(rt2x00dev, PHY_CSR6, 0x00080606);
        rt73usb_register_write(rt2x00dev, PHY_CSR7, 0x00000408);
 
-       rt73usb_register_read(rt2x00dev, AC_TXOP_CSR0, ®);
-       rt2x00_set_field32(®, AC_TXOP_CSR0_AC0_TX_OP, 0);
-       rt2x00_set_field32(®, AC_TXOP_CSR0_AC1_TX_OP, 0);
-       rt73usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
-
-       rt73usb_register_read(rt2x00dev, AC_TXOP_CSR1, ®);
-       rt2x00_set_field32(®, AC_TXOP_CSR1_AC2_TX_OP, 192);
-       rt2x00_set_field32(®, AC_TXOP_CSR1_AC3_TX_OP, 48);
-       rt73usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
-
        rt73usb_register_read(rt2x00dev, MAC_CSR9, ®);
        rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0);
        rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
        return 0;
 }
 
+static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
+                          const struct ieee80211_tx_queue_params *params)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct data_queue *queue;
+       struct rt2x00_field32 field;
+       int retval;
+       u32 reg;
+
+       /*
+        * First pass the configuration through rt2x00lib, that will
+        * update the queue settings and validate the input. After that
+        * we are free to update the registers based on the value
+        * in the queue parameter.
+        */
+       retval = rt2x00mac_conf_tx(hw, queue_idx, params);
+       if (retval)
+               return retval;
+
+       queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
+
+       /* Update WMM TXOP register */
+       if (queue_idx < 2) {
+               field.bit_offset = queue_idx * 16;
+               field.bit_mask = 0xffff << field.bit_offset;
+
+               rt73usb_register_read(rt2x00dev, AC_TXOP_CSR0, ®);
+               rt2x00_set_field32(®, field, queue->txop);
+               rt73usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
+       } else if (queue_idx < 4) {
+               field.bit_offset = (queue_idx - 2) * 16;
+               field.bit_mask = 0xffff << field.bit_offset;
+
+               rt73usb_register_read(rt2x00dev, AC_TXOP_CSR1, ®);
+               rt2x00_set_field32(®, field, queue->txop);
+               rt73usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
+       }
+
+       /* Update WMM registers */
+       field.bit_offset = queue_idx * 4;
+       field.bit_mask = 0xf << field.bit_offset;
+
+       rt73usb_register_read(rt2x00dev, AIFSN_CSR, ®);
+       rt2x00_set_field32(®, field, queue->aifs);
+       rt73usb_register_write(rt2x00dev, AIFSN_CSR, reg);
+
+       rt73usb_register_read(rt2x00dev, CWMIN_CSR, ®);
+       rt2x00_set_field32(®, field, queue->cw_min);
+       rt73usb_register_write(rt2x00dev, CWMIN_CSR, reg);
+
+       rt73usb_register_read(rt2x00dev, CWMAX_CSR, ®);
+       rt2x00_set_field32(®, field, queue->cw_max);
+       rt73usb_register_write(rt2x00dev, CWMAX_CSR, reg);
+
+       return 0;
+}
+
 #if 0
 /*
  * Mac80211 demands get_tsf must be atomic.
        .get_stats              = rt2x00mac_get_stats,
        .set_retry_limit        = rt73usb_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
-       .conf_tx                = rt2x00mac_conf_tx,
+       .conf_tx                = rt73usb_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt73usb_get_tsf,
 };