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

📄 es2lan.c

📁 grub源码分析文档
💻 C
📖 第 1 页 / 共 3 页
字号:
		e1000_release_phy_80003es2lan(hw);		return ret_val;	}	/*	 * The "ready" bit in the MDIC register may be incorrectly set	 * before the device has completed the "Page Select" MDI	 * transaction.  So we wait 200us after each MDI command...	 */	udelay(200);	/* ...and verify the command was successful. */	ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {		ret_val = -E1000_ERR_PHY;		e1000_release_phy_80003es2lan(hw);		return ret_val;	}	udelay(200);	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,					   data);	udelay(200);	e1000_release_phy_80003es2lan(hw);	return ret_val;}/** *  e1000_write_phy_reg_gg82563_80003es2lan - Write GG82563 PHY register *  @hw: pointer to the HW structure *  @offset: offset of the register to read *  @data: value to write to the register * *  Write to the GG82563 PHY register.  This is a function pointer entry *  point called by the api module. **/static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,						   u32 offset, u16 data){	s32 ret_val;	u32 page_select;	u16 temp;	ret_val = e1000_acquire_phy_80003es2lan(hw);	if (ret_val)		return ret_val;	/* Select Configuration Page */	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {		page_select = GG82563_PHY_PAGE_SELECT;	} else {		/*		 * Use Alternative Page Select register to access		 * registers 30 and 31		 */		page_select = GG82563_PHY_PAGE_SELECT_ALT;	}	temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);	ret_val = e1000e_write_phy_reg_mdic(hw, page_select, temp);	if (ret_val) {		e1000_release_phy_80003es2lan(hw);		return ret_val;	}	/*	 * The "ready" bit in the MDIC register may be incorrectly set	 * before the device has completed the "Page Select" MDI	 * transaction.  So we wait 200us after each MDI command...	 */	udelay(200);	/* ...and verify the command was successful. */	ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {		e1000_release_phy_80003es2lan(hw);		return -E1000_ERR_PHY;	}	udelay(200);	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,					    data);	udelay(200);	e1000_release_phy_80003es2lan(hw);	return ret_val;}/** *  e1000_write_nvm_80003es2lan - Write to ESB2 NVM *  @hw: pointer to the HW structure *  @offset: offset of the register to read *  @words: number of words to write *  @data: buffer of data to write to the NVM * *  Write "words" of data to the ESB2 NVM.  This is a function *  pointer entry point called by the api module. **/static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,				       u16 words, u16 *data){	return e1000e_write_nvm_spi(hw, offset, words, data);}/** *  e1000_get_cfg_done_80003es2lan - Wait for configuration to complete *  @hw: pointer to the HW structure * *  Wait a specific amount of time for manageability processes to complete. *  This is a function pointer entry point called by the phy module. **/static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw){	s32 timeout = PHY_CFG_TIMEOUT;	u32 mask = E1000_NVM_CFG_DONE_PORT_0;	if (hw->bus.func == 1)		mask = E1000_NVM_CFG_DONE_PORT_1;	while (timeout) {		if (er32(EEMNGCTL) & mask)			break;		msleep(1);		timeout--;	}	if (!timeout) {		hw_dbg(hw, "MNG configuration cycle has not completed.\n");		return -E1000_ERR_RESET;	}	return 0;}/** *  e1000_phy_force_speed_duplex_80003es2lan - Force PHY speed and duplex *  @hw: pointer to the HW structure * *  Force the speed and duplex settings onto the PHY.  This is a *  function pointer entry point called by the phy module. **/static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw){	s32 ret_val;	u16 phy_data;	bool link;	/*	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI	 * forced whenever speed and duplex are forced.	 */	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);	if (ret_val)		return ret_val;	phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO;	ret_val = e1e_wphy(hw, GG82563_PHY_SPEC_CTRL, phy_data);	if (ret_val)		return ret_val;	hw_dbg(hw, "GG82563 PSCR: %X\n", phy_data);	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);	if (ret_val)		return ret_val;	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);	/* Reset the phy to commit changes. */	phy_data |= MII_CR_RESET;	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);	if (ret_val)		return ret_val;	udelay(1);	if (hw->phy.autoneg_wait_to_complete) {		hw_dbg(hw, "Waiting for forced speed/duplex link "			 "on GG82563 phy.\n");		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,						     100000, &link);		if (ret_val)			return ret_val;		if (!link) {			/*			 * We didn't get link.			 * Reset the DSP and cross our fingers.			 */			ret_val = e1000e_phy_reset_dsp(hw);			if (ret_val)				return ret_val;		}		/* Try once more */		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,						     100000, &link);		if (ret_val)			return ret_val;	}	ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);	if (ret_val)		return ret_val;	/*	 * Resetting the phy means we need to verify the TX_CLK corresponds	 * to the link speed.  10Mbps -> 2.5MHz, else 25MHz.	 */	phy_data &= ~GG82563_MSCR_TX_CLK_MASK;	if (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED)		phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5;	else		phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25;	/*	 * In addition, we must re-enable CRS on Tx for both half and full	 * duplex.	 */	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;	ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);	return ret_val;}/** *  e1000_get_cable_length_80003es2lan - Set approximate cable length *  @hw: pointer to the HW structure * *  Find the approximate cable length as measured by the GG82563 PHY. *  This is a function pointer entry point called by the phy module. **/static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw){	struct e1000_phy_info *phy = &hw->phy;	s32 ret_val;	u16 phy_data;	u16 index;	ret_val = e1e_rphy(hw, GG82563_PHY_DSP_DISTANCE, &phy_data);	if (ret_val)		return ret_val;	index = phy_data & GG82563_DSPD_CABLE_LENGTH;	phy->min_cable_length = e1000_gg82563_cable_length_table[index];	phy->max_cable_length = e1000_gg82563_cable_length_table[index+5];	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;	return 0;}/** *  e1000_get_link_up_info_80003es2lan - Report speed and duplex *  @hw: pointer to the HW structure *  @speed: pointer to speed buffer *  @duplex: pointer to duplex buffer * *  Retrieve the current speed and duplex configuration. *  This is a function pointer entry point called by the api module. **/static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,					      u16 *duplex){	s32 ret_val;	if (hw->phy.media_type == e1000_media_type_copper) {		ret_val = e1000e_get_speed_and_duplex_copper(hw,								    speed,								    duplex);		if (ret_val)			return ret_val;		if (*speed == SPEED_1000)			ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);		else			ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw,							      *duplex);	} else {		ret_val = e1000e_get_speed_and_duplex_fiber_serdes(hw,								  speed,								  duplex);	}	return ret_val;}/** *  e1000_reset_hw_80003es2lan - Reset the ESB2 controller *  @hw: pointer to the HW structure * *  Perform a global reset to the ESB2 controller. *  This is a function pointer entry point called by the api module. **/static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw){	u32 ctrl;	u32 icr;	s32 ret_val;	/*	 * Prevent the PCI-E bus from sticking if there is no TLP connection	 * on the last TLP read/write transaction when MAC is reset.	 */	ret_val = e1000e_disable_pcie_master(hw);	if (ret_val)		hw_dbg(hw, "PCI-E Master disable polling has failed.\n");	hw_dbg(hw, "Masking off all interrupts\n");	ew32(IMC, 0xffffffff);	ew32(RCTL, 0);	ew32(TCTL, E1000_TCTL_PSP);	e1e_flush();	msleep(10);	ctrl = er32(CTRL);	hw_dbg(hw, "Issuing a global reset to MAC\n");	ew32(CTRL, ctrl | E1000_CTRL_RST);	ret_val = e1000e_get_auto_rd_done(hw);	if (ret_val)		/* We don't want to continue accessing MAC registers. */		return ret_val;	/* Clear any pending interrupt events. */	ew32(IMC, 0xffffffff);	icr = er32(ICR);	return 0;}/** *  e1000_init_hw_80003es2lan - Initialize the ESB2 controller *  @hw: pointer to the HW structure * *  Initialize the hw bits, LED, VFTA, MTA, link and hw counters. *  This is a function pointer entry point called by the api module. **/static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	u32 reg_data;	s32 ret_val;	u16 i;	e1000_initialize_hw_bits_80003es2lan(hw);	/* Initialize identification LED */	ret_val = e1000e_id_led_init(hw);	if (ret_val) {		hw_dbg(hw, "Error initializing identification LED\n");		/* This is not fatal and we should not stop init due to this */	}	/* Disabling VLAN filtering */	hw_dbg(hw, "Initializing the IEEE VLAN\n");	e1000e_clear_vfta(hw);	/* Setup the receive address. */	e1000e_init_rx_addrs(hw, mac->rar_entry_count);	/* Zero out the Multicast HASH table */	hw_dbg(hw, "Zeroing the MTA\n");	for (i = 0; i < mac->mta_reg_count; i++)		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);	/* Setup link and flow control */	ret_val = e1000e_setup_link(hw);	/* Set the transmit descriptor write-back policy */	reg_data = er32(TXDCTL(0));	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |		   E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;	ew32(TXDCTL(0), reg_data);	/* ...for both queues. */	reg_data = er32(TXDCTL(1));	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |		   E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;	ew32(TXDCTL(1), reg_data);	/* Enable retransmit on late collisions */	reg_data = er32(TCTL);	reg_data |= E1000_TCTL_RTLC;	ew32(TCTL, reg_data);	/* Configure Gigabit Carry Extend Padding */	reg_data = er32(TCTL_EXT);	reg_data &= ~E1000_TCTL_EXT_GCEX_MASK;	reg_data |= DEFAULT_TCTL_EXT_GCEX_80003ES2LAN;	ew32(TCTL_EXT, reg_data);	/* Configure Transmit Inter-Packet Gap */	reg_data = er32(TIPG);	reg_data &= ~E1000_TIPG_IPGT_MASK;	reg_data |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN;	ew32(TIPG, reg_data);	reg_data = E1000_READ_REG_ARRAY(hw, E1000_FFLT, 0x0001);	reg_data &= ~0x00100000;	E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data);	/*	 * Clear all of the statistics registers (clear on read).  It is	 * important that we do this after we have tried to establish link	 * because the symbol error count will increment wildly if there	 * is no link.	 */	e1000_clear_hw_cntrs_80003es2lan(hw);	return ret_val;}/** *  e1000_initialize_hw_bits_80003es2lan - Init hw bits of ESB2 *  @hw: pointer to the HW structure * *  Initializes required hardware-dependent bits needed for normal operation. **/static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw){	u32 reg;	/* Transmit Descriptor Control 0 */	reg = er32(TXDCTL(0));	reg |= (1 << 22);	ew32(TXDCTL(0), reg);

⌨️ 快捷键说明

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