X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Frt2x00%2Frt2400pci.c;h=a491ba5bb5c36bb5e41287c0ccbf547d08cf81a5;hb=dec13b6bda600c7e7da993e634562873112af50b;hp=52ccb85fed659d109cdc71b317250151f38000fe;hpb=baf26a7eae3b05d25dd967b92eb2e09406ed9cf4;p=linux-2.6 diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 52ccb85fed..a491ba5bb5 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -244,32 +244,70 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) #endif /* CONFIG_RT2400PCI_RFKILL */ #ifdef CONFIG_RT2400PCI_LEDS -static void rt2400pci_led_brightness(struct led_classdev *led_cdev, +static void rt2400pci_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 rt2400pci_led_brightness NULL + +static int rt2400pci_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; +} #endif /* CONFIG_RT2400PCI_LEDS */ /* * Configuration handlers. */ +static void rt2400pci_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 + * 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); + rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); +} + static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, struct rt2x00intf_conf *conf, @@ -279,8 +317,6 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, u32 reg; if (flags & CONFIG_UPDATE_TYPE) { - rt2x00pci_register_write(rt2x00dev, CSR14, 0); - /* * Enable beacon config */ @@ -294,10 +330,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, */ rt2x00pci_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); - rt2x00_set_field32(®, CSR14_TBCN, - (conf->sync == TSF_SYNC_BEACON)); - rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); + rt2x00_set_field32(®, CSR14_TBCN, 1); rt2x00pci_register_write(rt2x00dev, CSR14, reg); } @@ -310,10 +344,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, conf->bssid, sizeof(conf->bssid)); } -static int rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, - const int short_preamble, - const int ack_timeout, - const int ack_consume_time) +static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, + struct rt2x00lib_erp *erp) { int preamble_mask; u32 reg; @@ -321,15 +353,17 @@ static int rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, /* * When short preamble is enabled, we should set bit 0x08 */ - preamble_mask = short_preamble << 3; + preamble_mask = erp->short_preamble << 3; rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); - rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, ack_timeout); - rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, ack_consume_time); + rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, + erp->ack_timeout); + rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, + erp->ack_consume_time); 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); @@ -351,8 +385,6 @@ static int rt2400pci_config_preamble(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 rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, @@ -423,6 +455,13 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, u8 r1; u8 r4; + /* + * We should never come here because rt2x00lib is supposed + * to catch this and send us the correct antenna explicitely. + */ + BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || + ant->tx == ANTENNA_SW_DIVERSITY); + rt2400pci_bbp_read(rt2x00dev, 4, &r4); rt2400pci_bbp_read(rt2x00dev, 1, &r1); @@ -436,14 +475,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, case ANTENNA_A: rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0); break; - case ANTENNA_SW_DIVERSITY: - /* - * NOTE: We should never come here because rt2x00lib is - * supposed to catch this and send us the correct antenna - * explicitely. However we are nog going to bug about this. - * Instead, just default to antenna B. - */ case ANTENNA_B: + default: rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2); break; } @@ -458,14 +491,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, case ANTENNA_A: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0); break; - case ANTENNA_SW_DIVERSITY: - /* - * NOTE: We should never come here because rt2x00lib is - * supposed to catch this and send us the correct antenna - * explicitely. However we are nog going to bug about this. - * Instead, just default to antenna B. - */ case ANTENNA_B: + default: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); break; } @@ -597,11 +624,12 @@ static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, u32 word; rt2x00_desc_read(priv_rx->desc, 2, &word); - rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->queue->data_size); + rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, + entry->queue->data_size); rt2x00_desc_write(priv_rx->desc, 2, word); rt2x00_desc_read(priv_rx->desc, 1, &word); - rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->dma); + rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); rt2x00_desc_write(priv_rx->desc, 1, word); rt2x00_desc_read(priv_rx->desc, 0, &word); @@ -615,15 +643,6 @@ static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; u32 word; - rt2x00_desc_read(priv_tx->desc, 1, &word); - rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->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_set_field32(&word, TXD_W0_VALID, 0); rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); @@ -648,22 +667,26 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) priv_tx = rt2x00dev->tx[1].entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); - rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, priv_tx->dma); + rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, + priv_tx->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); priv_tx = rt2x00dev->tx[0].entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); - rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, priv_tx->dma); + rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, + priv_tx->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); - rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, priv_tx->dma); + rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, + priv_tx->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); - rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, priv_tx->dma); + rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, + priv_tx->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); @@ -673,7 +696,7 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) priv_rx = rt2x00dev->rx->entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); - rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->dma); + rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma); rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); return 0; @@ -699,11 +722,6 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) (rt2x00dev->rx->data_size / 128)); rt2x00pci_register_write(rt2x00dev, CSR9, 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, 0x3f080000); rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); @@ -974,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_tx *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); @@ -1019,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); } @@ -1028,13 +1050,15 @@ 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, ®); if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { + rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); + rt2x00_set_field32(®, CSR14_TBCN, 1); rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); rt2x00pci_register_write(rt2x00dev, CSR14, reg); } @@ -1042,12 +1066,9 @@ static void rt2400pci_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); } @@ -1060,11 +1081,12 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, struct queue_entry_priv_pci_rx *priv_rx = 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); - 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)) @@ -1072,20 +1094,24 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, /* * Obtain the status about this packet. + * The signal is the PLCP value, and needs to be stripped + * of the preamble bit (0x08). */ - rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); - rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - + rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; + rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - entry->queue->rt2x00dev->rssi_offset; - rxdesc->ofdm = 0; rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); - rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); + + 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 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; @@ -1105,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); @@ -1152,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; } @@ -1263,19 +1300,22 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) #ifdef CONFIG_RT2400PCI_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; + 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; } #endif /* CONFIG_RT2400PCI_LEDS */ @@ -1326,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, @@ -1347,8 +1385,8 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Initialize hw_mode information. */ - spec->num_modes = 1; - spec->num_rates = 4; + spec->supported_bands = SUPPORT_BAND_2GHZ; + spec->supported_rates = SUPPORT_RATE_CCK; spec->tx_power_a = NULL; spec->tx_power_bg = txpower; spec->tx_power_default = DEFAULT_TXPOWER; @@ -1393,64 +1431,6 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) /* * IEEE80211 stack callback functions. */ -static void rt2400pci_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. - */ - *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 - * 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); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); -} - static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw, u32 short_retry, u32 long_retry) { @@ -1465,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; @@ -1476,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)) @@ -1505,14 +1484,6 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw) return tsf; } -static void rt2400pci_reset_tsf(struct ieee80211_hw *hw) -{ - struct rt2x00_dev *rt2x00dev = hw->priv; - - rt2x00pci_register_write(rt2x00dev, CSR16, 0); - rt2x00pci_register_write(rt2x00dev, CSR17, 0); -} - static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { @@ -1520,12 +1491,21 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct rt2x00_intf *intf = vif_to_intf(control->vif); struct queue_entry_priv_pci_tx *priv_tx; struct skb_frame_desc *skbdesc; + struct txentry_desc txdesc; + u32 reg; if (unlikely(!intf->beacon)) return -ENOBUFS; - priv_tx = 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, control); + /* * Fill in skb descriptor */ @@ -1539,12 +1519,14 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, skbdesc->entry = intf->beacon; /* - * mac80211 doesn't provide the control->queue variable - * for beacons. Set our own queue identification so - * it can be used during descriptor initialization. + * Disable beaconing while we are reloading the beacon data, + * otherwise we might be sending out invalid data. */ - control->queue = RT2X00_BCN_QUEUE_BEACON; - rt2x00lib_write_tx_desc(rt2x00dev, skb, control); + rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); + rt2x00_set_field32(®, CSR14_TBCN, 0); + rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); + rt2x00pci_register_write(rt2x00dev, CSR14, reg); /* * Enable beacon generation. @@ -1552,7 +1534,8 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * and kick the beacon generator. */ memcpy(priv_tx->data, skb->data, skb->len); - rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); + rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); + rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); return 0; } @@ -1574,14 +1557,13 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { .remove_interface = rt2x00mac_remove_interface, .config = rt2x00mac_config, .config_interface = rt2x00mac_config_interface, - .configure_filter = rt2400pci_configure_filter, + .configure_filter = rt2x00mac_configure_filter, .get_stats = rt2x00mac_get_stats, .set_retry_limit = rt2400pci_set_retry_limit, .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt2400pci_conf_tx, .get_tx_stats = rt2x00mac_get_tx_stats, .get_tsf = rt2400pci_get_tsf, - .reset_tsf = rt2400pci_reset_tsf, .beacon_update = rt2400pci_beacon_update, .tx_last_beacon = rt2400pci_tx_last_beacon, }; @@ -1598,13 +1580,13 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .link_stats = rt2400pci_link_stats, .reset_tuner = rt2400pci_reset_tuner, .link_tuner = rt2400pci_link_tuner, - .led_brightness = rt2400pci_led_brightness, .write_tx_desc = rt2400pci_write_tx_desc, .write_tx_data = rt2x00pci_write_tx_data, .kick_tx_queue = rt2400pci_kick_tx_queue, .fill_rxdone = rt2400pci_fill_rxdone, + .config_filter = rt2400pci_config_filter, .config_intf = rt2400pci_config_intf, - .config_preamble = rt2400pci_config_preamble, + .config_erp = rt2400pci_config_erp, .config = rt2400pci_config, }; @@ -1642,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,