📄 ixgb_hw.c
字号:
/******************************************************************************* 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 + -