]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/rt2x00/rt2400pci.c
mac80211: move TX info into skb->cb
[karo-tx-linux.git] / drivers / net / wireless / rt2x00 / rt2400pci.c
index b41187af13063606ca024f73ca3b19cc8bd3573a..900140d3b304539d8a50127246cb1744a3c18184 100644 (file)
@@ -363,7 +363,7 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
-       rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00 | preamble_mask);
+       rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
        rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
        rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10));
        rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
@@ -620,48 +620,38 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
 static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
                                   struct queue_entry *entry)
 {
-       struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
+       struct queue_entry_priv_pci *entry_priv = entry->priv_data;
        u32 word;
 
-       rt2x00_desc_read(priv_rx->desc, 2, &word);
+       rt2x00_desc_read(entry_priv->desc, 2, &word);
        rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH,
                           entry->queue->data_size);
-       rt2x00_desc_write(priv_rx->desc, 2, word);
+       rt2x00_desc_write(entry_priv->desc, 2, word);
 
-       rt2x00_desc_read(priv_rx->desc, 1, &word);
-       rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma);
-       rt2x00_desc_write(priv_rx->desc, 1, word);
+       rt2x00_desc_read(entry_priv->desc, 1, &word);
+       rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma);
+       rt2x00_desc_write(entry_priv->desc, 1, word);
 
-       rt2x00_desc_read(priv_rx->desc, 0, &word);
+       rt2x00_desc_read(entry_priv->desc, 0, &word);
        rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
-       rt2x00_desc_write(priv_rx->desc, 0, word);
+       rt2x00_desc_write(entry_priv->desc, 0, word);
 }
 
 static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev,
                                   struct queue_entry *entry)
 {
-       struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data;
+       struct queue_entry_priv_pci *entry_priv = entry->priv_data;
        u32 word;
 
-       rt2x00_desc_read(priv_tx->desc, 1, &word);
-       rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma);
-       rt2x00_desc_write(priv_tx->desc, 1, word);
-
-       rt2x00_desc_read(priv_tx->desc, 2, &word);
-       rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH,
-                          entry->queue->data_size);
-       rt2x00_desc_write(priv_tx->desc, 2, word);
-
-       rt2x00_desc_read(priv_tx->desc, 0, &word);
+       rt2x00_desc_read(entry_priv->desc, 0, &word);
        rt2x00_set_field32(&word, TXD_W0_VALID, 0);
        rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
