diff options
| author | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-11 14:36:25 +0100 | 
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-11 14:36:25 +0100 | 
| commit | a8931ef380c92d121ae74ecfb03b2d63f72eea6f (patch) | |
| tree | 980fb6b019e11e6cb1ece55b7faff184721a8053 /drivers/net/e1000e/ich8lan.c | |
| parent | 90574d0a4d4b73308ae54a2a57a4f3f1fa98e984 (diff) | |
| parent | e5a5816f7875207cb0a0a7032e39a4686c5e10a4 (diff) | |
| download | olio-linux-3.10-a8931ef380c92d121ae74ecfb03b2d63f72eea6f.tar.xz olio-linux-3.10-a8931ef380c92d121ae74ecfb03b2d63f72eea6f.zip  | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/net/e1000e/ich8lan.c')
| -rw-r--r-- | drivers/net/e1000e/ich8lan.c | 83 | 
1 files changed, 82 insertions, 1 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 768485dbb2c..9e38452a738 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -38,6 +38,12 @@   * 82566DM Gigabit Network Connection   * 82566MC Gigabit Network Connection   * 82566MM Gigabit Network Connection + * 82567LM Gigabit Network Connection + * 82567LF Gigabit Network Connection + * 82567LM-2 Gigabit Network Connection + * 82567LF-2 Gigabit Network Connection + * 82567V-2 Gigabit Network Connection + * 82562GT-3 10/100 Network Connection   */  #include <linux/netdevice.h> @@ -198,6 +204,19 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)  	phy->addr			= 1;  	phy->reset_delay_us		= 100; +	/* +	 * We may need to do this twice - once for IGP and if that fails, +	 * we'll set BM func pointers and try again +	 */ +	ret_val = e1000e_determine_phy_address(hw); +	if (ret_val) { +		hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm; +		hw->phy.ops.read_phy_reg  = e1000e_read_phy_reg_bm; +		ret_val = e1000e_determine_phy_address(hw); +		if (ret_val) +			return ret_val; +	} +  	phy->id = 0;  	while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&  	       (i++ < 100)) { @@ -219,6 +238,13 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)  		phy->type = e1000_phy_ife;  		phy->autoneg_mask = E1000_ALL_NOT_GIG;  		break; +	case BME1000_E_PHY_ID: +		phy->type = e1000_phy_bm; +		phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; +		hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm; +		hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm; +		hw->phy.ops.commit_phy = e1000e_phy_sw_reset; +		break;  	default:  		return -E1000_ERR_PHY;  		break; @@ -664,6 +690,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)  		return e1000_get_phy_info_ife_ich8lan(hw);  		break;  	case e1000_phy_igp_3: +	case e1000_phy_bm:  		return e1000e_get_phy_info_igp(hw);  		break;  	default: @@ -728,7 +755,7 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)  	s32 ret_val = 0;  	u16 data; -	if (phy->type != e1000_phy_igp_3) +	if (phy->type == e1000_phy_ife)  		return ret_val;  	phy_ctrl = er32(PHY_CTRL); @@ -1918,8 +1945,35 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)  		ret_val = e1000e_copper_link_setup_igp(hw);  		if (ret_val)  			return ret_val; +	} else if (hw->phy.type == e1000_phy_bm) { +		ret_val = e1000e_copper_link_setup_m88(hw); +		if (ret_val) +			return ret_val;  	} +	if (hw->phy.type == e1000_phy_ife) { +		ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, ®_data); +		if (ret_val) +			return ret_val; + +		reg_data &= ~IFE_PMC_AUTO_MDIX; + +		switch (hw->phy.mdix) { +		case 1: +			reg_data &= ~IFE_PMC_FORCE_MDIX; +			break; +		case 2: +			reg_data |= IFE_PMC_FORCE_MDIX; +			break; +		case 0: +		default: +			reg_data |= IFE_PMC_AUTO_MDIX; +			break; +		} +		ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data); +		if (ret_val) +			return ret_val; +	}  	return e1000e_setup_copper_link(hw);  } @@ -2127,6 +2181,31 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)  }  /** + *  e1000e_disable_gig_wol_ich8lan - disable gig during WoL + *  @hw: pointer to the HW structure + * + *  During S0 to Sx transition, it is possible the link remains at gig + *  instead of negotiating to a lower speed.  Before going to Sx, set + *  'LPLU Enabled' and 'Gig Disable' to force link speed negotiation + *  to a lower speed. + * + *  Should only be called for ICH9 devices. + **/ +void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) +{ +	u32 phy_ctrl; + +	if (hw->mac.type == e1000_ich9lan) { +		phy_ctrl = er32(PHY_CTRL); +		phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | +		            E1000_PHY_CTRL_GBE_DISABLE; +		ew32(PHY_CTRL, phy_ctrl); +	} + +	return; +} + +/**   *  e1000_cleanup_led_ich8lan - Restore the default LED operation   *  @hw: pointer to the HW structure   * @@ -2247,6 +2326,7 @@ static struct e1000_nvm_operations ich8_nvm_ops = {  struct e1000_info e1000_ich8_info = {  	.mac			= e1000_ich8lan,  	.flags			= FLAG_HAS_WOL +				  | FLAG_IS_ICH  				  | FLAG_RX_CSUM_ENABLED  				  | FLAG_HAS_CTRLEXT_ON_LOAD  				  | FLAG_HAS_AMT @@ -2262,6 +2342,7 @@ struct e1000_info e1000_ich8_info = {  struct e1000_info e1000_ich9_info = {  	.mac			= e1000_ich9lan,  	.flags			= FLAG_HAS_JUMBO_FRAMES +				  | FLAG_IS_ICH  				  | FLAG_HAS_WOL  				  | FLAG_RX_CSUM_ENABLED  				  | FLAG_HAS_CTRLEXT_ON_LOAD  |