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

📄 e1000_80003es2lan.c

📁 linux系统的网卡驱动包
💻 C
📖 第 1 页 / 共 3 页
字号:
 **/static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,                                                  u32 offset, u16 *data){	s32 ret_val;	u32 page_select;	u16 temp;	DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan");	ret_val = e1000_acquire_phy_80003es2lan(hw);	if (ret_val)		goto out;	/* 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 = e1000_write_phy_reg_mdic(hw, page_select, temp);	if (ret_val) {		e1000_release_phy_80003es2lan(hw);		goto out;	}	/*	 * 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...	 */	usec_delay(200);	/* ...and verify the command was successful. */	ret_val = e1000_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);		goto out;	}	usec_delay(200);	ret_val = e1000_read_phy_reg_mdic(hw,	                                 MAX_PHY_REG_ADDRESS & offset,	                                 data);	usec_delay(200);	e1000_release_phy_80003es2lan(hw);out:	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;	DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan");	ret_val = e1000_acquire_phy_80003es2lan(hw);	if (ret_val)		goto out;	/* 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 = e1000_write_phy_reg_mdic(hw, page_select, temp);	if (ret_val) {		e1000_release_phy_80003es2lan(hw);		goto out;	}	/*	 * 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...	 */	usec_delay(200);	/* ...and verify the command was successful. */	ret_val = e1000_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);		goto out;	}	usec_delay(200);	ret_val = e1000_write_phy_reg_mdic(hw,	                                  MAX_PHY_REG_ADDRESS & offset,	                                  data);	usec_delay(200);	e1000_release_phy_80003es2lan(hw);out:	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){	DEBUGFUNC("e1000_write_nvm_80003es2lan");	return e1000_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;	s32 ret_val = E1000_SUCCESS;	u32 mask = E1000_NVM_CFG_DONE_PORT_0;	DEBUGFUNC("e1000_get_cfg_done_80003es2lan");	if (hw->bus.func == 1)		mask = E1000_NVM_CFG_DONE_PORT_1;	while (timeout) {		if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)			break;		msec_delay(1);		timeout--;	}	if (!timeout) {		DEBUGOUT("MNG configuration cycle has not completed.\n");		ret_val = -E1000_ERR_RESET;		goto out;	}out:	return ret_val;}/** *  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;	DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan");	/*	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI	 * forced whenever speed and duplex are forced.	 */	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);	if (ret_val)		goto out;	phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO;	ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data);	if (ret_val)		goto out;	DEBUGOUT1("GG82563 PSCR: %X\n", phy_data);	ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data);	if (ret_val)		goto out;	e1000_phy_force_speed_duplex_setup(hw, &phy_data);	/* Reset the phy to commit changes. */	phy_data |= MII_CR_RESET;	ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data);	if (ret_val)		goto out;	usec_delay(1);	if (hw->phy.autoneg_wait_to_complete) {		DEBUGOUT("Waiting for forced speed/duplex link "		         "on GG82563 phy.\n");		ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,		                                     100000, &link);		if (ret_val)			goto out;		if (!link) {			/*			 * We didn't get link.			 * Reset the DSP and cross our fingers.			 */			ret_val = e1000_phy_reset_dsp_generic(hw);			if (ret_val)				goto out;		}		/* Try once more */		ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,		                                     100000, &link);		if (ret_val)			goto out;	}	ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);	if (ret_val)		goto out;	/*	 * 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 = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);out:	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, index;	DEBUGFUNC("e1000_get_cable_length_80003es2lan");	ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data);	if (ret_val)		goto out;	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;out:	return ret_val;}/** *  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;	DEBUGFUNC("e1000_get_link_up_info_80003es2lan");	if (hw->phy.media_type == e1000_media_type_copper) {		ret_val = e1000_get_speed_and_duplex_copper_generic(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);	} else {		ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw,		                                                  speed,		                                                  duplex);	}out:	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, icr;	s32 ret_val;	DEBUGFUNC("e1000_reset_hw_80003es2lan");	/*	 * 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 = e1000_disable_pcie_master_generic(hw);	if (ret_val) {		DEBUGOUT("PCI-E Master disable polling has failed.\n");	}	DEBUGOUT("Masking off all interrupts\n");	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);	E1000_WRITE_REG(hw, E1000_RCTL, 0);	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);	E1000_WRITE_FLUSH(hw);	msec_delay(10);	ctrl = E1000_READ_REG(hw, E1000_CTRL);	DEBUGOUT("Issuing a global reset to MAC\n");	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);	ret_val = e1000_get_auto_rd_done_generic(hw);	if (ret_val)		/* We don't want to continue accessing MAC registers. */		goto out;	/* Clear any pending interrupt events. */	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);	icr = E1000_READ_REG(hw, E1000_ICR);	ret_val = e1000_check_alt_mac_addr_generic(hw);out:	return ret_val;}/** *  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;	DEBUGFUNC("e1000_init_hw_80003es2lan");	e1000_initialize_hw_bits_80003es2lan(hw);	/* Initialize identification LED */	ret_val = e1000_id_led_init_generic(hw);	if (ret_val) {		DEBUGOUT("Error initializing identification LED\n");		/* This is not fatal and we should not stop init due to this */	}	/* Disabling VLAN filtering */	DEBUGOUT("Initializing the IEEE VLAN\n");	e1000_clear_vfta(hw);	/* Setup the receive address. */	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);	/* Zero out the Multicast HASH table */	DEBUGOUT("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 = e1000_setup_link(hw);	/* Set the transmit descriptor write-back policy */	reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0));	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |	           E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;	E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data);	/* ...for both queues. */	reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1));	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |	           E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;	E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data);	/* Enable retransmit on late collisions */	reg_data = E1000_READ_REG(hw, E1000_TCTL);	reg_data |= E1000_TCTL_RTLC;	E1000_WRITE_REG(hw, E1000_TCTL, reg_data);	/* Configure Gigabit Carry Extend Padding */	reg_data = E1000_READ_REG(hw, E1000_TCTL_EXT);	reg_data &= ~E1000_TCTL_EXT_GCEX_MASK;	reg_data |= DEFAULT_TCTL_EXT_GCEX_80003ES2LAN;	E1000_WRITE_REG(hw, E1000_TCTL_EXT, reg_data);	/* Configure Transmit Inter-Packet Gap */	reg_data = E1000_READ_REG(hw, E1000_TIPG);	reg_data &= ~E1000_TIPG_IPGT_MASK;	reg_data |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN;	E1000_WRITE_REG(hw, E1000_TIPG, reg_data);	reg_data = E1000_READ_REG_ARRAY(hw, E1000_FFLT, 0x0001);

⌨️ 快捷键说明

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