aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb
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
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')
-rw-r--r--drivers/net/igb/e1000_82575.c55
-rw-r--r--drivers/net/igb/e1000_82575.h1
-rw-r--r--drivers/net/igb/e1000_hw.h1
3 files changed, 40 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
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index ebd146fd4e15..7be3a0b6a057 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -167,6 +167,7 @@ struct e1000_adv_tx_context_desc {
167#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */ 167#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
168#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */ 168#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
169 169
170#define E1000_NVM_APME_82575 0x0400
170#define MAX_NUM_VFS 8 171#define MAX_NUM_VFS 8
171 172
172#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */ 173#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 119869b1124d..b1e0c0613a94 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -50,6 +50,7 @@ struct e1000_hw;
50#define E1000_REVISION_2 2 50#define E1000_REVISION_2 2
51#define E1000_REVISION_4 4 51#define E1000_REVISION_4 4
52 52
53#define E1000_FUNC_0 0
53#define E1000_FUNC_1 1 54#define E1000_FUNC_1 1
54 55
55enum e1000_mac_type { 56enum e1000_mac_type {