]> err.no Git - linux-2.6/blobdiff - drivers/net/wireless/rt2x00/rt2400pci.c
rt2x00: Move led initialization into function
[linux-2.6] / drivers / net / wireless / rt2x00 / rt2400pci.c
index 69b1dbd1adf0cc29818adce59f46e60ec45ce330..94226b47d1d9259266c2def716c88a14360dc6e4 100644 (file)
@@ -277,6 +277,17 @@ static int rt2400pci_blink_set(struct led_classdev *led_cdev,
 
        return 0;
 }
+
+static void rt2400pci_init_led(struct rt2x00_dev *rt2x00dev,
+                              struct rt2x00_led *led,
+                              enum led_type type)
+{
+       led->rt2x00dev = rt2x00dev;
+       led->type = type;
+       led->led_dev.brightness_set = rt2400pci_brightness_set;
+       led->led_dev.blink_set = rt2400pci_blink_set;
+       led->flags = LED_INITIALIZED;
+}
 #endif /* CONFIG_RT2400PCI_LEDS */
 
 /*
@@ -620,48 +631,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 +675,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 +704,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;
@@ -790,25 +792,32 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev)
        return 0;
 }
 
-static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
+static int rt2400pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
 {
        unsigned int i;
-       u16 eeprom;
-       u8 reg_id;
        u8 value;
 
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                rt2400pci_bbp_read(rt2x00dev, 0, &value);
                if ((value != 0xff) && (value != 0x00))
-                       goto continue_csr_init;
-               NOTICE(rt2x00dev, "Waiting for BBP register.\n");
+                       return 0;
                udelay(REGISTER_BUSY_DELAY);
        }
 
        ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
        return -EACCES;
+}
+
+static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+       unsigned int i;
+       u16 eeprom;
+       u8 reg_id;
+       u8 value;
+
+       if (unlikely(rt2400pci_wait_bbp_ready(rt2x00dev)))
+               return -EACCES;
 
-continue_csr_init:
        rt2400pci_bbp_write(rt2x00dev, 1, 0x00);
        rt2400pci_bbp_write(rt2x00dev, 3, 0x27);
        rt2400pci_bbp_write(rt2x00dev, 4, 0x08);
@@ -847,7 +856,8 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
 
        rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
        rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
-                          state == STATE_RADIO_RX_OFF);
+                          (state == STATE_RADIO_RX_OFF) ||
+                          (state == STATE_RADIO_RX_OFF_LINK));
        rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
 }
 
@@ -884,17 +894,10 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize all registers.
         */
-       if (rt2400pci_init_queues(rt2x00dev) ||
-           rt2400pci_init_registers(rt2x00dev) ||
-           rt2400pci_init_bbp(rt2x00dev)) {
-               ERROR(rt2x00dev, "Register initialization failed.\n");
+       if (unlikely(rt2400pci_init_queues(rt2x00dev) ||
+                    rt2400pci_init_registers(rt2x00dev) ||
+                    rt2400pci_init_bbp(rt2x00dev)))
                return -EIO;
-       }
-
-       /*
-        * Enable interrupts.
-        */
-       rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);
 
        return 0;
 }
@@ -916,11 +919,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
        rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
        rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
        rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
-
-       /*
-        * Disable interrupts.
-        */
-       rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF);
 }
 
 static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -955,10 +953,6 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
                msleep(10);
        }
 
-       NOTICE(rt2x00dev, "Device failed to enter state %d, "
-              "current device state: bbp %d and rf %d.\n",
-              state, bbp_state, rf_state);
-
        return -EBUSY;
 }
 
@@ -976,11 +970,13 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
                break;
        case STATE_RADIO_RX_ON:
        case STATE_RADIO_RX_ON_LINK:
-               rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
-               break;
        case STATE_RADIO_RX_OFF:
        case STATE_RADIO_RX_OFF_LINK:
-               rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+               rt2400pci_toggle_rx(rt2x00dev, state);
+               break;
+       case STATE_RADIO_IRQ_ON:
+       case STATE_RADIO_IRQ_OFF:
+               rt2400pci_toggle_irq(rt2x00dev, state);
                break;
        case STATE_DEEP_SLEEP:
        case STATE_SLEEP:
@@ -993,6 +989,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
                break;
        }
 
+       if (unlikely(retval))
+               ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+                     state, retval);
+
        return retval;
 }
 
@@ -1001,17 +1001,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 +1051,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);
 }
 
@@ -1083,16 +1087,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))
@@ -1108,7 +1111,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,15 +1123,15 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
                             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))
@@ -1306,23 +1309,10 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
 #ifdef CONFIG_RT2400PCI_LEDS
        value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
 
-       rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
-       rt2x00dev->led_radio.type = LED_TYPE_RADIO;
-       rt2x00dev->led_radio.led_dev.brightness_set =
-           rt2400pci_brightness_set;
-       rt2x00dev->led_radio.led_dev.blink_set =
-           rt2400pci_blink_set;
-       rt2x00dev->led_radio.flags = LED_INITIALIZED;
-
-       if (value == LED_MODE_TXRX_ACTIVITY) {
-               rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
-               rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY;
-               rt2x00dev->led_qual.led_dev.brightness_set =
-                   rt2400pci_brightness_set;
-               rt2x00dev->led_qual.led_dev.blink_set =
-                   rt2400pci_blink_set;
-               rt2x00dev->led_qual.flags = LED_INITIALIZED;
-       }
+       rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+       if (value == LED_MODE_TXRX_ACTIVITY)
+               rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
+                                  LED_TYPE_ACTIVITY);
 #endif /* CONFIG_RT2400PCI_LEDS */
 
        /*
@@ -1375,7 +1365,6 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
                               IEEE80211_HW_SIGNAL_DBM;
        rt2x00dev->hw->extra_tx_headroom = 0;
-       rt2x00dev->hw->queues = 2;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
        SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1491,18 +1480,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
@@ -1512,7 +1510,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;
 
@@ -1531,8 +1529,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);
+       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;
@@ -1592,28 +1590,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 = {
@@ -1622,6 +1620,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,