X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Frt2x00%2Frt2400pci.c;h=b3dffcfed835c9918f3433155dc7d9b54d9f893c;hb=d74f5ba473b915e5d4ea1ed391984bb62d9de8b1;hp=a491ba5bb5c36bb5e41287c0ccbf547d08cf81a5;hpb=dec13b6bda600c7e7da993e634562873112af50b;p=linux-2.6 diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index a491ba5bb5..b3dffcfed8 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -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,39 +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; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); u32 word; - rt2x00_desc_read(priv_rx->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_read(entry_priv->desc, 2, &word); + rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len); + 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, skbdesc->skb_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, 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; /* @@ -665,28 +675,28 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, 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, ®); rt2x00_set_field32(®, 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, ®); rt2x00_set_field32(®, 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, ®); rt2x00_set_field32(®, 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, ®); rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, - priv_tx->desc_dma); + entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); @@ -694,9 +704,10 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, 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, ®); - rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma); + rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, + entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); return 0; @@ -781,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); @@ -838,7 +856,8 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, 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); } @@ -875,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; } @@ -907,11 +919,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, 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, @@ -946,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; } @@ -967,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: @@ -984,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; } @@ -995,7 +1004,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci_tx *entry_priv = skbdesc->entry->priv_data; + struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; __le32 *txd = skbdesc->desc; u32 word; @@ -1003,12 +1012,12 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, * 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_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_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_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len); + rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len); rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 3, &word); @@ -1042,7 +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, -+ test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); + test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_desc_write(txd, 0, word); } @@ -1078,14 +1087,14 @@ 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); if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; @@ -1114,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)) @@ -1145,7 +1154,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, } txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); - rt2x00pci_txdone(rt2x00dev, entry, &txdesc); + rt2x00lib_txdone(entry, &txdesc); } } @@ -1300,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 */ /* @@ -1370,7 +1366,7 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_SIGNAL_DBM; rt2x00dev->hw->extra_tx_headroom = 0; - SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); + SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); @@ -1416,9 +1412,10 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) rt2400pci_probe_hw_mode(rt2x00dev); /* - * This device requires the atim queue + * This device requires the atim queue and DMA-mapped skbs. */ __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); /* * Set the rssi offset. @@ -1484,19 +1481,19 @@ 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, @@ -1504,17 +1501,14 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * for our information. */ intf->beacon->skb = skb; - rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control); + rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); /* * Fill in skb descriptor */ skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); - 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; @@ -1533,7 +1527,7 @@ 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. */ - memcpy(priv_tx->data, skb->data, skb->len); + rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); @@ -1594,28 +1588,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 = {