diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 98 |
1 files changed, 65 insertions, 33 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d3bc218ec85c..b9104e28bc2e 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -573,6 +573,32 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
573 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | 573 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); |
574 | } | 574 | } |
575 | 575 | ||
576 | static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, | ||
577 | struct rt2x00lib_conf *libconf) | ||
578 | { | ||
579 | enum dev_state state = | ||
580 | (libconf->conf->flags & IEEE80211_CONF_PS) ? | ||
581 | STATE_SLEEP : STATE_AWAKE; | ||
582 | u32 reg; | ||
583 | |||
584 | if (state == STATE_SLEEP) { | ||
585 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); | ||
586 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, | ||
587 | (libconf->conf->beacon_int - 20) * 16); | ||
588 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, | ||
589 | libconf->conf->listen_interval - 1); | ||
590 | |||
591 | /* We must first disable autowake before it can be enabled */ | ||
592 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); | ||
593 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | ||
594 | |||
595 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); | ||
596 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | ||
597 | } | ||
598 | |||
599 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | ||
600 | } | ||
601 | |||
576 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | 602 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, |
577 | struct rt2x00lib_conf *libconf, | 603 | struct rt2x00lib_conf *libconf, |
578 | const unsigned int flags) | 604 | const unsigned int flags) |
@@ -588,6 +614,8 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | |||
588 | rt2500pci_config_retry_limit(rt2x00dev, libconf); | 614 | rt2500pci_config_retry_limit(rt2x00dev, libconf); |
589 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) | 615 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) |
590 | rt2500pci_config_duration(rt2x00dev, libconf); | 616 | rt2500pci_config_duration(rt2x00dev, libconf); |
617 | if (flags & IEEE80211_CONF_CHANGE_PS) | ||
618 | rt2500pci_config_ps(rt2x00dev, libconf); | ||
591 | } | 619 | } |
592 | 620 | ||
593 | /* | 621 | /* |
@@ -611,29 +639,33 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
611 | qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); | 639 | qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); |
612 | } | 640 | } |
613 | 641 | ||
614 | static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | 642 | static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, |
643 | struct link_qual *qual, u8 vgc_level) | ||
615 | { | 644 | { |
616 | rt2500pci_bbp_write(rt2x00dev, 17, 0x48); | 645 | if (qual->vgc_level_reg != vgc_level) { |
617 | rt2x00dev->link.vgc_level = 0x48; | 646 | rt2500pci_bbp_write(rt2x00dev, 17, vgc_level); |
647 | qual->vgc_level_reg = vgc_level; | ||
648 | } | ||
618 | } | 649 | } |
619 | 650 | ||
620 | static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | 651 | static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev, |
652 | struct link_qual *qual) | ||
621 | { | 653 | { |
622 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | 654 | rt2500pci_set_vgc(rt2x00dev, qual, 0x48); |
623 | u8 r17; | 655 | } |
624 | 656 | ||
657 | static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev, | ||
658 | struct link_qual *qual, const u32 count) | ||
659 | { | ||
625 | /* | 660 | /* |
626 | * To prevent collisions with MAC ASIC on chipsets | 661 | * To prevent collisions with MAC ASIC on chipsets |
627 | * up to version C the link tuning should halt after 20 | 662 | * up to version C the link tuning should halt after 20 |
628 | * seconds while being associated. | 663 | * seconds while being associated. |
629 | */ | 664 | */ |
630 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 665 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
631 | rt2x00dev->intf_associated && | 666 | rt2x00dev->intf_associated && count > 20) |
632 | rt2x00dev->link.count > 20) | ||
633 | return; | 667 | return; |
634 | 668 | ||
635 | rt2500pci_bbp_read(rt2x00dev, 17, &r17); | ||
636 | |||
637 | /* | 669 | /* |
638 | * Chipset versions C and lower should directly continue | 670 | * Chipset versions C and lower should directly continue |
639 | * to the dynamic CCA tuning. Chipset version D and higher | 671 | * to the dynamic CCA tuning. Chipset version D and higher |
@@ -649,29 +681,25 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
649 | * then corrupt the R17 tuning. To remidy this the tuning should | 681 | * then corrupt the R17 tuning. To remidy this the tuning should |
650 | * be stopped (While making sure the R17 value will not exceed limits) | 682 | * be stopped (While making sure the R17 value will not exceed limits) |
651 | */ | 683 | */ |
652 | if (rssi < -80 && rt2x00dev->link.count > 20) { | 684 | if (qual->rssi < -80 && count > 20) { |
653 | if (r17 >= 0x41) { | 685 | if (qual->vgc_level_reg >= 0x41) |
654 | r17 = rt2x00dev->link.vgc_level; | 686 | rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level); |
655 | rt2500pci_bbp_write(rt2x00dev, 17, r17); | ||
656 | } | ||
657 | return; | 687 | return; |
658 | } | 688 | } |
659 | 689 | ||
660 | /* | 690 | /* |
661 | * Special big-R17 for short distance | 691 | * Special big-R17 for short distance |
662 | */ | 692 | */ |
663 | if (rssi >= -58) { | 693 | if (qual->rssi >= -58) { |
664 | if (r17 != 0x50) | 694 | rt2500pci_set_vgc(rt2x00dev, qual, 0x50); |
665 | rt2500pci_bbp_write(rt2x00dev, 17, 0x50); | ||
666 | return; | 695 | return; |
667 | } | 696 | } |
668 | 697 | ||
669 | /* | 698 | /* |
670 | * Special mid-R17 for middle distance | 699 | * Special mid-R17 for middle distance |
671 | */ | 700 | */ |
672 | if (rssi >= -74) { | 701 | if (qual->rssi >= -74) { |
673 | if (r17 != 0x41) | 702 | rt2500pci_set_vgc(rt2x00dev, qual, 0x41); |
674 | rt2500pci_bbp_write(rt2x00dev, 17, 0x41); | ||
675 | return; | 703 | return; |
676 | } | 704 | } |
677 | 705 | ||
@@ -679,8 +707,8 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
679 | * Leave short or middle distance condition, restore r17 | 707 | * Leave short or middle distance condition, restore r17 |
680 | * to the dynamic tuning range. | 708 | * to the dynamic tuning range. |
681 | */ | 709 | */ |
682 | if (r17 >= 0x41) { | 710 | if (qual->vgc_level_reg >= 0x41) { |
683 | rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level); | 711 | rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level); |
684 | return; | 712 | return; |
685 | } | 713 | } |
686 | 714 | ||
@@ -690,12 +718,12 @@ dynamic_cca_tune: | |||
690 | * R17 is inside the dynamic tuning range, | 718 | * R17 is inside the dynamic tuning range, |
691 | * start tuning the link based on the false cca counter. | 719 | * start tuning the link based on the false cca counter. |
692 | */ | 720 | */ |
693 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) { | 721 | if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40) { |
694 | rt2500pci_bbp_write(rt2x00dev, 17, ++r17); | 722 | rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg); |
695 | rt2x00dev->link.vgc_level = r17; | 723 | qual->vgc_level = qual->vgc_level_reg; |
696 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) { | 724 | } else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32) { |
697 | rt2500pci_bbp_write(rt2x00dev, 17, --r17); | 725 | rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg); |
698 | rt2x00dev->link.vgc_level = r17; | 726 | qual->vgc_level = qual->vgc_level_reg; |
699 | } | 727 | } |
700 | } | 728 | } |
701 | 729 | ||
@@ -1205,7 +1233,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1205 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1233 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1206 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1234 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1207 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1235 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1208 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1236 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1209 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | 1237 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); |
1210 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1238 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1211 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1239 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
@@ -1524,7 +1552,9 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1524 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1552 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1525 | 1553 | ||
1526 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | 1554 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1527 | if (value == LED_MODE_TXRX_ACTIVITY) | 1555 | if (value == LED_MODE_TXRX_ACTIVITY || |
1556 | value == LED_MODE_DEFAULT || | ||
1557 | value == LED_MODE_ASUS) | ||
1528 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual, | 1558 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1529 | LED_TYPE_ACTIVITY); | 1559 | LED_TYPE_ACTIVITY); |
1530 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 1560 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
@@ -1721,7 +1751,9 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1721 | * Initialize all hw fields. | 1751 | * Initialize all hw fields. |
1722 | */ | 1752 | */ |
1723 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1753 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1724 | IEEE80211_HW_SIGNAL_DBM; | 1754 | IEEE80211_HW_SIGNAL_DBM | |
1755 | IEEE80211_HW_SUPPORTS_PS | | ||
1756 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
1725 | 1757 | ||
1726 | rt2x00dev->hw->extra_tx_headroom = 0; | 1758 | rt2x00dev->hw->extra_tx_headroom = 0; |
1727 | 1759 | ||