-       rt2x00_desc_write(priv_tx->desc, 0, word);
+       rt2x00_desc_write(entry_priv->desc, 0, word);
 }
 
 static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
 {
-       struct queue_entry_priv_pci_rx *priv_rx;
-       struct queue_entry_priv_pci_tx *priv_tx;
+       struct queue_entry_priv_pci *entry_priv;
        u32 reg;
 
        /*
@@ -674,28 +664,28 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit);
        rt2x00pci_register_write(rt2x00dev, TXCSR2, reg);
 
-       priv_tx = rt2x00dev->tx[1].entries[0].priv_data;
+       entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
        rt2x00pci_register_read(rt2x00dev, TXCSR3, &reg);
        rt2x00_set_field32(&reg, TXCSR3_TX_RING_REGISTER,
-                          priv_tx->desc_dma);
+                          entry_priv->desc_dma);
        rt2x00pci_register_write(rt2x00dev, TXCSR3, reg);
 
-       priv_tx = rt2x00dev->tx[0].entries[0].priv_data;
+       entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
        rt2x00pci_register_read(rt2x00dev, TXCSR5, &reg);
        rt2x00_set_field32(&reg, TXCSR5_PRIO_RING_REGISTER,
-                          priv_tx->desc_dma);
+                          entry_priv->desc_dma);
        rt2x00pci_register_write(rt2x00dev, TXCSR5, reg);
 
-       priv_tx = rt2x00dev->bcn[1].entries[0].priv_data;
+       entry_priv = rt2x00dev->bcn[1].entries[0].priv_data;
        rt2x00pci_register_read(rt2x00dev, TXCSR4, &reg);
        rt2x00_set_field32(&reg, TXCSR4_ATIM_RING_REGISTER,
-                          priv_tx->desc_dma);
+                          entry_priv->desc_dma);
        rt2x00pci_register_write(rt2x00dev, TXCSR4, reg);
 
-       priv_tx = rt2x00dev->bcn[0].entries[0].priv_data;
+       entry_priv = rt2x00dev->bcn[0].entries[0].priv_data;
        rt2x00pci_register_read(rt2x00dev, TXCSR6, &reg);
        rt2x00_set_field32(&reg, TXCSR6_BEACON_RING_REGISTER,
-                          priv_tx->desc_dma);
+                          entry_priv->desc_dma);
        rt2x00pci_register_write(rt2x00dev, TXCSR6, reg);
 
        rt2x00pci_register_read(rt2x00dev, RXCSR1, &reg);
@@ -703,9 +693,10 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, RXCSR1_NUM_RXD, rt2x00dev->rx->limit);
        rt2x00pci_register_write(rt2x00dev, RXCSR1, reg);
 
-       priv_rx = rt2x00dev->rx->entries[0].priv_data;
+       entry_priv = rt2x00dev->rx->entries[0].priv_data;
        rt2x00pci_register_read(rt2x00dev, RXCSR2, &reg);
-       rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma);
+       rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER,
+                          entry_priv->desc_dma);
        rt2x00pci_register_write(rt2x00dev, RXCSR2, reg);
 
        return 0;
@@ -1001,17 +992,22 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
  */
 static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
                                    struct sk_buff *skb,
-                                   struct txentry_desc *txdesc,
-                                   struct ieee80211_tx_control *control)
+                                   struct txentry_desc *txdesc)
 {
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+       struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
        __le32 *txd = skbdesc->desc;
        u32 word;
 
        /*
         * Start writing the descriptor words.
         */
+       rt2x00_desc_read(entry_priv->desc, 1, &word);
+       rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry_priv->data_dma);
+       rt2x00_desc_write(entry_priv->desc, 1, word);
+
        rt2x00_desc_read(txd, 2, &word);
+       rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skbdesc->data_len);
        rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skbdesc->data_len);
        rt2x00_desc_write(txd, 2, word);
 
@@ -1046,8 +1042,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
                           test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags));
        rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
        rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
-                          !!(control->flags &
-                             IEEE80211_TXCTL_LONG_RETRY_LIMIT));
+                          test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
        rt2x00_desc_write(txd, 0, word);
 }
 
@@ -1055,11 +1050,11 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
  * TX data initialization
  */
 static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
-                                   const unsigned int queue)
+                                   const enum data_queue_qid queue)
 {
        u32 reg;
 
-       if (queue == RT2X00_BCN_QUEUE_BEACON) {
+       if (queue == QID_BEACON) {
                rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
                if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
                        rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
@@ -1071,12 +1066,9 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
        }
 
        rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
-       rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO,
-                          (queue == IEEE80211_TX_QUEUE_DATA0));
-       rt2x00_set_field32(&reg, TXCSR0_KICK_TX,
-                          (queue == IEEE80211_TX_QUEUE_DATA1));
-       rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM,
-                          (queue == RT2X00_BCN_QUEUE_ATIM));
+       rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
+       rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
+       rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue == QID_ATIM));
        rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 }
 
