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

📄 es2lan.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*******************************************************************************//* * 80003ES2LAN Gigabit Ethernet Controller (Copper) * 80003ES2LAN Gigabit Ethernet Controller (Serdes) */#include <linux/netdevice.h>#include <linux/ethtool.h>#include <linux/delay.h>#include <linux/pci.h>#include "e1000.h"#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL	 0x00#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL	 0x02#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL	 0x10#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE	 0x1F#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS	 0x0008#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS	 0x0800#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING	 0x0010#define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT	 0x0000#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE		 0x2000#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN	 0x00010000#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN	 0x8#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN	 0x9/* GG82563 PHY Specific Status Register (Page 0, Register 16 */#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE	 0x0002 /* 1=Reversal Disab. */#define GG82563_PSCR_CROSSOVER_MODE_MASK	 0x0060#define GG82563_PSCR_CROSSOVER_MODE_MDI		 0x0000 /* 00=Manual MDI */#define GG82563_PSCR_CROSSOVER_MODE_MDIX	 0x0020 /* 01=Manual MDIX */#define GG82563_PSCR_CROSSOVER_MODE_AUTO	 0x0060 /* 11=Auto crossover *//* PHY Specific Control Register 2 (Page 0, Register 26) */#define GG82563_PSCR2_REVERSE_AUTO_NEG		 0x2000						/* 1=Reverse Auto-Negotiation *//* MAC Specific Control Register (Page 2, Register 21) *//* Tx clock speed for Link Down and 1000BASE-T for the following speeds */#define GG82563_MSCR_TX_CLK_MASK		 0x0007#define GG82563_MSCR_TX_CLK_10MBPS_2_5		 0x0004#define GG82563_MSCR_TX_CLK_100MBPS_25		 0x0005#define GG82563_MSCR_TX_CLK_1000MBPS_25		 0x0007#define GG82563_MSCR_ASSERT_CRS_ON_TX		 0x0010 /* 1=Assert *//* DSP Distance Register (Page 5, Register 26) */#define GG82563_DSPD_CABLE_LENGTH		 0x0007 /* 0 = <50M							   1 = 50-80M							   2 = 80-110M							   3 = 110-140M							   4 = >140M *//* Kumeran Mode Control Register (Page 193, Register 16) */#define GG82563_KMCR_PASS_FALSE_CARRIER		 0x0800/* Max number of times Kumeran read/write should be validated */#define GG82563_MAX_KMRN_RETRY  0x5/* Power Management Control Register (Page 193, Register 20) */#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE	 0x0001					   /* 1=Enable SERDES Electrical Idle *//* In-Band Control Register (Page 194, Register 18) */#define GG82563_ICR_DIS_PADDING			 0x0010 /* Disable Padding *//* * A table for the GG82563 cable length where the range is defined * with a lower bound at "index" and the upper bound at * "index + 5". */static const u16 e1000_gg82563_cable_length_table[] =	 { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF };static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw);static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw);static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw);static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw);static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex);/** *  e1000_init_phy_params_80003es2lan - Init ESB2 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_80003es2lan(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;	phy->type		= e1000_phy_gg82563;	/* This can only be done after all function pointers are setup. */	ret_val = e1000e_get_phy_id(hw);	/* Verify phy id */	if (phy->id != GG82563_E_PHY_ID)		return -E1000_ERR_PHY;	return ret_val;}/** *  e1000_init_nvm_params_80003es2lan - Init ESB2 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_80003es2lan(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;	}	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;	return 0;}/** *  e1000_init_mac_params_80003es2lan - Init ESB2 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_80003es2lan(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_80003ES2LAN_SERDES_DPT:		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_80003es2lan;		func->check_for_link = e1000e_check_for_copper_link;		break;	case e1000_media_type_fiber:		func->setup_physical_interface = e1000e_setup_fiber_serdes_link;		func->check_for_link = e1000e_check_for_fiber_link;		break;	case e1000_media_type_internal_serdes:		func->setup_physical_interface = e1000e_setup_fiber_serdes_link;		func->check_for_link = e1000e_check_for_serdes_link;		break;	default:		return -E1000_ERR_CONFIG;		break;	}	return 0;}static s32 e1000_get_variants_80003es2lan(struct e1000_adapter *adapter){	struct e1000_hw *hw = &adapter->hw;	s32 rc;	rc = e1000_init_mac_params_80003es2lan(adapter);	if (rc)		return rc;	rc = e1000_init_nvm_params_80003es2lan(hw);	if (rc)		return rc;	rc = e1000_init_phy_params_80003es2lan(hw);	if (rc)		return rc;	return 0;}/** *  e1000_acquire_phy_80003es2lan - Acquire rights to access PHY *  @hw: pointer to the HW structure * *  A wrapper to acquire access rights to the correct PHY.  This is a *  function pointer entry point called by the api module. **/static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw){	u16 mask;	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;	mask |= E1000_SWFW_CSR_SM;	return e1000_acquire_swfw_sync_80003es2lan(hw, mask);}/** *  e1000_release_phy_80003es2lan - Release rights to access PHY *  @hw: pointer to the HW structure * *  A wrapper to release access rights to the correct PHY.  This is a *  function pointer entry point called by the api module. **/static void e1000_release_phy_80003es2lan(struct e1000_hw *hw){	u16 mask;	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;	mask |= E1000_SWFW_CSR_SM;	e1000_release_swfw_sync_80003es2lan(hw, mask);}/** *  e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM *  @hw: pointer to the HW structure * *  Acquire the semaphore to access the EEPROM.  This is a function *  pointer entry point called by the api module. **/static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw){	s32 ret_val;	ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);	if (ret_val)		return ret_val;	ret_val = e1000e_acquire_nvm(hw);	if (ret_val)		e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);	return ret_val;}/** *  e1000_release_nvm_80003es2lan - Relinquish rights to access NVM *  @hw: pointer to the HW structure * *  Release the semaphore used to access the EEPROM.  This is a *  function pointer entry point called by the api module. **/static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw){	e1000e_release_nvm(hw);	e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);}/** *  e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore *  @hw: pointer to the HW structure *  @mask: specifies which semaphore to acquire * *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask *  will also specify which port we're acquiring the lock for. **/static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask){	u32 swfw_sync;	u32 swmask = mask;	u32 fwmask = mask << 16;	s32 i = 0;	s32 timeout = 200;	while (i < timeout) {		if (e1000e_get_hw_semaphore(hw))			return -E1000_ERR_SWFW_SYNC;		swfw_sync = er32(SW_FW_SYNC);		if (!(swfw_sync & (fwmask | swmask)))			break;		/*		 * Firmware currently using resource (fwmask)		 * or other software thread using resource (swmask)		 */		e1000e_put_hw_semaphore(hw);		mdelay(5);		i++;	}	if (i == timeout) {		hw_dbg(hw,		       "Driver can't access resource, SW_FW_SYNC timeout.\n");		return -E1000_ERR_SWFW_SYNC;	}	swfw_sync |= swmask;	ew32(SW_FW_SYNC, swfw_sync);	e1000e_put_hw_semaphore(hw);	return 0;}/** *  e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore *  @hw: pointer to the HW structure *  @mask: specifies which semaphore to acquire * *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask *  will also specify which port we're releasing the lock for. **/static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask){	u32 swfw_sync;	while (e1000e_get_hw_semaphore(hw) != 0);	/* Empty */	swfw_sync = er32(SW_FW_SYNC);	swfw_sync &= ~mask;	ew32(SW_FW_SYNC, swfw_sync);	e1000e_put_hw_semaphore(hw);}/** *  e1000_read_phy_reg_gg82563_80003es2lan - Read GG82563 PHY register *  @hw: pointer to the HW structure *  @offset: offset of the register to read *  @data: pointer to the data returned from the operation * *  Read the GG82563 PHY register.  This is a function pointer entry *  point called by the api module. **/static s32 e1000_read_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) {

⌨️ 快捷键说明

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