X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Frt2x00%2Frt2500pci.c;h=c8cf8c1d095fb00903a807179e2abec6942c08e7;hb=475433be3d8f4d840e2930eef96671b7f8d11053;hp=4e312cb0ff0b315bdc7d0f57cafcf683253a5580;hpb=fd3c91c5e57eef8db71cf52e2473832c330bf5db;p=linux-2.6 diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 4e312cb0ff..c8cf8c1d09 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -244,39 +244,91 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) #endif /* CONFIG_RT2500PCI_RFKILL */ #ifdef CONFIG_RT2500PCI_LEDS -static void rt2500pci_led_brightness(struct led_classdev *led_cdev, +static void rt2500pci_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct rt2x00_led *led = container_of(led_cdev, struct rt2x00_led, led_dev); unsigned int enabled = brightness != LED_OFF; - unsigned int activity = - led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; u32 reg; rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); - if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { + if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) rt2x00_set_field32(®, LEDCSR_LINK, enabled); - rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled && activity); - } + else if (led->type == LED_TYPE_ACTIVITY) + rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); } -#else -#define rt2500pci_led_brightness NULL + +static int rt2500pci_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct rt2x00_led *led = + container_of(led_cdev, struct rt2x00_led, led_dev); + u32 reg; + + rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); + rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); + rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); + rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); + + return 0; +} + +static void rt2500pci_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 = rt2500pci_brightness_set; + led->led_dev.blink_set = rt2500pci_blink_set; + led->flags = LED_INITIALIZED; +} #endif /* CONFIG_RT2500PCI_LEDS */ /* * Configuration handlers. */ +static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev, + const unsigned int filter_flags) +{ + u32 reg; + + /* + * Start configuration steps. + * Note that the version error will always be dropped + * and broadcast frames will always be accepted since + * there is no filter for it at this time. + */ + rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00_set_field32(®, RXCSR0_DROP_CRC, + !(filter_flags & FIF_FCSFAIL)); + rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, + !(filter_flags & FIF_PLCPFAIL)); + rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, + !(filter_flags & FIF_CONTROL)); + rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, + !(filter_flags & FIF_PROMISC_IN_BSS)); + rt2x00_set_field32(®, RXCSR0_DROP_TODS, + !(filter_flags & FIF_PROMISC_IN_BSS) && + !rt2x00dev->intf_ap_count); + rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); + rt2x00_set_field32(®, RXCSR0_DROP_MCAST, + !(filter_flags & FIF_ALLMULTI)); + rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); + rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); +} + static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, struct rt2x00intf_conf *conf, const unsigned int flags) { - struct data_queue *queue = - rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); + struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON); unsigned int bcn_preload; u32 reg; @@ -309,8 +361,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, conf->bssid, sizeof(conf->bssid)); } -static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) +static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, + struct rt2x00lib_erp *erp) { int preamble_mask; u32 reg; @@ -328,7 +380,7 @@ static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); - rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00 | preamble_mask); + rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); @@ -350,8 +402,6 @@ static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); - - return 0; } static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, @@ -676,38 +726,33 @@ dynamic_cca_tune: static void rt2500pci_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, 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 rt2500pci_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, 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 rt2500pci_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; /* @@ -720,28 +765,28 @@ static int rt2500pci_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, ®); @@ -749,9 +794,10 @@ static int rt2500pci_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_tx->desc_dma); + rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, + entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); return 0; @@ -784,11 +830,6 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, CSR11_CW_SELECT, 0); rt2x00pci_register_write(rt2x00dev, CSR11, reg); - rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); - rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); - rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); - rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); - rt2x00pci_register_write(rt2x00dev, CNT3, 0); rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); @@ -894,25 +935,32 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) return 0; } -static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) +static int rt2500pci_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++) { rt2500pci_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 rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) +{ + unsigned int i; + u16 eeprom; + u8 reg_id; + u8 value; + + if (unlikely(rt2500pci_wait_bbp_ready(rt2x00dev))) + return -EACCES; -continue_csr_init: rt2500pci_bbp_write(rt2x00dev, 3, 0x02); rt2500pci_bbp_write(rt2x00dev, 4, 0x19); rt2500pci_bbp_write(rt2x00dev, 14, 0x1c); @@ -967,7 +1015,8 @@ static void rt2500pci_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); } @@ -1004,17 +1053,10 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Initialize all registers. */ - if (rt2500pci_init_queues(rt2x00dev) || - rt2500pci_init_registers(rt2x00dev) || - rt2500pci_init_bbp(rt2x00dev)) { - ERROR(rt2x00dev, "Register initialization failed.\n"); + if (unlikely(rt2500pci_init_queues(rt2x00dev) || + rt2500pci_init_registers(rt2x00dev) || + rt2500pci_init_bbp(rt2x00dev))) return -EIO; - } - - /* - * Enable interrupts. - */ - rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); return 0; } @@ -1036,11 +1078,6 @@ static void rt2500pci_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. - */ - rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); } static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, @@ -1075,10 +1112,6 @@ static int rt2500pci_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; } @@ -1096,11 +1129,13 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, break; case STATE_RADIO_RX_ON: case STATE_RADIO_RX_ON_LINK: - rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); - break; case STATE_RADIO_RX_OFF: case STATE_RADIO_RX_OFF_LINK: - rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); + rt2500pci_toggle_rx(rt2x00dev, state); + break; + case STATE_RADIO_IRQ_ON: + case STATE_RADIO_IRQ_OFF: + rt2500pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: @@ -1113,6 +1148,10 @@ static int rt2500pci_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; } @@ -1121,16 +1160,20 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, */ static void rt2500pci_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_IV_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); @@ -1164,9 +1207,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, - !!(control->flags & - IEEE80211_TXCTL_LONG_RETRY_LIMIT)); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); + test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); rt2x00_desc_write(txd, 0, word); } @@ -1175,11 +1216,11 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, * TX data initialization */ static void rt2500pci_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, ®); if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); @@ -1191,12 +1232,9 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, } rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, - (queue == IEEE80211_TX_QUEUE_DATA0)); - rt2x00_set_field32(®, TXCSR0_KICK_TX, - (queue == IEEE80211_TX_QUEUE_DATA1)); - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, - (queue == RT2X00_BCN_QUEUE_ATIM)); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); + rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); } @@ -1206,43 +1244,51 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, static void rt2500pci_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; - rt2x00_desc_read(priv_rx->desc, 0, &word0); - rt2x00_desc_read(priv_rx->desc, 2, &word2); + rt2x00_desc_read(entry_priv->desc, 0, &word0); + rt2x00_desc_read(entry_priv->desc, 2, &word2); - 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)) rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; + /* + * Obtain the status about this packet. + * When frame was received with an OFDM bitrate, + * the signal is the PLCP value. If it was received with + * a CCK bitrate the signal is the rate in 100kbit/s. + */ rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - entry->queue->rt2x00dev->rssi_offset; - rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); - rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); + + if (rt2x00_get_field32(word0, RXD_W0_OFDM)) + rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; + if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) + rxdesc->dev_flags |= RXDONE_MY_BSS; } /* * Interrupt functions. */ static void rt2500pci_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)) @@ -1251,7 +1297,18 @@ static void rt2500pci_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); @@ -1298,19 +1355,19 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) * 3 - Atim ring transmit done interrupt. */ if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) - rt2500pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); + rt2500pci_txdone(rt2x00dev, QID_ATIM); /* * 4 - Priority ring transmit done interrupt. */ if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) - rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); + rt2500pci_txdone(rt2x00dev, QID_AC_BE); /* * 5 - Tx ring transmit done interrupt. */ if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) - rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA1); + rt2500pci_txdone(rt2x00dev, QID_AC_BK); return IRQ_HANDLED; } @@ -1430,20 +1487,10 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) #ifdef CONFIG_RT2500PCI_LEDS value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); - switch (value) { - case LED_MODE_ASUS: - case LED_MODE_ALPHA: - case LED_MODE_DEFAULT: - rt2x00dev->led_flags = LED_SUPPORT_RADIO; - break; - case LED_MODE_TXRX_ACTIVITY: - rt2x00dev->led_flags = - LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; - break; - case LED_MODE_SIGNAL_STRENGTH: - rt2x00dev->led_flags = LED_SUPPORT_RADIO; - break; - } + rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); + if (value == LED_MODE_TXRX_ACTIVITY) + rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual, + LED_TYPE_ACTIVITY); #endif /* CONFIG_RT2500PCI_LEDS */ /* @@ -1636,11 +1683,10 @@ static void rt2500pci_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, @@ -1721,69 +1767,6 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) /* * IEEE80211 stack callback functions. */ -static void rt2500pci_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - int mc_count, - struct dev_addr_list *mc_list) -{ - struct rt2x00_dev *rt2x00dev = hw->priv; - u32 reg; - - /* - * Mask off any flags we are going to ignore from - * the total_flags field. - */ - *total_flags &= - FIF_ALLMULTI | - FIF_FCSFAIL | - FIF_PLCPFAIL | - FIF_CONTROL | - FIF_OTHER_BSS | - FIF_PROMISC_IN_BSS; - - /* - * Apply some rules to the filters: - * - Some filters imply different filters to be set. - * - Some things we can't filter out at all. - */ - if (mc_count) - *total_flags |= FIF_ALLMULTI; - if (*total_flags & FIF_OTHER_BSS || - *total_flags & FIF_PROMISC_IN_BSS) - *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; - - /* - * Check if there is any work left for us. - */ - if (rt2x00dev->packet_filter == *total_flags) - return; - rt2x00dev->packet_filter = *total_flags; - - /* - * Start configuration steps. - * Note that the version error will always be dropped - * and broadcast frames will always be accepted since - * there is no filter for it at this time. - */ - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); - rt2x00_set_field32(®, RXCSR0_DROP_CRC, - !(*total_flags & FIF_FCSFAIL)); - rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, - !(*total_flags & FIF_PLCPFAIL)); - rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, - !(*total_flags & FIF_CONTROL)); - rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, - !(*total_flags & FIF_PROMISC_IN_BSS)); - rt2x00_set_field32(®, RXCSR0_DROP_TODS, - !(*total_flags & FIF_PROMISC_IN_BSS)); - rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); - rt2x00_set_field32(®, RXCSR0_DROP_MCAST, - !(*total_flags & FIF_ALLMULTI)); - rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); -} - static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw, u32 short_retry, u32 long_retry) { @@ -1812,19 +1795,28 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) return tsf; } -static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ieee80211_tx_control *control) +static int rt2500pci_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 @@ -1834,7 +1826,7 @@ static int rt2500pci_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; @@ -1848,21 +1840,14 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, rt2x00_set_field32(®, 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; } @@ -1884,7 +1869,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { .remove_interface = rt2x00mac_remove_interface, .config = rt2x00mac_config, .config_interface = rt2x00mac_config_interface, - .configure_filter = rt2500pci_configure_filter, + .configure_filter = rt2x00mac_configure_filter, .get_stats = rt2x00mac_get_stats, .set_retry_limit = rt2500pci_set_retry_limit, .bss_info_changed = rt2x00mac_bss_info_changed, @@ -1907,11 +1892,11 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .link_stats = rt2500pci_link_stats, .reset_tuner = rt2500pci_reset_tuner, .link_tuner = rt2500pci_link_tuner, - .led_brightness = rt2500pci_led_brightness, .write_tx_desc = rt2500pci_write_tx_desc, .write_tx_data = rt2x00pci_write_tx_data, .kick_tx_queue = rt2500pci_kick_tx_queue, .fill_rxdone = rt2500pci_fill_rxdone, + .config_filter = rt2500pci_config_filter, .config_intf = rt2500pci_config_intf, .config_erp = rt2500pci_config_erp, .config = rt2500pci_config, @@ -1921,28 +1906,28 @@ static const struct data_queue_desc rt2500pci_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 rt2500pci_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 rt2500pci_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 rt2500pci_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 rt2500pci_ops = { @@ -1951,6 +1936,7 @@ static const struct rt2x00_ops rt2500pci_ops = { .max_ap_intf = 1, .eeprom_size = EEPROM_SIZE, .rf_size = RF_SIZE, + .tx_queues = NUM_TX_QUEUES, .rx = &rt2500pci_queue_rx, .tx = &rt2500pci_queue_tx, .bcn = &rt2500pci_queue_bcn,