@@ -1086,16 +1078,15 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 static void rt2400pci_fill_rxdone(struct queue_entry *entry,
                                  struct rxdone_entry_desc *rxdesc)
 {
-       struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
+       struct queue_entry_priv_pci *entry_priv = entry->priv_data;
        u32 word0;
        u32 word2;
        u32 word3;
 
-       rt2x00_desc_read(priv_rx->desc, 0, &word0);
-       rt2x00_desc_read(priv_rx->desc, 2, &word2);
-       rt2x00_desc_read(priv_rx->desc, 3, &word3);
+       rt2x00_desc_read(entry_priv->desc, 0, &word0);
+       rt2x00_desc_read(entry_priv->desc, 2, &word2);
+       rt2x00_desc_read(entry_priv->desc, 3, &word3);
 
-       rxdesc->flags = 0;
        if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
                rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
        if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
@@ -1111,7 +1102,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
            entry->queue->rt2x00dev->rssi_offset;
        rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
 
-       rxdesc->dev_flags = RXDONE_SIGNAL_PLCP;
+       rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
        if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
                rxdesc->dev_flags |= RXDONE_MY_BSS;
 }
@@ -1120,18 +1111,18 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
  * Interrupt functions.
  */
 static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
-                            const enum ieee80211_tx_queue queue_idx)
+                            const enum data_queue_qid queue_idx)
 {
        struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
-       struct queue_entry_priv_pci_tx *priv_tx;
+       struct queue_entry_priv_pci *entry_priv;
        struct queue_entry *entry;
        struct txdone_entry_desc txdesc;
        u32 word;
 
        while (!rt2x00queue_empty(queue)) {
                entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-               priv_tx = entry->priv_data;
-               rt2x00_desc_read(priv_tx->desc, 0, &word);
+               entry_priv = entry->priv_data;
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
 
                if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
                    !rt2x00_get_field32(word, TXD_W0_VALID))
@@ -1140,7 +1131,18 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
                /*
                 * Obtain the status about this packet.
                 */
-               txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT);
+               txdesc.flags = 0;
+               switch (rt2x00_get_field32(word, TXD_W0_RESULT)) {
+               case 0: /* Success */
+               case 1: /* Success with retry */
+                       __set_bit(TXDONE_SUCCESS, &txdesc.flags);
+                       break;
+               case 2: /* Failure, excessive retries */
+                       __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
+                       /* Don't break, this is a failed frame! */
+               default: /* Failure */
+                       __set_bit(TXDONE_FAILURE, &txdesc.flags);
+               }
                txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
 
                rt2x00pci_txdone(rt2x00dev, entry, &txdesc);
@@ -1187,19 +1189,19 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
         * 3 - Atim ring transmit done interrupt.
         */
        if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING))
-               rt2400pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM);
+               rt2400pci_txdone(rt2x00dev, QID_ATIM);
 
        /*
         * 4 - Priority ring transmit done interrupt.
         */
        if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
-               rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
+               rt2400pci_txdone(rt2x00dev, QID_AC_BE);
 
        /*
         * 5 - Tx ring transmit done interrupt.
         */
        if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
-               rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA1);
+               rt2400pci_txdone(rt2x00dev, QID_AC_BK);
 
        return IRQ_HANDLED;
 }
@@ -1308,7 +1310,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
 
        if (value == LED_MODE_TXRX_ACTIVITY) {
                rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
-               rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY;
+               rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY;
                rt2x00dev->led_qual.led_dev.brightness_set =
                    rt2400pci_brightness_set;
                rt2x00dev->led_qual.led_dev.blink_set =
@@ -1364,11 +1366,9 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize all hw fields.
         */
-       rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+       rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+                              IEEE80211_HW_SIGNAL_DBM;
        rt2x00dev->hw->extra_tx_headroom = 0;
-       rt2x00dev->hw->max_signal = MAX_SIGNAL;
-       rt2x00dev->hw->max_rssi = MAX_RX_SSI;
-       rt2x00dev->hw->queues = 2;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
        SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1445,8 +1445,7 @@ static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,
        return 0;
 }
 
-static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
-                            int queue,
+static int rt2400pci_conf_tx(struct ieee80211_hw *hw, u16 queue,
                             const struct ieee80211_tx_queue_params *params)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -1456,7 +1455,7 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
         * per queue. So by default we only configure the TX queue,
         * and ignore all other configurations.
         */
