⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ich8lan.c

📁 grub源码分析文档
💻 C
📖 第 1 页 / 共 5 页
字号:
 *  control.  Calls the appropriate media-specific link configuration *  function.  Assuming the adapter has a valid link partner, a valid link *  should be established.  Assumes the hardware has previously been reset *  and the transmitter and receiver are not enabled. **/static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw){	s32 ret_val;	if (e1000_check_reset_block(hw))		return 0;	/*	 * ICH parts do not have a word in the NVM to determine	 * the default flow control setting, so we explicitly	 * set it to full.	 */	if (hw->fc.type == e1000_fc_default)		hw->fc.type = e1000_fc_full;	hw->fc.original_type = hw->fc.type;	hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);	/* Continue to configure the copper link. */	ret_val = e1000_setup_copper_link_ich8lan(hw);	if (ret_val)		return ret_val;	ew32(FCTTV, hw->fc.pause_time);	return e1000e_set_fc_watermarks(hw);}/** *  e1000_setup_copper_link_ich8lan - Configure MAC/PHY interface *  @hw: pointer to the HW structure * *  Configures the kumeran interface to the PHY to wait the appropriate time *  when polling the PHY, then call the generic setup_copper_link to finish *  configuring the copper link. **/static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw){	u32 ctrl;	s32 ret_val;	u16 reg_data;	ctrl = er32(CTRL);	ctrl |= E1000_CTRL_SLU;	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);	ew32(CTRL, ctrl);	/*	 * Set the mac to wait the maximum time between each iteration	 * and increase the max iterations when polling the phy;	 * this fixes erroneous timeouts at 10Mbps.	 */	ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);	if (ret_val)		return ret_val;	ret_val = e1000e_read_kmrn_reg(hw, GG82563_REG(0x34, 9), &reg_data);	if (ret_val)		return ret_val;	reg_data |= 0x3F;	ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data);	if (ret_val)		return ret_val;	if (hw->phy.type == e1000_phy_igp_3) {		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, &reg_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);}/** *  e1000_get_link_up_info_ich8lan - Get current link speed and duplex *  @hw: pointer to the HW structure *  @speed: pointer to store current link speed *  @duplex: pointer to store the current link duplex * *  Calls the generic get_speed_and_duplex to retrieve the current link *  information and then calls the Kumeran lock loss workaround for links at *  gigabit speeds. **/static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,					  u16 *duplex){	s32 ret_val;	ret_val = e1000e_get_speed_and_duplex_copper(hw, speed, duplex);	if (ret_val)		return ret_val;	if ((hw->mac.type == e1000_ich8lan) &&	    (hw->phy.type == e1000_phy_igp_3) &&	    (*speed == SPEED_1000)) {		ret_val = e1000_kmrn_lock_loss_workaround_ich8lan(hw);	}	return ret_val;}/** *  e1000_kmrn_lock_loss_workaround_ich8lan - Kumeran workaround *  @hw: pointer to the HW structure * *  Work-around for 82566 Kumeran PCS lock loss: *  On link status change (i.e. PCI reset, speed change) and link is up and *  speed is gigabit- *    0) if workaround is optionally disabled do nothing *    1) wait 1ms for Kumeran link to come up *    2) check Kumeran Diagnostic register PCS lock loss bit *    3) if not set the link is locked (all is good), otherwise... *    4) reset the PHY *    5) repeat up to 10 times *  Note: this is only called for IGP3 copper when speed is 1gb. **/static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw){	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;	u32 phy_ctrl;	s32 ret_val;	u16 i, data;	bool link;	if (!dev_spec->kmrn_lock_loss_workaround_enabled)		return 0;	/*	 * Make sure link is up before proceeding.  If not just return.	 * Attempting this while link is negotiating fouled up link	 * stability	 */	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);	if (!link)		return 0;	for (i = 0; i < 10; i++) {		/* read once to clear */		ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data);		if (ret_val)			return ret_val;		/* and again to get new status */		ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data);		if (ret_val)			return ret_val;		/* check for PCS lock */		if (!(data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS))			return 0;		/* Issue PHY reset */		e1000_phy_hw_reset(hw);		mdelay(5);	}	/* Disable GigE link negotiation */	phy_ctrl = er32(PHY_CTRL);	phy_ctrl |= (E1000_PHY_CTRL_GBE_DISABLE |		     E1000_PHY_CTRL_NOND0A_GBE_DISABLE);	ew32(PHY_CTRL, phy_ctrl);	/*	 * Call gig speed drop workaround on Gig disable before accessing	 * any PHY registers	 */	e1000e_gig_downshift_workaround_ich8lan(hw);	/* unable to acquire PCS lock */	return -E1000_ERR_PHY;}/** *  e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state *  @hw: pointer to the HW structure *  @state: boolean value used to set the current Kumeran workaround state * *  If ICH8, set the current Kumeran workaround state (enabled - TRUE *  /disabled - FALSE). **/void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,						 bool state){	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;	if (hw->mac.type != e1000_ich8lan) {		hw_dbg(hw, "Workaround applies to ICH8 only.\n");		return;	}	dev_spec->kmrn_lock_loss_workaround_enabled = state;}/** *  e1000_ipg3_phy_powerdown_workaround_ich8lan - Power down workaround on D3 *  @hw: pointer to the HW structure * *  Workaround for 82566 power-down on D3 entry: *    1) disable gigabit link *    2) write VR power-down enable *    3) read it back *  Continue if successful, else issue LCD reset and repeat **/void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw){	u32 reg;	u16 data;	u8  retry = 0;	if (hw->phy.type != e1000_phy_igp_3)		return;	/* Try the workaround twice (if needed) */	do {		/* Disable link */		reg = er32(PHY_CTRL);		reg |= (E1000_PHY_CTRL_GBE_DISABLE |			E1000_PHY_CTRL_NOND0A_GBE_DISABLE);		ew32(PHY_CTRL, reg);		/*		 * Call gig speed drop workaround on Gig disable before		 * accessing any PHY registers		 */		if (hw->mac.type == e1000_ich8lan)			e1000e_gig_downshift_workaround_ich8lan(hw);		/* Write VR power-down enable */		e1e_rphy(hw, IGP3_VR_CTRL, &data);		data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK;		e1e_wphy(hw, IGP3_VR_CTRL, data | IGP3_VR_CTRL_MODE_SHUTDOWN);		/* Read it back and test */		e1e_rphy(hw, IGP3_VR_CTRL, &data);		data &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK;		if ((data == IGP3_VR_CTRL_MODE_SHUTDOWN) || retry)			break;		/* Issue PHY reset and repeat at most one more time */		reg = er32(CTRL);		ew32(CTRL, reg | E1000_CTRL_PHY_RST);		retry++;	} while (retry);}/** *  e1000e_gig_downshift_workaround_ich8lan - WoL from S5 stops working *  @hw: pointer to the HW structure * *  Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC), *  LPLU, Gig disable, MDIC PHY reset): *    1) Set Kumeran Near-end loopback *    2) Clear Kumeran Near-end loopback *  Should only be called for ICH8[m] devices with IGP_3 Phy. **/void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw){	s32 ret_val;	u16 reg_data;	if ((hw->mac.type != e1000_ich8lan) ||	    (hw->phy.type != e1000_phy_igp_3))		return;	ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,				      &reg_data);	if (ret_val)		return;	reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK;	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,				       reg_data);	if (ret_val)		return;	reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK;	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,				       reg_data);}/** *  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 * *  Return the LED back to the default configuration. **/static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw){	if (hw->phy.type == e1000_phy_ife)		return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);	ew32(LEDCTL, hw->mac.ledctl_default);	return 0;}/** *  e1000_led_on_ich8lan - Turn LEDs on *  @hw: pointer to the HW structure * *  Turn on the LEDs. **/static s32 e1000_led_on_ich8lan(struct e1000_hw *hw){	if (hw->phy.type == e1000_phy_ife)		return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED,				(IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON));	ew32(LEDCTL, hw->mac.ledctl_mode2);	return 0;}/** *  e1000_led_off_ich8lan - Turn LEDs off *  @hw: pointer to the HW structure * *  Turn off the LEDs. **/static s32 e1000_led_off_ich8lan(struct e1000_hw *hw){	if (hw->phy.type == e1000_phy_ife)		return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED,			       (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF));	ew32(LEDCTL, hw->mac.ledctl_mode1);	return 0;}/** *  e1000_phy_init_script_igp3 - Inits the IGP3 PHY *  @hw: pointer to the HW structure * *  Initializes a Intel Gigabit PHY3 when an EEPROM is not present. **/static s32 e1000_phy_init_script_igp3(struct e1000_hw *hw){	/* PHY init IGP 3 */	/* Enable rise/fall, 10-mode work in class-A */	e1e_wphy(hw, 0x2F5B, 0x9018);	/* Remove all caps from Replica path filter */	e1e_wphy(hw, 0x2F52, 0x0000);	/* Bias trimming for ADC, AFE and Driver (Default) */	e1e_wphy(hw, 0x2FB1, 0x8B24);	/* Increase Hybrid poly bias */	e1e_wphy(hw, 0x2FB2, 0xF8F0);	/* Add 4% to Tx amplitude in Gig mode */	e1e_wphy(hw, 0x2010, 0x10B0);	/* Disable trimming (TTT) */	e1e_wphy(hw, 0x2011, 0x0000);	/* Poly DC correction to 94.6% + 2% for all channels */	e1e_wphy(hw, 0x20DD, 0x249A);	/* ABS DC correction to 95.9% */	e1e_wphy(hw, 0x20DE, 0x00D3);	/* BG temp curve trim */	e1e_wphy(hw, 0x28B4, 0x04CE);	/* Increasing ADC OPAMP stage 1 currents to max */	e1e_wphy(hw, 0x2F70, 0x29E4);	/* Force 1000 ( required for enabling PHY regs configuration) */	e1e_wphy(hw, 0x0000, 0x0140);	/* Set upd_freq to 6 */	e1e_wphy(hw, 0x1F30, 0x1606);	/* Disable NPDFE */	e1e_wphy(hw, 0x1F31, 0xB814);	/* Disable adaptive fixed FFE (Default) */	e1e_wphy(hw, 0x1F35, 0x002A);	/* Enable FFE hysteresis */	e1e_wphy(hw, 0x1F3E, 0x0067);	/* Fixed FFE for short cable lengths */	e1e_wphy(hw, 0x1F54, 0x0065);	/* Fixed FFE for medium cable lengths */	e1e_wphy(hw, 0x1F55, 0x002A);	/* Fixed FFE for long cable lengths */	e1e_wphy(hw, 0x1F56, 0x002A);	/* Enable Adaptive Clip Threshold */	e1e_wphy(hw, 0x1F72, 0x3FB0);	/* AHT reset limit to 1 */	e1e_wphy(hw, 0x1F76, 0xC0FF);	/* Set AHT master delay to 127 msec */	e1e_wphy(hw, 0x1F77, 0x1DEC);	/* Set scan bits for AHT */	e1e_wphy(hw, 0x1F78, 0xF9EF);	/* Set AHT Preset bits */	e1e_wphy(hw, 0x1F79, 0x0210);	/* Change integ_factor of channel A to 3 */	e1e_wphy(hw, 0x1895, 0x0003);	/* Change prop_factor of channels BCD to 8 */	e1e_wphy(hw, 0x1796, 0x0008);	/* Change cg_icount + enable integbp for channels BCD */	e1e_wphy(hw, 0x1798, 0xD008);	/*	 * Change cg_icount + enable integbp + change prop_factor_master	 * to 8 for channel A	 */	e1e_wphy(hw, 0x1898, 0xD918);	/* Disable AHT in Slave mode on channel A */	e1e_wphy(hw, 0x187A, 0x0800);	/*	 * Enable LPLU and disable AN to 1000 in non-D0a states,	 * Enable SPD+B2B	 */	e1e_wphy(hw, 0x0019, 0x008D);	/* Enable restart AN on an1000_dis change */	e1e_wphy(hw, 0x001B, 0x2080);	/* Enable wh_fifo read clock in 10/100 modes */	e1e_wphy(hw, 0x0014, 0x0045);	/* Restart AN, Speed selection is 1000 */	e1e_wphy(hw, 0x0000, 0x1340);	return 0;}/** *  e1000_get_cfg_done_ich8lan - Read config done bit *  @hw: pointer to the HW structure * *  Read the management control register for the config done bit for *  completion status.  NOTE: silicon which is EEPROM-less will fail trying *  to read the config done bit, so an error is *ONLY* logged and returns *  E1000_SUCCESS.  If we were to return with error, EEPROM-less silicon *  would not be able to be reset or change link. **/sta

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -