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

📄 e1000_80003es2lan.c

📁 Intel 82546系列lan driver源码
💻 C
📖 第 1 页 / 共 3 页
字号:
 *  @hw: pointer to the HW structure * *  Setup some GG82563 PHY registers for obtaining link **/static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw){	struct e1000_phy_info *phy = &hw->phy;	s32 ret_val;	u32 ctrl_ext;	u16 data;	if (!phy->reset_disable) {		ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL,		                             &data);		if (ret_val)			goto out;		data |= GG82563_MSCR_ASSERT_CRS_ON_TX;		/* Use 25MHz for both link down and 1000Base-T for Tx clock. */		data |= GG82563_MSCR_TX_CLK_1000MBPS_25;		ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL,		                              data);		if (ret_val)			goto out;		/*		 * Options:		 *   MDI/MDI-X = 0 (default)		 *   0 - Auto for all speeds		 *   1 - MDI mode		 *   2 - MDI-X mode		 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)		 */		ret_val = e1e_rphy(hw, GG82563_PHY_SPEC_CTRL, &data);		if (ret_val)			goto out;		data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;		switch (phy->mdix) {		case 1:			data |= GG82563_PSCR_CROSSOVER_MODE_MDI;			break;		case 2:			data |= GG82563_PSCR_CROSSOVER_MODE_MDIX;			break;		case 0:		default:			data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;			break;		}		/*		 * Options:		 *   disable_polarity_correction = 0 (default)		 *       Automatic Correction for Reversed Cable Polarity		 *   0 - Disabled		 *   1 - Enabled		 */		data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;		if (phy->disable_polarity_correction)			data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE;		ret_val = e1e_wphy(hw, GG82563_PHY_SPEC_CTRL, data);		if (ret_val)			goto out;		/* SW Reset the PHY so all changes take effect */		ret_val = e1000e_commit_phy(hw);		if (ret_val) {			e_dbg("Error Resetting the PHY\n");			goto out;		}	}	/* Bypass Rx and Tx FIFO's */	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,					E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,					E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |					E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);	if (ret_val)		goto out;	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,	                              E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,	                              &data);	if (ret_val)		goto out;	data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,	                               E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,	                               data);	if (ret_val)		goto out;	ret_val = e1e_rphy(hw, GG82563_PHY_SPEC_CTRL_2, &data);	if (ret_val)		goto out;	data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;	ret_val = e1e_wphy(hw, GG82563_PHY_SPEC_CTRL_2, data);	if (ret_val)		goto out;	ctrl_ext = er32(CTRL_EXT);	ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);	ew32(CTRL_EXT, ctrl_ext);	ret_val = e1e_rphy(hw, GG82563_PHY_PWR_MGMT_CTRL, &data);	if (ret_val)		goto out;	/*	 * Do not init these registers when the HW is in IAMT mode, since the	 * firmware will have already initialized them.  We only initialize	 * them if the HW is not in IAMT mode.	 */	if (!(hw->mac.ops.check_mng_mode(hw))) {		/* Enable Electrical Idle on the PHY */		data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;		ret_val = e1e_wphy(hw, GG82563_PHY_PWR_MGMT_CTRL,		                                data);		if (ret_val)			goto out;		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,		                               &data);		if (ret_val)			goto out;		data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;		ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL,		                                data);		if (ret_val)			goto out;	}	/*	 * Workaround: Disable padding in Kumeran interface in the MAC	 * and in the PHY to avoid CRC errors.	 */	ret_val = e1e_rphy(hw, GG82563_PHY_INBAND_CTRL, &data);	if (ret_val)		goto out;	data |= GG82563_ICR_DIS_PADDING;	ret_val = e1e_wphy(hw, GG82563_PHY_INBAND_CTRL, data);	if (ret_val)		goto out;out:	return ret_val;}/** *  e1000_setup_copper_link_80003es2lan - Setup Copper Link for ESB2 *  @hw: pointer to the HW structure * *  Essentially a wrapper for setting up all things "copper" related. *  This is a function pointer entry point called by the mac module. **/static s32 e1000_setup_copper_link_80003es2lan(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 = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4),	                                           0xFFFF);	if (ret_val)		goto out;	ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),	                                          &reg_data);	if (ret_val)		goto out;	reg_data |= 0x3F;	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),	                                           reg_data);	if (ret_val)		goto out;	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,	                              E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,	                              &reg_data);	if (ret_val)		goto out;	reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING;	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,	                               E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,	                               reg_data);	if (ret_val)		goto out;	ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw);	if (ret_val)		goto out;	ret_val = e1000e_setup_copper_link(hw);out:	return ret_val;}/** *  e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up *  @hw: pointer to the HW structure *  @duplex: current duplex setting * *  Configure the KMRN interface by applying last minute quirks for *  10/100 operation. **/static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw){	s32 ret_val = E1000_SUCCESS;	u16 speed;	u16 duplex;	if (hw->phy.media_type == e1000_media_type_copper) {		ret_val = e1000e_get_speed_and_duplex_copper(hw,		                                                    &speed,		                                                    &duplex);		if (ret_val)			goto out;		if (speed == SPEED_1000)			ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);		else			ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex);	}out:	return ret_val;}/** *  e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation *  @hw: pointer to the HW structure *  @duplex: current duplex setting * *  Configure the KMRN interface by applying last minute quirks for *  10/100 operation. **/static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex){	s32 ret_val = E1000_SUCCESS;	u32 tipg;	u32 i = 0;	u16 reg_data, reg_data2;	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT;	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,	                               E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,	                               reg_data);	if (ret_val)		goto out;	/* Configure Transmit Inter-Packet Gap */	tipg = er32(TIPG);	tipg &= ~E1000_TIPG_IPGT_MASK;	tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN;	ew32(TIPG, tipg);	do {		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,		                               &reg_data);		if (ret_val)			goto out;		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,		                               &reg_data2);		if (ret_val)			goto out;		i++;	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));	if (duplex == HALF_DUPLEX)		reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;	else		reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;	ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);out:	return ret_val;}/** *  e1000_cfg_kmrn_1000_80003es2lan - Apply "quirks" for gigabit operation *  @hw: pointer to the HW structure * *  Configure the KMRN interface by applying last minute quirks for *  gigabit operation. **/static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw){	s32 ret_val = E1000_SUCCESS;	u16 reg_data, reg_data2;	u32 tipg;	u32 i = 0;	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,	                               E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,	                               reg_data);	if (ret_val)		goto out;	/* Configure Transmit Inter-Packet Gap */	tipg = er32(TIPG);	tipg &= ~E1000_TIPG_IPGT_MASK;	tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN;	ew32(TIPG, tipg);	do {		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,		                               &reg_data);		if (ret_val)			goto out;		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,		                               &reg_data2);		if (ret_val)			goto out;		i++;	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;	ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);out:	return ret_val;}/** *  e1000_read_kmrn_reg_80003es2lan - Read kumeran register *  @hw: pointer to the HW structure *  @offset: register offset to be read *  @data: pointer to the read data * *  Acquire semaphore, then read the PHY register at offset *  using the kumeran interface.  The information retrieved is stored in data. *  Release the semaphore before exiting. **/s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data){	u32 kmrnctrlsta;	s32 ret_val = E1000_SUCCESS;	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);	if (ret_val)		goto out;	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &	               E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;	ew32(KMRNCTRLSTA, kmrnctrlsta);	udelay(2);	kmrnctrlsta = er32(KMRNCTRLSTA);	*data = (u16)kmrnctrlsta;	e1000_release_mac_csr_80003es2lan(hw);out:	return ret_val;}/** *  e1000_write_kmrn_reg_80003es2lan - Write kumeran register *  @hw: pointer to the HW structure *  @offset: register offset to write to *  @data: data to write at register offset * *  Acquire semaphore, then write the data to PHY register *  at the offset using the kumeran interface.  Release semaphore *  before exiting. **/s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data){	u32 kmrnctrlsta;	s32 ret_val = E1000_SUCCESS;	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);	if (ret_val)		goto out;	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &	               E1000_KMRNCTRLSTA_OFFSET) | data;	ew32(KMRNCTRLSTA, kmrnctrlsta);	udelay(2);	e1000_release_mac_csr_80003es2lan(hw);out:	return ret_val;}/** *  e1000_read_mac_addr_80003es2lan - Read device MAC address *  @hw: pointer to the HW structure **/static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw){	s32 ret_val = E1000_SUCCESS;	if (e1000_check_alt_mac_addr_generic(hw))		ret_val = e1000e_read_mac_addr_generic(hw);	return ret_val;}/** * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down * @hw: pointer to the HW structure * * In the case of a PHY power down to save power, or to turn off link during a * driver unload, or wake on lan is not enabled, remove the link. **/static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw){	/* If the management interface is not enabled, then power down */	if (!(hw->mac.ops.check_mng_mode(hw) ||	      e1000_check_reset_block(hw)))		e1000_power_down_phy_copper(hw);	return;}/** *  e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters *  @hw: pointer to the HW structure * *  Clears the hardware counters by reading the counter registers. **/static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw){	e1000e_clear_hw_cntrs_base(hw);	er32(PRC64);	er32(PRC127);	er32(PRC255);	er32(PRC511);	er32(PRC1023);	er32(PRC1522);	er32(PTC64);	er32(PTC127);	er32(PTC255);	er32(PTC511);	er32(PTC1023);	er32(PTC1522);	er32(ALGNERRC);	er32(RXERRC);	er32(TNCRS);	er32(CEXTERR);	er32(TSCTC);	er32(TSCTFC);	er32(MGTPRC);	er32(MGTPDC);	er32(MGTPTC);	er32(IAC);	er32(ICRXOC);	er32(ICRXPTC);	er32(ICRXATC);	er32(ICTXPTC);	er32(ICTXATC);	er32(ICTXQEC);	er32(ICTXQMTC);	er32(ICRXDMTC);}

⌨️ 快捷键说明

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