-       if (queue != IEEE80211_TX_QUEUE_DATA0)
+       if (queue != 0)
                return -EINVAL;
 
        if (rt2x00mac_conf_tx(hw, queue, params))
@@ -1485,18 +1484,27 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw)
        return tsf;
 }
 
-static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                                  struct ieee80211_tx_control *control)
+static int rt2400pci_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 queue_entry_priv_pci_tx *priv_tx;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
+       struct queue_entry_priv_pci *entry_priv;
        struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
        u32 reg;
 
        if (unlikely(!intf->beacon))
                return -ENOBUFS;
-       priv_tx = intf->beacon->priv_data;
+       entry_priv = 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);
 
        /*
         * Fill in skb descriptor
@@ -1506,7 +1514,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
        skbdesc->data = skb->data;
        skbdesc->data_len = skb->len;
-       skbdesc->desc = priv_tx->desc;
+       skbdesc->desc = entry_priv->desc;
        skbdesc->desc_len = intf->beacon->queue->desc_size;
        skbdesc->entry = intf->beacon;
 
@@ -1520,21 +1528,14 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
        rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 
-       /*
-        * mac80211 doesn't provide the control->queue variable
-        * for beacons. Set our own queue identification so
-        * it can be used during descriptor initialization.
-        */
-       control->queue = RT2X00_BCN_QUEUE_BEACON;
-       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
-
        /*
         * Enable beacon generation.
         * Write entire beacon with descriptor to register,
         * and kick the beacon generator.
         */
-       memcpy(priv_tx->data, skb->data, skb->len);
-       rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
+       memcpy(entry_priv->data, skb->data, skb->len);
+       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
+       rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
 
        return 0;
 }
@@ -1593,28 +1594,28 @@ static const struct data_queue_desc rt2400pci_queue_rx = {
        .entry_num              = RX_ENTRIES,
        .data_size              = DATA_FRAME_SIZE,
        .desc_size              = RXD_DESC_SIZE,
-       .priv_size              = sizeof(struct queue_entry_priv_pci_rx),
+       .priv_size              = sizeof(struct queue_entry_priv_pci),
 };
 
 static const struct data_queue_desc rt2400pci_queue_tx = {
        .entry_num              = TX_ENTRIES,
        .data_size              = DATA_FRAME_SIZE,
        .desc_size              = TXD_DESC_SIZE,
-       .priv_size              = sizeof(struct queue_entry_priv_pci_tx),
+       .priv_size              = sizeof(struct queue_entry_priv_pci),
 };
 
 static const struct data_queue_desc rt2400pci_queue_bcn = {
        .entry_num              = BEACON_ENTRIES,
        .data_size              = MGMT_FRAME_SIZE,
        .desc_size              = TXD_DESC_SIZE,
-       .priv_size              = sizeof(struct queue_entry_priv_pci_tx),
+       .priv_size              = sizeof(struct queue_entry_priv_pci),
 };
 
 static const struct data_queue_desc rt2400pci_queue_atim = {
        .entry_num              = ATIM_ENTRIES,
        .data_size              = DATA_FRAME_SIZE,
        .desc_size              = TXD_DESC_SIZE,
-       .priv_size              = sizeof(struct queue_entry_priv_pci_tx),
+       .priv_size              = sizeof(struct queue_entry_priv_pci),
 };
 
 static const struct rt2x00_ops rt2400pci_ops = {
@@ -1623,6 +1624,7 @@ static const struct rt2x00_ops rt2400pci_ops = {
        .max_ap_intf    = 1,
        .eeprom_size    = EEPROM_SIZE,
        .rf_size        = RF_SIZE,
+       .tx_queues      = NUM_TX_QUEUES,
        .rx             = &rt2400pci_queue_rx,
        .tx             = &rt2400pci_queue_tx,
        .bcn            = &rt2400pci_queue_bcn,