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

📄 ixgb_hw.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.    This program is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the Free   Software Foundation; either version 2 of the License, or (at your option)   any later version.    This program is distributed in the hope that 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., 59   Temple Place - Suite 330, Boston, MA  02111-1307, USA.    The full GNU General Public License is included in this distribution in the  file called LICENSE.    Contact Information:  Linux NICS <linux.nics@intel.com>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************//* ixgb_hw.c * Shared functions for accessing and configuring the adapter */#include "ixgb_hw.h"#include "ixgb_ids.h"/*  Local function prototypes */static uint32_t ixgb_hash_mc_addr(struct ixgb_hw *hw, uint8_t * mc_addr);static void ixgb_mta_set(struct ixgb_hw *hw, uint32_t hash_value);static void ixgb_get_bus_info(struct ixgb_hw *hw);static boolean_t ixgb_link_reset(struct ixgb_hw *hw);static void ixgb_optics_reset(struct ixgb_hw *hw);static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw);static void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);static void ixgb_clear_vfta(struct ixgb_hw *hw);static void ixgb_init_rx_addrs(struct ixgb_hw *hw);static uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,				  uint32_t reg_address,				  uint32_t phy_address,				  uint32_t device_type);static boolean_t ixgb_setup_fc(struct ixgb_hw *hw);static boolean_t mac_addr_valid(uint8_t *mac_addr);static uint32_t ixgb_mac_reset(struct ixgb_hw *hw){	uint32_t ctrl_reg;	ctrl_reg =  IXGB_CTRL0_RST |				IXGB_CTRL0_SDP3_DIR |   /* All pins are Output=1 */				IXGB_CTRL0_SDP2_DIR |				IXGB_CTRL0_SDP1_DIR |				IXGB_CTRL0_SDP0_DIR |				IXGB_CTRL0_SDP3	 |   /* Initial value 1101   */				IXGB_CTRL0_SDP2	 |				IXGB_CTRL0_SDP0;#ifdef HP_ZX1	/* Workaround for 82597EX reset errata */	IXGB_WRITE_REG_IO(hw, CTRL0, ctrl_reg);#else	IXGB_WRITE_REG(hw, CTRL0, ctrl_reg);#endif	/* Delay a few ms just to allow the reset to complete */	msec_delay(IXGB_DELAY_AFTER_RESET);	ctrl_reg = IXGB_READ_REG(hw, CTRL0);#ifdef DBG	/* Make sure the self-clearing global reset bit did self clear */	ASSERT(!(ctrl_reg & IXGB_CTRL0_RST));#endif	if (hw->phy_type == ixgb_phy_type_txn17401) {		ixgb_optics_reset(hw);	}	return ctrl_reg;}/****************************************************************************** * Reset the transmit and receive units; mask and clear all interrupts. * * hw - Struct containing variables accessed by shared code *****************************************************************************/boolean_tixgb_adapter_stop(struct ixgb_hw *hw){	uint32_t ctrl_reg;	uint32_t icr_reg;	DEBUGFUNC("ixgb_adapter_stop");	/* If we are stopped or resetting exit gracefully and wait to be	 * started again before accessing the hardware.	 */	if(hw->adapter_stopped) {		DEBUGOUT("Exiting because the adapter is already stopped!!!\n");		return FALSE;	}	/* Set the Adapter Stopped flag so other driver functions stop	 * touching the Hardware.	 */	hw->adapter_stopped = TRUE;	/* Clear interrupt mask to stop board from generating interrupts */	DEBUGOUT("Masking off all interrupts\n");	IXGB_WRITE_REG(hw, IMC, 0xFFFFFFFF);	/* Disable the Transmit and Receive units.  Then delay to allow	 * any pending transactions to complete before we hit the MAC with	 * the global reset.	 */	IXGB_WRITE_REG(hw, RCTL, IXGB_READ_REG(hw, RCTL) & ~IXGB_RCTL_RXEN);	IXGB_WRITE_REG(hw, TCTL, IXGB_READ_REG(hw, TCTL) & ~IXGB_TCTL_TXEN);	msec_delay(IXGB_DELAY_BEFORE_RESET);	/* Issue a global reset to the MAC.  This will reset the chip's	 * transmit, receive, DMA, and link units.  It will not effect	 * the current PCI configuration.  The global reset bit is self-	 * clearing, and should clear within a microsecond.	 */	DEBUGOUT("Issuing a global reset to MAC\n");	ctrl_reg = ixgb_mac_reset(hw);	/* Clear interrupt mask to stop board from generating interrupts */	DEBUGOUT("Masking off all interrupts\n");	IXGB_WRITE_REG(hw, IMC, 0xffffffff);	/* Clear any pending interrupt events. */	icr_reg = IXGB_READ_REG(hw, ICR);	return (ctrl_reg & IXGB_CTRL0_RST);}/****************************************************************************** * Identifies the vendor of the optics module on the adapter.  The SR adapters * support two different types of XPAK optics, so it is necessary to determine * which optics are present before applying any optics-specific workarounds. * * hw - Struct containing variables accessed by shared code. * * Returns: the vendor of the XPAK optics module. *****************************************************************************/static ixgb_xpak_vendorixgb_identify_xpak_vendor(struct ixgb_hw *hw){	uint32_t i;	uint16_t vendor_name[5];	ixgb_xpak_vendor xpak_vendor;	DEBUGFUNC("ixgb_identify_xpak_vendor");	/* Read the first few bytes of the vendor string from the XPAK NVR	 * registers.  These are standard XENPAK/XPAK registers, so all XPAK	 * devices should implement them. */	for (i = 0; i < 5; i++) {		vendor_name[i] = ixgb_read_phy_reg(hw,						   MDIO_PMA_PMD_XPAK_VENDOR_NAME						   + i, IXGB_PHY_ADDRESS,						   MDIO_PMA_PMD_DID);	}	/* Determine the actual vendor */	if (vendor_name[0] == 'I' &&	    vendor_name[1] == 'N' &&	    vendor_name[2] == 'T' &&	    vendor_name[3] == 'E' && vendor_name[4] == 'L') {		xpak_vendor = ixgb_xpak_vendor_intel;	} else {		xpak_vendor = ixgb_xpak_vendor_infineon;	}	return (xpak_vendor);}/****************************************************************************** * Determine the physical layer module on the adapter. * * hw - Struct containing variables accessed by shared code.  The device_id *      field must be (correctly) populated before calling this routine. * * Returns: the phy type of the adapter. *****************************************************************************/static ixgb_phy_typeixgb_identify_phy(struct ixgb_hw *hw){	ixgb_phy_type phy_type;	ixgb_xpak_vendor xpak_vendor;	DEBUGFUNC("ixgb_identify_phy");	/* Infer the transceiver/phy type from the device id */	switch (hw->device_id) {	case IXGB_DEVICE_ID_82597EX:		DEBUGOUT("Identified TXN17401 optics\n");		phy_type = ixgb_phy_type_txn17401;		break;	case IXGB_DEVICE_ID_82597EX_SR:		/* The SR adapters carry two different types of XPAK optics		 * modules; read the vendor identifier to determine the exact		 * type of optics. */		xpak_vendor = ixgb_identify_xpak_vendor(hw);		if (xpak_vendor == ixgb_xpak_vendor_intel) {			DEBUGOUT("Identified TXN17201 optics\n");			phy_type = ixgb_phy_type_txn17201;		} else {			DEBUGOUT("Identified G6005 optics\n");			phy_type = ixgb_phy_type_g6005;		}		break;	case IXGB_DEVICE_ID_82597EX_LR:		DEBUGOUT("Identified G6104 optics\n");		phy_type = ixgb_phy_type_g6104;		break;	default:		DEBUGOUT("Unknown physical layer module\n");		phy_type = ixgb_phy_type_unknown;		break;	}	return (phy_type);}/****************************************************************************** * Performs basic configuration of the adapter. * * hw - Struct containing variables accessed by shared code * * Resets the controller. * Reads and validates the EEPROM. * Initializes the receive address registers. * Initializes the multicast table. * Clears all on-chip counters. * Calls routine to setup flow control settings. * Leaves the transmit and receive units disabled and uninitialized. * * Returns: *      TRUE if successful, *      FALSE if unrecoverable problems were encountered. *****************************************************************************/boolean_tixgb_init_hw(struct ixgb_hw *hw){	uint32_t i;	uint32_t ctrl_reg;	boolean_t status;	DEBUGFUNC("ixgb_init_hw");	/* Issue a global reset to the MAC.  This will reset the chip's	 * transmit, receive, DMA, and link units.  It will not effect	 * the current PCI configuration.  The global reset bit is self-	 * clearing, and should clear within a microsecond.	 */	DEBUGOUT("Issuing a global reset to MAC\n");	ctrl_reg = ixgb_mac_reset(hw);	DEBUGOUT("Issuing an EE reset to MAC\n");#ifdef HP_ZX1	/* Workaround for 82597EX reset errata */	IXGB_WRITE_REG_IO(hw, CTRL1, IXGB_CTRL1_EE_RST);#else	IXGB_WRITE_REG(hw, CTRL1, IXGB_CTRL1_EE_RST);#endif	/* Delay a few ms just to allow the reset to complete */	msec_delay(IXGB_DELAY_AFTER_EE_RESET);	if (ixgb_get_eeprom_data(hw) == FALSE) {		return(FALSE);	}	/* Use the device id to determine the type of phy/transceiver. */	hw->device_id = ixgb_get_ee_device_id(hw);	hw->phy_type = ixgb_identify_phy(hw);	/* Setup the receive addresses.	 * Receive Address Registers (RARs 0 - 15).	 */	ixgb_init_rx_addrs(hw);	/*	 * Check that a valid MAC address has been set.	 * If it is not valid, we fail hardware init.	 */	if (!mac_addr_valid(hw->curr_mac_addr)) {		DEBUGOUT("MAC address invalid after ixgb_init_rx_addrs\n");		return(FALSE);	}	/* tell the routines in this file they can access hardware again */	hw->adapter_stopped = FALSE;	/* Fill in the bus_info structure */	ixgb_get_bus_info(hw);	/* Zero out the Multicast HASH table */	DEBUGOUT("Zeroing the MTA\n");	for(i = 0; i < IXGB_MC_TBL_SIZE; i++)		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);	/* Zero out the VLAN Filter Table Array */	ixgb_clear_vfta(hw);	/* Zero all of the hardware counters */	ixgb_clear_hw_cntrs(hw);	/* Call a subroutine to setup flow control. */	status = ixgb_setup_fc(hw);	/* 82597EX errata: Call check-for-link in case lane deskew is locked */	ixgb_check_for_link(hw);	return (status);}/****************************************************************************** * Initializes receive address filters. * * hw - Struct containing variables accessed by shared code * * Places the MAC address in receive address register 0 and clears the rest * of the receive addresss registers. Clears the multicast table. Assumes * the receiver is in reset when the routine is called. *****************************************************************************/static voidixgb_init_rx_addrs(struct ixgb_hw *hw){	uint32_t i;	DEBUGFUNC("ixgb_init_rx_addrs");	/*	 * If the current mac address is valid, assume it is a software override	 * to the permanent address.	 * Otherwise, use the permanent address from the eeprom.	 */	if (!mac_addr_valid(hw->curr_mac_addr)) {		/* Get the MAC address from the eeprom for later reference */		ixgb_get_ee_mac_addr(hw, hw->curr_mac_addr);		DEBUGOUT3(" Keeping Permanent MAC Addr =%.2X %.2X %.2X ",			  hw->curr_mac_addr[0],			  hw->curr_mac_addr[1], hw->curr_mac_addr[2]);		DEBUGOUT3("%.2X %.2X %.2X\n",			  hw->curr_mac_addr[3],			  hw->curr_mac_addr[4], hw->curr_mac_addr[5]);	} else {		/* Setup the receive address. */		DEBUGOUT("Overriding MAC Address in RAR[0]\n");		DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ",			  hw->curr_mac_addr[0],			  hw->curr_mac_addr[1], hw->curr_mac_addr[2]);		DEBUGOUT3("%.2X %.2X %.2X\n",			  hw->curr_mac_addr[3],			  hw->curr_mac_addr[4], hw->curr_mac_addr[5]);		ixgb_rar_set(hw, hw->curr_mac_addr, 0);	}	/* Zero out the other 15 receive addresses. */	DEBUGOUT("Clearing RAR[1-15]\n");	for(i = 1; i < IXGB_RAR_ENTRIES; i++) {		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);	}	return;}/****************************************************************************** * Updates the MAC's list of multicast addresses. * * hw - Struct containing variables accessed by shared code * mc_addr_list - the list of new multicast addresses * mc_addr_count - number of addresses * pad - number of bytes between addresses in the list * * The given list replaces any existing list. Clears the last 15 receive

⌨️ 快捷键说明

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