aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/e1000_82575.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-10-05 02:31:47 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-06 17:59:16 -0400
commit70d92f86dc162fc24e13cd79fd3481ae39b66f72 (patch)
treeb436d0f2463f88f1844b82deabe7cc5f02ef4104 /drivers/net/igb/e1000_82575.c
parentcc9073bbc901a0b695c9c5966d65520c29af70af (diff)
igb: update comments for serdes config and update to handle duplex
This update corrects the driver so that it handles duplex for serdes links correctly instead of just forcing full duplex always. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb/e1000_82575.c')
-rw-r--r--drivers/net/igb/e1000_82575.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index b60daf43cf27..5604b3e08f35 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -706,9 +706,7 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
706 s32 ret_val; 706 s32 ret_val;
707 u16 speed, duplex; 707 u16 speed, duplex;
708 708
709 /* SGMII link check is done through the PCS register. */ 709 if (hw->phy.media_type != e1000_media_type_copper) {
710 if ((hw->phy.media_type != e1000_media_type_copper) ||
711 (igb_sgmii_active_82575(hw))) {
712 ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed, 710 ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
713 &duplex); 711 &duplex);
714 /* 712 /*
@@ -723,6 +721,7 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
723 721
724 return ret_val; 722 return ret_val;
725} 723}
724
726/** 725/**
727 * igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex 726 * igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
728 * @hw: pointer to the HW structure 727 * @hw: pointer to the HW structure
@@ -788,13 +787,23 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
788void igb_shutdown_serdes_link_82575(struct e1000_hw *hw) 787void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
789{ 788{
790 u32 reg; 789 u32 reg;
790 u16 eeprom_data = 0;
791 791
792 if (hw->phy.media_type != e1000_media_type_internal_serdes || 792 if (hw->phy.media_type != e1000_media_type_internal_serdes ||
793 igb_sgmii_active_82575(hw)) 793 igb_sgmii_active_82575(hw))
794 return; 794 return;
795 795
796 /* if the management interface is not enabled, then power down */ 796 if (hw->bus.func == E1000_FUNC_0)
797 if (!igb_enable_mng_pass_thru(hw)) { 797 hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
798 else if (hw->bus.func == E1000_FUNC_1)
799 hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
800
801 /*
802 * If APM is not enabled in the EEPROM and management interface is
803 * not enabled, then power down.
804 */
805 if (!(eeprom_data & E1000_NVM_APME_82575) &&
806 !igb_enable_mng_pass_thru(hw)) {
798 /* Disable PCS to turn off link */ 807 /* Disable PCS to turn off link */
799 reg = rd32(E1000_PCS_CFG0); 808 reg = rd32(E1000_PCS_CFG0);
800 reg &= ~E1000_PCS_CFG_PCS_EN; 809 reg &= ~E1000_PCS_CFG_PCS_EN;
@@ -1010,10 +1019,13 @@ out:
1010} 1019}
1011 1020
1012/** 1021/**
1013 * igb_setup_serdes_link_82575 - Setup link for fiber/serdes 1022 * igb_setup_serdes_link_82575 - Setup link for serdes
1014 * @hw: pointer to the HW structure 1023 * @hw: pointer to the HW structure
1015 * 1024 *
1016 * Configures speed and duplex for fiber and serdes links. 1025 * Configure the physical coding sub-layer (PCS) link. The PCS link is
1026 * used on copper connections where the serialized gigabit media independent
1027 * interface (sgmii), or serdes fiber is being used. Configures the link
1028 * for auto-negotiation or forces speed/duplex.
1017 **/ 1029 **/
1018static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) 1030static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
1019{ 1031{
@@ -1086,18 +1098,27 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
1086 */ 1098 */
1087 if (hw->mac.autoneg || igb_sgmii_active_82575(hw)) { 1099 if (hw->mac.autoneg || igb_sgmii_active_82575(hw)) {
1088 /* Set PCS register for autoneg */ 1100 /* Set PCS register for autoneg */
1089 reg |= E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */ 1101 reg |= E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
1090 E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */ 1102 E1000_PCS_LCTL_FDV_FULL | /* SerDes Full dplx */
1091 E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */ 1103 E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
1092 E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */ 1104 E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
1093 hw_dbg("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg); 1105 hw_dbg("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
1094 } else { 1106 } else {
1095 /* Set PCS register for forced speed */ 1107 /* Check for duplex first */
1096 reg |= E1000_PCS_LCTL_FLV_LINK_UP | /* Force link up */ 1108 if (hw->mac.forced_speed_duplex & E1000_ALL_FULL_DUPLEX)
1097 E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */ 1109 reg |= E1000_PCS_LCTL_FDV_FULL;
1098 E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */ 1110
1099 E1000_PCS_LCTL_FSD | /* Force Speed */ 1111 /* No need to check for 1000/full since the spec states that
1100 E1000_PCS_LCTL_FORCE_LINK; /* Force Link */ 1112 * it requires autoneg to be enabled */
1113 /* Now set speed */
1114 if (hw->mac.forced_speed_duplex & E1000_ALL_100_SPEED)
1115 reg |= E1000_PCS_LCTL_FSV_100;
1116
1117 /* Force speed and force link */
1118 reg |= E1000_PCS_LCTL_FSD |
1119 E1000_PCS_LCTL_FORCE_LINK |
1120 E1000_PCS_LCTL_FLV_LINK_UP;
1121
1101 hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg); 1122 hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
1102 } 1123 }
1103 1124