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

📄 e1000_82571.c

📁 linux系统的网卡驱动包
💻 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*******************************************************************************//* e1000_82571 * e1000_82572 * e1000_82573 * e1000_82574 */#include "e1000_api.h"#include "e1000_82571.h"static s32  e1000_init_phy_params_82571(struct e1000_hw *hw);static s32  e1000_init_nvm_params_82571(struct e1000_hw *hw);static s32  e1000_init_mac_params_82571(struct e1000_hw *hw);static s32  e1000_acquire_nvm_82571(struct e1000_hw *hw);static void e1000_release_nvm_82571(struct e1000_hw *hw);static s32  e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset,                                  u16 words, u16 *data);static s32  e1000_update_nvm_checksum_82571(struct e1000_hw *hw);static s32  e1000_validate_nvm_checksum_82571(struct e1000_hw *hw);static s32  e1000_get_cfg_done_82571(struct e1000_hw *hw);static s32  e1000_set_d0_lplu_state_82571(struct e1000_hw *hw,                                          bool active);static s32  e1000_reset_hw_82571(struct e1000_hw *hw);static s32  e1000_init_hw_82571(struct e1000_hw *hw);static void e1000_clear_vfta_82571(struct e1000_hw *hw);static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,                                           u8 *mc_addr_list, u32 mc_addr_count,                                           u32 rar_used_count, u32 rar_count);static s32  e1000_setup_link_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_valid_led_default_82571(struct e1000_hw *hw, u16 *data);static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);static s32  e1000_get_hw_semaphore_82571(struct e1000_hw *hw);static s32  e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);static s32  e1000_get_phy_id_82571(struct e1000_hw *hw);static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);static void e1000_initialize_hw_bits_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_read_mac_addr_82571(struct e1000_hw *hw);static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);struct e1000_dev_spec_82571 {	bool laa_is_present;};/** *  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;	struct e1000_functions *func = &hw->func;	s32 ret_val = E1000_SUCCESS;	DEBUGFUNC("e1000_init_phy_params_82571");	if (hw->phy.media_type != e1000_media_type_copper) {		phy->type        = e1000_phy_none;		goto out;	}	phy->addr                        = 1;	phy->autoneg_mask                = AUTONEG_ADVERTISE_SPEED_DEFAULT;	phy->reset_delay_us              = 100;	func->acquire_phy                = e1000_get_hw_semaphore_82571;	func->check_polarity             = e1000_check_polarity_igp;	func->check_reset_block          = e1000_check_reset_block_generic;	func->release_phy                = e1000_put_hw_semaphore_82571;	func->reset_phy                  = e1000_phy_hw_reset_generic;	func->set_d0_lplu_state          = e1000_set_d0_lplu_state_82571;	func->set_d3_lplu_state          = e1000_set_d3_lplu_state_generic;	func->power_up_phy               = e1000_power_up_phy_copper;	func->power_down_phy             = e1000_power_down_phy_copper_82571;	switch (hw->mac.type) {	case e1000_82571:	case e1000_82572:		phy->type                = e1000_phy_igp_2;		func->get_cfg_done       = e1000_get_cfg_done_82571;		func->get_phy_info       = e1000_get_phy_info_igp;		func->force_speed_duplex = e1000_phy_force_speed_duplex_igp;		func->get_cable_length   = e1000_get_cable_length_igp_2;		func->read_phy_reg       = e1000_read_phy_reg_igp;		func->write_phy_reg      = e1000_write_phy_reg_igp;		/* This uses above function pointers */		ret_val = e1000_get_phy_id_82571(hw);		/* Verify PHY ID */		if (phy->id != IGP01E1000_I_PHY_ID) {			ret_val = -E1000_ERR_PHY;			goto out;		}		break;	case e1000_82573:		phy->type                = e1000_phy_m88;		func->get_cfg_done       = e1000_get_cfg_done_generic;		func->get_phy_info       = e1000_get_phy_info_m88;		func->commit_phy         = e1000_phy_sw_reset_generic;		func->force_speed_duplex = e1000_phy_force_speed_duplex_m88;		func->get_cable_length   = e1000_get_cable_length_m88;		func->read_phy_reg       = e1000_read_phy_reg_m88;		func->write_phy_reg      = e1000_write_phy_reg_m88;		/* This uses above function pointers */		ret_val = e1000_get_phy_id_82571(hw);		/* Verify PHY ID */		if (phy->id != M88E1111_I_PHY_ID) {			ret_val = -E1000_ERR_PHY;			DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id);			goto out;		}		break;	default:		ret_val = -E1000_ERR_PHY;		goto out;		break;	}out:	return ret_val;}/** *  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;	struct e1000_functions *func = &hw->func;	u32 eecd = E1000_READ_REG(hw, E1000_EECD);	u16 size;	DEBUGFUNC("e1000_init_nvm_params_82571");	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;			E1000_WRITE_REG(hw, E1000_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;	}	/* Function Pointers */	func->acquire_nvm       = e1000_acquire_nvm_82571;	func->read_nvm          = (hw->mac.type == e1000_82573)	                          ? e1000_read_nvm_eerd	                          : e1000_read_nvm_spi;	func->release_nvm       = e1000_release_nvm_82571;	func->update_nvm        = e1000_update_nvm_checksum_82571;	func->validate_nvm      = e1000_validate_nvm_checksum_82571;	func->valid_led_default = e1000_valid_led_default_82571;	func->write_nvm         = e1000_write_nvm_82571;	return E1000_SUCCESS;}/** *  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_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	struct e1000_functions *func = &hw->func;	s32 ret_val = E1000_SUCCESS;	DEBUGFUNC("e1000_init_mac_params_82571");	/* Set media type */	switch (hw->device_id) {	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_82571EB_SERDES_DUAL:	case E1000_DEV_ID_82571EB_SERDES_QUAD:	case E1000_DEV_ID_82572EI_SERDES:		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 part includes ASF firmware */	mac->asf_firmware_present = TRUE;	/* Set if manageability features are enabled. */	mac->arc_subsystem_valid =	        (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)	                ? TRUE : FALSE;	/* Function pointers */	/* bus type/speed/width */	func->get_bus_info = e1000_get_bus_info_pcie_generic;	/* reset */	func->reset_hw = e1000_reset_hw_82571;	/* hw initialization */	func->init_hw = e1000_init_hw_82571;	/* link setup */	func->setup_link = e1000_setup_link_82571;	/* physical interface link setup */	func->setup_physical_interface =	        (hw->phy.media_type == e1000_media_type_copper)	                ? e1000_setup_copper_link_82571	                : e1000_setup_fiber_serdes_link_82571;	/* check for link */	switch (hw->phy.media_type) {	case e1000_media_type_copper:		func->check_for_link = e1000_check_for_copper_link_generic;		break;	case e1000_media_type_fiber:		func->check_for_link = e1000_check_for_fiber_link_generic;		break;	case e1000_media_type_internal_serdes:		func->check_for_link = e1000_check_for_serdes_link_generic;		break;	default:		ret_val = -E1000_ERR_CONFIG;		goto out;		break;	}	/* check management mode */	func->check_mng_mode = e1000_check_mng_mode_generic;	/* multicast address update */	func->update_mc_addr_list = e1000_update_mc_addr_list_82571;	/* writing VFTA */	func->write_vfta = e1000_write_vfta_generic;	/* clearing VFTA */	func->clear_vfta = e1000_clear_vfta_82571;	/* setting MTA */	func->mta_set = e1000_mta_set_generic;	/* read mac address */	func->read_mac_addr = e1000_read_mac_addr_82571;	/* blink LED */	func->blink_led = e1000_blink_led_generic;	/* setup LED */	func->setup_led = e1000_setup_led_generic;	/* cleanup LED */	func->cleanup_led = e1000_cleanup_led_generic;	/* turn on/off LED */	func->led_on = e1000_led_on_generic;	func->led_off = e1000_led_off_generic;	/* remove device */	func->remove_device = e1000_remove_device_generic;	/* clear hardware counters */	func->clear_hw_cntrs = e1000_clear_hw_cntrs_82571;	/* link info */	func->get_link_up_info =	        (hw->phy.media_type == e1000_media_type_copper)	                ? e1000_get_speed_and_duplex_copper_generic	                : e1000_get_speed_and_duplex_fiber_serdes_generic;	hw->dev_spec_size = sizeof(struct e1000_dev_spec_82571);	/* Device-specific structure allocation */	ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size);out:	return ret_val;}/** *  e1000_init_function_pointers_82571 - Init func ptrs. *  @hw: pointer to the HW structure * *  The only function explicitly called by the api module to initialize *  all function pointers and parameters. **/void e1000_init_function_pointers_82571(struct e1000_hw *hw){	DEBUGFUNC("e1000_init_function_pointers_82571");	hw->func.init_mac_params = e1000_init_mac_params_82571;	hw->func.init_nvm_params = e1000_init_nvm_params_82571;	hw->func.init_phy_params = e1000_init_phy_params_82571;}/** *  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;	s32 ret_val = E1000_SUCCESS;	DEBUGFUNC("e1000_get_phy_id_82571");	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:		ret_val = e1000_get_phy_id(hw);		break;	default:		ret_val = -E1000_ERR_PHY;		break;	}	return ret_val;}/** *  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 ret_val = E1000_SUCCESS;	s32 timeout = hw->nvm.word_size + 1;	s32 i = 0;	DEBUGFUNC("e1000_get_hw_semaphore_82571");	/* Get the FW semaphore. */	for (i = 0; i < timeout; i++) {		swsm = E1000_READ_REG(hw, E1000_SWSM);		E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);		/* Semaphore acquired if bit latched */		if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)			break;		usec_delay(50);	}	if (i == timeout) {		/* Release semaphores */		e1000_put_hw_semaphore_generic(hw);		DEBUGOUT("Driver can't access the NVM\n");		ret_val = -E1000_ERR_NVM;		goto out;	}out:	return ret_val;}/** *  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;	DEBUGFUNC("e1000_put_hw_semaphore_82571");	swsm = E1000_READ_REG(hw, E1000_SWSM);	swsm &= ~E1000_SWSM_SWESMBI;	E1000_WRITE_REG(hw, E1000_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;	DEBUGFUNC("e1000_acquire_nvm_82571");	ret_val = e1000_get_hw_semaphore_82571(hw);	if (ret_val)		goto out;

⌨️ 快捷键说明

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