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

📄 82571.c

📁 grub源码分析文档
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************  Intel PRO/1000 Linux driver  Copyright(c) 1999 - 2008 Intel Corporation.  This program is free software; you can redistribute it and/or modify it  under the terms and conditions of the GNU General Public License,  version 2, as published by the Free Software Foundation.  This program is distributed in the hope it will be useful, but WITHOUT  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for  more details.  You should have received a copy of the GNU General Public License along with  this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.  The full GNU General Public License is included in this distribution in  the file called "COPYING".  Contact Information:  Linux NICS <linux.nics@intel.com>  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************//* * 82571EB Gigabit Ethernet Controller * 82571EB Gigabit Ethernet Controller (Fiber) * 82571EB Dual Port Gigabit Mezzanine Adapter * 82571EB Quad Port Gigabit Mezzanine Adapter * 82571PT Gigabit PT Quad Port Server ExpressModule * 82572EI Gigabit Ethernet Controller (Copper) * 82572EI Gigabit Ethernet Controller (Fiber) * 82572EI Gigabit Ethernet Controller * 82573V Gigabit Ethernet Controller (Copper) * 82573E Gigabit Ethernet Controller (Copper) * 82573L Gigabit Ethernet Controller */#include <linux/netdevice.h>#include <linux/delay.h>#include <linux/pci.h>#include "e1000.h"#define ID_LED_RESERVED_F746 0xF746#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \			      (ID_LED_OFF1_ON2  <<  8) | \			      (ID_LED_DEF1_DEF2 <<  4) | \			      (ID_LED_DEF1_DEF2))#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,				      u16 words, u16 *data);static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);static s32 e1000_setup_link_82571(struct e1000_hw *hw);static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);/** *  e1000_init_phy_params_82571 - Init PHY func ptrs. *  @hw: pointer to the HW structure * *  This is a function pointer entry point called by the api module. **/static s32 e1000_init_phy_params_82571(struct e1000_hw *hw){	struct e1000_phy_info *phy = &hw->phy;	s32 ret_val;	if (hw->phy.media_type != e1000_media_type_copper) {		phy->type = e1000_phy_none;		return 0;	}	phy->addr			 = 1;	phy->autoneg_mask		 = AUTONEG_ADVERTISE_SPEED_DEFAULT;	phy->reset_delay_us		 = 100;	switch (hw->mac.type) {	case e1000_82571:	case e1000_82572:		phy->type = e1000_phy_igp_2;		ret_val = e1000_get_phy_id_82571(hw);		/* Verify PHY ID */		if (phy->id != IGP01E1000_I_PHY_ID)			return -E1000_ERR_PHY;		break;	case e1000_82573:		phy->type = e1000_phy_m88;		ret_val = e1000_get_phy_id_82571(hw);		/* Verify PHY ID */		if (phy->id != M88E1111_I_PHY_ID) {			hw_dbg(hw, "PHY ID unknown: type = 0x%08x\n", phy->id);			return -E1000_ERR_PHY;		}		break;	default:		return -E1000_ERR_PHY;		break;	}	/* This can only be done after all function pointers are setup. */	ret_val = e1000_get_phy_id_82571(hw);	/* Verify phy id */	switch (hw->mac.type) {	case e1000_82571:	case e1000_82572:		if (phy->id != IGP01E1000_I_PHY_ID)			return -E1000_ERR_PHY;		break;	case e1000_82573:		if (phy->id != M88E1111_I_PHY_ID)			return -E1000_ERR_PHY;		break;	default:		return -E1000_ERR_PHY;		break;	}	return 0;}/** *  e1000_init_nvm_params_82571 - Init NVM func ptrs. *  @hw: pointer to the HW structure * *  This is a function pointer entry point called by the api module. **/static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw){	struct e1000_nvm_info *nvm = &hw->nvm;	u32 eecd = er32(EECD);	u16 size;	nvm->opcode_bits = 8;	nvm->delay_usec = 1;	switch (nvm->override) {	case e1000_nvm_override_spi_large:		nvm->page_size = 32;		nvm->address_bits = 16;		break;	case e1000_nvm_override_spi_small:		nvm->page_size = 8;		nvm->address_bits = 8;		break;	default:		nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;		nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;		break;	}	switch (hw->mac.type) {	case e1000_82573:		if (((eecd >> 15) & 0x3) == 0x3) {			nvm->type = e1000_nvm_flash_hw;			nvm->word_size = 2048;			/*			 * Autonomous Flash update bit must be cleared due			 * to Flash update issue.			 */			eecd &= ~E1000_EECD_AUPDEN;			ew32(EECD, eecd);			break;		}		/* Fall Through */	default:		nvm->type = e1000_nvm_eeprom_spi;		size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>				  E1000_EECD_SIZE_EX_SHIFT);		/*		 * Added to a constant, "size" becomes the left-shift value		 * for setting word_size.		 */		size += NVM_WORD_SIZE_BASE_SHIFT;		/* EEPROM access above 16k is unsupported */		if (size > 14)			size = 14;		nvm->word_size	= 1 << size;		break;	}	return 0;}/** *  e1000_init_mac_params_82571 - Init MAC func ptrs. *  @hw: pointer to the HW structure * *  This is a function pointer entry point called by the api module. **/static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter){	struct e1000_hw *hw = &adapter->hw;	struct e1000_mac_info *mac = &hw->mac;	struct e1000_mac_operations *func = &mac->ops;	/* Set media type */	switch (adapter->pdev->device) {	case E1000_DEV_ID_82571EB_FIBER:	case E1000_DEV_ID_82572EI_FIBER:	case E1000_DEV_ID_82571EB_QUAD_FIBER:		hw->phy.media_type = e1000_media_type_fiber;		break;	case E1000_DEV_ID_82571EB_SERDES:	case E1000_DEV_ID_82572EI_SERDES:	case E1000_DEV_ID_82571EB_SERDES_DUAL:	case E1000_DEV_ID_82571EB_SERDES_QUAD:		hw->phy.media_type = e1000_media_type_internal_serdes;		break;	default:		hw->phy.media_type = e1000_media_type_copper;		break;	}	/* Set mta register count */	mac->mta_reg_count = 128;	/* Set rar entry count */	mac->rar_entry_count = E1000_RAR_ENTRIES;	/* Set if manageability features are enabled. */	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0;	/* check for link */	switch (hw->phy.media_type) {	case e1000_media_type_copper:		func->setup_physical_interface = e1000_setup_copper_link_82571;		func->check_for_link = e1000e_check_for_copper_link;		func->get_link_up_info = e1000e_get_speed_and_duplex_copper;		break;	case e1000_media_type_fiber:		func->setup_physical_interface =			e1000_setup_fiber_serdes_link_82571;		func->check_for_link = e1000e_check_for_fiber_link;		func->get_link_up_info =			e1000e_get_speed_and_duplex_fiber_serdes;		break;	case e1000_media_type_internal_serdes:		func->setup_physical_interface =			e1000_setup_fiber_serdes_link_82571;		func->check_for_link = e1000e_check_for_serdes_link;		func->get_link_up_info =			e1000e_get_speed_and_duplex_fiber_serdes;		break;	default:		return -E1000_ERR_CONFIG;		break;	}	return 0;}static s32 e1000_get_variants_82571(struct e1000_adapter *adapter){	struct e1000_hw *hw = &adapter->hw;	static int global_quad_port_a; /* global port a indication */	struct pci_dev *pdev = adapter->pdev;	u16 eeprom_data = 0;	int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1;	s32 rc;	rc = e1000_init_mac_params_82571(adapter);	if (rc)		return rc;	rc = e1000_init_nvm_params_82571(hw);	if (rc)		return rc;	rc = e1000_init_phy_params_82571(hw);	if (rc)		return rc;	/* tag quad port adapters first, it's used below */	switch (pdev->device) {	case E1000_DEV_ID_82571EB_QUAD_COPPER:	case E1000_DEV_ID_82571EB_QUAD_FIBER:	case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:	case E1000_DEV_ID_82571PT_QUAD_COPPER:		adapter->flags |= FLAG_IS_QUAD_PORT;		/* mark the first port */		if (global_quad_port_a == 0)			adapter->flags |= FLAG_IS_QUAD_PORT_A;		/* Reset for multiple quad port adapters */		global_quad_port_a++;		if (global_quad_port_a == 4)			global_quad_port_a = 0;		break;	default:		break;	}	switch (adapter->hw.mac.type) {	case e1000_82571:		/* these dual ports don't have WoL on port B at all */		if (((pdev->device == E1000_DEV_ID_82571EB_FIBER) ||		     (pdev->device == E1000_DEV_ID_82571EB_SERDES) ||		     (pdev->device == E1000_DEV_ID_82571EB_COPPER)) &&		    (is_port_b))			adapter->flags &= ~FLAG_HAS_WOL;		/* quad ports only support WoL on port A */		if (adapter->flags & FLAG_IS_QUAD_PORT &&		    (!(adapter->flags & FLAG_IS_QUAD_PORT_A)))			adapter->flags &= ~FLAG_HAS_WOL;		/* Does not support WoL on any port */		if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)			adapter->flags &= ~FLAG_HAS_WOL;		break;	case e1000_82573:		if (pdev->device == E1000_DEV_ID_82573L) {			e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,				       &eeprom_data);			if (!(eeprom_data & NVM_WORD1A_ASPM_MASK))				adapter->flags |= FLAG_HAS_JUMBO_FRAMES;		}		break;	default:		break;	}	return 0;}/** *  e1000_get_phy_id_82571 - Retrieve the PHY ID and revision *  @hw: pointer to the HW structure * *  Reads the PHY registers and stores the PHY ID and possibly the PHY *  revision in the hardware structure. **/static s32 e1000_get_phy_id_82571(struct e1000_hw *hw){	struct e1000_phy_info *phy = &hw->phy;	switch (hw->mac.type) {	case e1000_82571:	case e1000_82572:		/*		 * The 82571 firmware may still be configuring the PHY.		 * In this case, we cannot access the PHY until the		 * configuration is done.  So we explicitly set the		 * PHY ID.		 */		phy->id = IGP01E1000_I_PHY_ID;		break;	case e1000_82573:		return e1000e_get_phy_id(hw);		break;	default:		return -E1000_ERR_PHY;		break;	}	return 0;}/** *  e1000_get_hw_semaphore_82571 - Acquire hardware semaphore *  @hw: pointer to the HW structure * *  Acquire the HW semaphore to access the PHY or NVM **/static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw){	u32 swsm;	s32 timeout = hw->nvm.word_size + 1;	s32 i = 0;	/* Get the FW semaphore. */	for (i = 0; i < timeout; i++) {		swsm = er32(SWSM);		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);		/* Semaphore acquired if bit latched */		if (er32(SWSM) & E1000_SWSM_SWESMBI)			break;		udelay(50);	}	if (i == timeout) {		/* Release semaphores */		e1000e_put_hw_semaphore(hw);		hw_dbg(hw, "Driver can't access the NVM\n");		return -E1000_ERR_NVM;	}	return 0;}/** *  e1000_put_hw_semaphore_82571 - Release hardware semaphore *  @hw: pointer to the HW structure * *  Release hardware semaphore used to access the PHY or NVM **/static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw){	u32 swsm;	swsm = er32(SWSM);	swsm &= ~E1000_SWSM_SWESMBI;	ew32(SWSM, swsm);}/** *  e1000_acquire_nvm_82571 - Request for access to the EEPROM *  @hw: pointer to the HW structure * *  To gain access to the EEPROM, first we must obtain a hardware semaphore. *  Then for non-82573 hardware, set the EEPROM access request bit and wait *  for EEPROM access grant bit.  If the access grant bit is not set, release *  hardware semaphore. **/static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw){	s32 ret_val;	ret_val = e1000_get_hw_semaphore_82571(hw);	if (ret_val)		return ret_val;	if (hw->mac.type != e1000_82573)		ret_val = e1000e_acquire_nvm(hw);	if (ret_val)		e1000_put_hw_semaphore_82571(hw);	return ret_val;}/** *  e1000_release_nvm_82571 - Release exclusive access to EEPROM *  @hw: pointer to the HW structure * *  Stop any current commands to the EEPROM and clear the EEPROM request bit. **/static void e1000_release_nvm_82571(struct e1000_hw *hw){	e1000e_release_nvm(hw);	e1000_put_hw_semaphore_82571(hw);}/** *  e1000_write_nvm_82571 - Write to EEPROM using appropriate interface *  @hw: pointer to the HW structure *  @offset: offset within the EEPROM to be written to *  @words: number of words to write *  @data: 16 bit word(s) to be written to the EEPROM * *  For non-82573 silicon, write data to EEPROM at offset using SPI interface.

⌨️ 快捷键说明

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