diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2006-09-27 15:53:51 -0400 |
---|---|---|
committer | Auke Kok <juke-jan.h.kok@intel.com> | 2006-09-27 15:53:51 -0400 |
commit | 09ae3e88662478c014617291e5a2115e6b2f65eb (patch) | |
tree | 75bda0753b1e751933cd35dc565adb67f619dfed /drivers/net/e1000/e1000_hw.c | |
parent | 65c7973fa5b46b024f38be208aa477e8daf9a603 (diff) |
e1000: gather hardware bit tweaks.
Several hardware bits were set all over the driver and have been
consolidated into a single function.
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers/net/e1000/e1000_hw.c')
-rw-r--r-- | drivers/net/e1000/e1000_hw.c | 155 |
1 files changed, 131 insertions, 24 deletions
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 6ec5cdddb5aa..dceaf5bd5f5b 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c | |||
@@ -61,6 +61,7 @@ static int32_t e1000_id_led_init(struct e1000_hw *hw); | |||
61 | static int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size); | 61 | static int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size); |
62 | static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw); | 62 | static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw); |
63 | static void e1000_init_rx_addrs(struct e1000_hw *hw); | 63 | static void e1000_init_rx_addrs(struct e1000_hw *hw); |
64 | static void e1000_initialize_hardware_bits(struct e1000_hw *hw); | ||
64 | static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw); | 65 | static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw); |
65 | static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw); | 66 | static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw); |
66 | static int32_t e1000_mng_enable_host_if(struct e1000_hw *hw); | 67 | static int32_t e1000_mng_enable_host_if(struct e1000_hw *hw); |
@@ -716,6 +717,123 @@ e1000_reset_hw(struct e1000_hw *hw) | |||
716 | } | 717 | } |
717 | 718 | ||
718 | /****************************************************************************** | 719 | /****************************************************************************** |
720 | * | ||
721 | * Initialize a number of hardware-dependent bits | ||
722 | * | ||
723 | * hw: Struct containing variables accessed by shared code | ||
724 | * | ||
725 | * This function contains hardware limitation workarounds for PCI-E adapters | ||
726 | * | ||
727 | *****************************************************************************/ | ||
728 | static void | ||
729 | e1000_initialize_hardware_bits(struct e1000_hw *hw) | ||
730 | { | ||
731 | if ((hw->mac_type >= e1000_82571) && (!hw->initialize_hw_bits_disable)) { | ||
732 | /* Settings common to all PCI-express silicon */ | ||
733 | uint32_t reg_ctrl, reg_ctrl_ext; | ||
734 | uint32_t reg_tarc0, reg_tarc1; | ||
735 | uint32_t reg_tctl; | ||
736 | uint32_t reg_txdctl, reg_txdctl1; | ||
737 | |||
738 | /* link autonegotiation/sync workarounds */ | ||
739 | reg_tarc0 = E1000_READ_REG(hw, TARC0); | ||
740 | reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)); | ||
741 | |||
742 | /* Enable not-done TX descriptor counting */ | ||
743 | reg_txdctl = E1000_READ_REG(hw, TXDCTL); | ||
744 | reg_txdctl |= E1000_TXDCTL_COUNT_DESC; | ||
745 | E1000_WRITE_REG(hw, TXDCTL, reg_txdctl); | ||
746 | reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1); | ||
747 | reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC; | ||
748 | E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1); | ||
749 | |||
750 | switch (hw->mac_type) { | ||
751 | case e1000_82571: | ||
752 | case e1000_82572: | ||
753 | /* Clear PHY TX compatible mode bits */ | ||
754 | reg_tarc1 = E1000_READ_REG(hw, TARC1); | ||
755 | reg_tarc1 &= ~((1 << 30)|(1 << 29)); | ||
756 | |||
757 | /* link autonegotiation/sync workarounds */ | ||
758 | reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23)); | ||
759 | |||
760 | /* TX ring control fixes */ | ||
761 | reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24)); | ||
762 | |||
763 | /* Multiple read bit is reversed polarity */ | ||
764 | reg_tctl = E1000_READ_REG(hw, TCTL); | ||
765 | if (reg_tctl & E1000_TCTL_MULR) | ||
766 | reg_tarc1 &= ~(1 << 28); | ||
767 | else | ||
768 | reg_tarc1 |= (1 << 28); | ||
769 | |||
770 | E1000_WRITE_REG(hw, TARC1, reg_tarc1); | ||
771 | break; | ||
772 | case e1000_82573: | ||
773 | reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); | ||
774 | reg_ctrl_ext &= ~(1 << 23); | ||
775 | reg_ctrl_ext |= (1 << 22); | ||
776 | |||
777 | /* TX byte count fix */ | ||
778 | reg_ctrl = E1000_READ_REG(hw, CTRL); | ||
779 | reg_ctrl &= ~(1 << 29); | ||
780 | |||
781 | E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext); | ||
782 | E1000_WRITE_REG(hw, CTRL, reg_ctrl); | ||
783 | break; | ||
784 | case e1000_80003es2lan: | ||
785 | /* improve small packet performace for fiber/serdes */ | ||
786 | if ((hw->media_type == e1000_media_type_fiber) || | ||
787 | (hw->media_type == e1000_media_type_internal_serdes)) { | ||
788 | reg_tarc0 &= ~(1 << 20); | ||
789 | } | ||
790 | |||
791 | /* Multiple read bit is reversed polarity */ | ||
792 | reg_tctl = E1000_READ_REG(hw, TCTL); | ||
793 | reg_tarc1 = E1000_READ_REG(hw, TARC1); | ||
794 | if (reg_tctl & E1000_TCTL_MULR) | ||
795 | reg_tarc1 &= ~(1 << 28); | ||
796 | else | ||
797 | reg_tarc1 |= (1 << 28); | ||
798 | |||
799 | E1000_WRITE_REG(hw, TARC1, reg_tarc1); | ||
800 | break; | ||
801 | case e1000_ich8lan: | ||
802 | /* Reduce concurrent DMA requests to 3 from 4 */ | ||
803 | if ((hw->revision_id < 3) || | ||
804 | ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) && | ||
805 | (hw->device_id != E1000_DEV_ID_ICH8_IGP_M))) | ||
806 | reg_tarc0 |= ((1 << 29)|(1 << 28)); | ||
807 | |||
808 | reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); | ||
809 | reg_ctrl_ext |= (1 << 22); | ||
810 | E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext); | ||
811 | |||
812 | /* workaround TX hang with TSO=on */ | ||
813 | reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)); | ||
814 | |||
815 | /* Multiple read bit is reversed polarity */ | ||
816 | reg_tctl = E1000_READ_REG(hw, TCTL); | ||
817 | reg_tarc1 = E1000_READ_REG(hw, TARC1); | ||
818 | if (reg_tctl & E1000_TCTL_MULR) | ||
819 | reg_tarc1 &= ~(1 << 28); | ||
820 | else | ||
821 | reg_tarc1 |= (1 << 28); | ||
822 | |||
823 | /* workaround TX hang with TSO=on */ | ||
824 | reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24)); | ||
825 | |||
826 | E1000_WRITE_REG(hw, TARC1, reg_tarc1); | ||
827 | break; | ||
828 | default: | ||
829 | break; | ||
830 | } | ||
831 | |||
832 | E1000_WRITE_REG(hw, TARC0, reg_tarc0); | ||
833 | } | ||
834 | } | ||
835 | |||
836 | /****************************************************************************** | ||
719 | * Performs basic configuration of the adapter. | 837 | * Performs basic configuration of the adapter. |
720 | * | 838 | * |
721 | * hw - Struct containing variables accessed by shared code | 839 | * hw - Struct containing variables accessed by shared code |
@@ -743,14 +861,13 @@ e1000_init_hw(struct e1000_hw *hw) | |||
743 | DEBUGFUNC("e1000_init_hw"); | 861 | DEBUGFUNC("e1000_init_hw"); |
744 | 862 | ||
745 | /* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */ | 863 | /* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */ |
746 | if (hw->mac_type == e1000_ich8lan) { | 864 | if ((hw->mac_type == e1000_ich8lan) && |
747 | reg_data = E1000_READ_REG(hw, TARC0); | 865 | ((hw->revision_id < 3) || |
748 | reg_data |= 0x30000000; | 866 | ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) && |
749 | E1000_WRITE_REG(hw, TARC0, reg_data); | 867 | (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) { |
750 | 868 | reg_data = E1000_READ_REG(hw, STATUS); | |
751 | reg_data = E1000_READ_REG(hw, STATUS); | 869 | reg_data &= ~0x80000000; |
752 | reg_data &= ~0x80000000; | 870 | E1000_WRITE_REG(hw, STATUS, reg_data); |
753 | E1000_WRITE_REG(hw, STATUS, reg_data); | ||
754 | } | 871 | } |
755 | 872 | ||
756 | /* Initialize Identification LED */ | 873 | /* Initialize Identification LED */ |
@@ -763,6 +880,9 @@ e1000_init_hw(struct e1000_hw *hw) | |||
763 | /* Set the media type and TBI compatibility */ | 880 | /* Set the media type and TBI compatibility */ |
764 | e1000_set_media_type(hw); | 881 | e1000_set_media_type(hw); |
765 | 882 | ||
883 | /* Must be called after e1000_set_media_type because media_type is used */ | ||
884 | e1000_initialize_hardware_bits(hw); | ||
885 | |||
766 | /* Disabling VLAN filtering. */ | 886 | /* Disabling VLAN filtering. */ |
767 | DEBUGOUT("Initializing the IEEE VLAN\n"); | 887 | DEBUGOUT("Initializing the IEEE VLAN\n"); |
768 | /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */ | 888 | /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */ |
@@ -854,17 +974,6 @@ e1000_init_hw(struct e1000_hw *hw) | |||
854 | if (hw->mac_type > e1000_82544) { | 974 | if (hw->mac_type > e1000_82544) { |
855 | ctrl = E1000_READ_REG(hw, TXDCTL); | 975 | ctrl = E1000_READ_REG(hw, TXDCTL); |
856 | ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; | 976 | ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; |
857 | switch (hw->mac_type) { | ||
858 | default: | ||
859 | break; | ||
860 | case e1000_82571: | ||
861 | case e1000_82572: | ||
862 | case e1000_82573: | ||
863 | case e1000_ich8lan: | ||
864 | case e1000_80003es2lan: | ||
865 | ctrl |= E1000_TXDCTL_COUNT_DESC; | ||
866 | break; | ||
867 | } | ||
868 | E1000_WRITE_REG(hw, TXDCTL, ctrl); | 977 | E1000_WRITE_REG(hw, TXDCTL, ctrl); |
869 | } | 978 | } |
870 | 979 | ||
@@ -902,8 +1011,6 @@ e1000_init_hw(struct e1000_hw *hw) | |||
902 | case e1000_ich8lan: | 1011 | case e1000_ich8lan: |
903 | ctrl = E1000_READ_REG(hw, TXDCTL1); | 1012 | ctrl = E1000_READ_REG(hw, TXDCTL1); |
904 | ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; | 1013 | ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; |
905 | if (hw->mac_type >= e1000_82571) | ||
906 | ctrl |= E1000_TXDCTL_COUNT_DESC; | ||
907 | E1000_WRITE_REG(hw, TXDCTL1, ctrl); | 1014 | E1000_WRITE_REG(hw, TXDCTL1, ctrl); |
908 | break; | 1015 | break; |
909 | } | 1016 | } |
@@ -1143,11 +1250,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw) | |||
1143 | if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) | 1250 | if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) |
1144 | E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK); | 1251 | E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK); |
1145 | 1252 | ||
1146 | /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be | 1253 | /* On adapters with a MAC newer than 82544, SWDP 1 will be |
1147 | * set when the optics detect a signal. On older adapters, it will be | 1254 | * set when the optics detect a signal. On older adapters, it will be |
1148 | * cleared when there is a signal. This applies to fiber media only. | 1255 | * cleared when there is a signal. This applies to fiber media only. |
1149 | * If we're on serdes media, adjust the output amplitude to value set in | 1256 | * If we're on serdes media, adjust the output amplitude to value |
1150 | * the EEPROM. | 1257 | * set in the EEPROM. |
1151 | */ | 1258 | */ |
1152 | ctrl = E1000_READ_REG(hw, CTRL); | 1259 | ctrl = E1000_READ_REG(hw, CTRL); |
1153 | if (hw->media_type == e1000_media_type_fiber) | 1260 | if (hw->media_type == e1000_media_type_fiber) |