aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2500pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c98
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
576static 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, &reg);
586 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
587 (libconf->conf->beacon_int - 20) * 16);
588 rt2x00_set_field32(&reg, 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(&reg, CSR20_AUTOWAKE, 0);
593 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
594
595 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
596 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
597 }
598
599 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
600}
601
576static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, 602static 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
614static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev) 642static 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
620static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) 651static 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
657static 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