X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fixgb%2Fixgb_hw.c;h=ecbf45861c6825c34c91adad1322c72d6137107d;hb=refs%2Fremotes%2Fvserver;hp=54490f738a6548b1be81bb6c241ea94c3903c931;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c index 54490f738..ecbf45861 100644 --- a/drivers/net/ixgb/ixgb_hw.c +++ b/drivers/net/ixgb/ixgb_hw.c @@ -1,28 +1,29 @@ /******************************************************************************* - - Copyright(c) 1999 - 2003 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 + Intel PRO/10GbE Linux driver + Copyright(c) 1999 - 2006 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., 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. - + 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 + e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *******************************************************************************/ /* ixgb_hw.c @@ -34,45 +35,65 @@ /* Local function prototypes */ -static u32 ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr); +static uint32_t ixgb_hash_mc_addr(struct ixgb_hw *hw, uint8_t * mc_addr); -static void ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value); +static void ixgb_mta_set(struct ixgb_hw *hw, uint32_t hash_value); static void ixgb_get_bus_info(struct ixgb_hw *hw); -boolean_t mac_addr_valid(u8 * mac_addr); - static boolean_t ixgb_link_reset(struct ixgb_hw *hw); static void ixgb_optics_reset(struct ixgb_hw *hw); -u32 ixgb_mac_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); -u32 -ixgb_mac_reset(struct ixgb_hw *hw) +static uint32_t ixgb_mac_reset(struct ixgb_hw *hw) { - u32 ctrl_reg; + 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; - /* Setup up hardware to known state with RESET. */ - 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 - outl(IXGB_CTRL0, hw->io_base); - outl(ctrl_reg, hw->io_base + 4); + /* 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); + msleep(IXGB_DELAY_AFTER_RESET); ctrl_reg = IXGB_READ_REG(hw, CTRL0); -#if DBG +#ifdef DBG /* Make sure the self-clearing global reset bit did self clear */ ASSERT(!(ctrl_reg & IXGB_CTRL0_RST)); #endif - ixgb_optics_reset(hw); + if (hw->phy_type == ixgb_phy_type_txn17401) { + ixgb_optics_reset(hw); + } + return ctrl_reg; } @@ -82,17 +103,17 @@ ixgb_mac_reset(struct ixgb_hw *hw) * hw - Struct containing variables accessed by shared code *****************************************************************************/ boolean_t -ixgb_adapter_stop(struct ixgb_hw * hw) +ixgb_adapter_stop(struct ixgb_hw *hw) { - u32 ctrl_reg; - u32 icr_reg; + 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) { + if(hw->adapter_stopped) { DEBUGOUT("Exiting because the adapter is already stopped!!!\n"); return FALSE; } @@ -112,7 +133,7 @@ ixgb_adapter_stop(struct ixgb_hw * hw) */ 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); + msleep(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 @@ -133,28 +154,130 @@ ixgb_adapter_stop(struct ixgb_hw * hw) 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_vendor +ixgb_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_type +ixgb_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; + case IXGB_DEVICE_ID_82597EX_CX4: + DEBUGOUT("Identified CX4\n"); + 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; + 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. + * + * 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. + * 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, + * TRUE if successful, * FALSE if unrecoverable problems were encountered. *****************************************************************************/ boolean_t -ixgb_init_hw(struct ixgb_hw * hw) +ixgb_init_hw(struct ixgb_hw *hw) { - u32 i; - u32 ctrl_reg; + uint32_t i; + uint32_t ctrl_reg; boolean_t status; DEBUGFUNC("ixgb_init_hw"); @@ -170,31 +293,35 @@ ixgb_init_hw(struct ixgb_hw * hw) DEBUGOUT("Issuing an EE reset to MAC\n"); #ifdef HP_ZX1 - outl(IXGB_CTRL1, hw->io_base); - outl(IXGB_CTRL1_EE_RST, hw->io_base + 4); + /* 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); + msleep(IXGB_DELAY_AFTER_EE_RESET); if (ixgb_get_eeprom_data(hw) == FALSE) { - return (FALSE); + return(FALSE); } - /* Setup the receive addresses. + /* 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); + return(FALSE); } /* tell the routines in this file they can access hardware again */ @@ -205,7 +332,7 @@ ixgb_init_hw(struct ixgb_hw * hw) /* Zero out the Multicast HASH table */ DEBUGOUT("Zeroing the MTA\n"); - for (i = 0; i < IXGB_MC_TBL_SIZE; i++) + for(i = 0; i < IXGB_MC_TBL_SIZE; i++) IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0); /* Zero out the VLAN Filter Table Array */ @@ -217,7 +344,7 @@ ixgb_init_hw(struct ixgb_hw * hw) /* Call a subroutine to setup flow control. */ status = ixgb_setup_fc(hw); - /* check-for-link in case lane deskew is locked */ + /* 82597EX errata: Call check-for-link in case lane deskew is locked */ ixgb_check_for_link(hw); return (status); @@ -226,20 +353,20 @@ ixgb_init_hw(struct ixgb_hw * hw) /****************************************************************************** * Initializes receive address filters. * - * hw - Struct containing variables accessed by shared code + * 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. *****************************************************************************/ -void +static void ixgb_init_rx_addrs(struct ixgb_hw *hw) { - u32 i; + 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. @@ -271,9 +398,10 @@ ixgb_init_rx_addrs(struct ixgb_hw *hw) /* 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); + for(i = 1; i < IXGB_RAR_ENTRIES; i++) { + /* Write high reg first to disable the AV bit first */ IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); + IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); } return; @@ -289,17 +417,18 @@ ixgb_init_rx_addrs(struct ixgb_hw *hw) * * The given list replaces any existing list. Clears the last 15 receive * address registers and the multicast table. Uses receive address registers - * for the first 15 multicast addresses, and hashes the rest into the + * for the first 15 multicast addresses, and hashes the rest into the * multicast table. *****************************************************************************/ void ixgb_mc_addr_list_update(struct ixgb_hw *hw, - u8 * mc_addr_list, - u32 mc_addr_count, u32 pad) + uint8_t *mc_addr_list, + uint32_t mc_addr_count, + uint32_t pad) { - u32 hash_value; - u32 i; - u32 rar_used_count = 1; /* RAR[0] is used for our MAC address */ + uint32_t hash_value; + uint32_t i; + uint32_t rar_used_count = 1; /* RAR[0] is used for our MAC address */ DEBUGFUNC("ixgb_mc_addr_list_update"); @@ -308,19 +437,19 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw, /* Clear RAR[1-15] */ DEBUGOUT(" Clearing RAR[1-15]\n"); - for (i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) { + for(i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) { IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); } /* Clear the MTA */ DEBUGOUT(" Clearing MTA\n"); - for (i = 0; i < IXGB_MC_TBL_SIZE; i++) { + for(i = 0; i < IXGB_MC_TBL_SIZE; i++) { IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0); } /* Add the new addresses */ - for (i = 0; i < mc_addr_count; i++) { + for(i = 0; i < mc_addr_count; i++) { DEBUGOUT(" Adding the multicast addresses:\n"); DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i, mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)], @@ -336,9 +465,9 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw, 5]); /* Place this multicast address in the RAR if there is room, * - * else put it in the MTA + * else put it in the MTA */ - if (rar_used_count < IXGB_RAR_ENTRIES) { + if(rar_used_count < IXGB_RAR_ENTRIES) { ixgb_rar_set(hw, mc_addr_list + (i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)), @@ -366,20 +495,21 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw, * Hashes an address to determine its location in the multicast table * * hw - Struct containing variables accessed by shared code - * mc_addr - the multicast address to hash + * mc_addr - the multicast address to hash * * Returns: * The hash value *****************************************************************************/ -static u32 -ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr) +static uint32_t +ixgb_hash_mc_addr(struct ixgb_hw *hw, + uint8_t *mc_addr) { - u32 hash_value = 0; + uint32_t hash_value = 0; DEBUGFUNC("ixgb_hash_mc_addr"); /* The portion of the address that is used for the hash table is - * determined by the mc_filter_type setting. + * determined by the mc_filter_type setting. */ switch (hw->mc_filter_type) { /* [0] [1] [2] [3] [4] [5] @@ -388,18 +518,18 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr) case 0: /* [47:36] i.e. 0x563 for above example address */ hash_value = - ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4)); + ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4)); break; case 1: /* [46:35] i.e. 0xAC6 for above example address */ hash_value = - ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5)); + ((mc_addr[4] >> 3) | (((uint16_t) mc_addr[5]) << 5)); break; case 2: /* [45:34] i.e. 0x5D8 for above example address */ hash_value = - ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6)); + ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6)); break; case 3: /* [43:32] i.e. 0x634 for above example address */ - hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8)); + hash_value = ((mc_addr[4]) | (((uint16_t) mc_addr[5]) << 8)); break; default: /* Invalid mc_filter_type, what should we do? */ @@ -419,17 +549,18 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr) * hash_value - Multicast address hash value *****************************************************************************/ static void -ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value) +ixgb_mta_set(struct ixgb_hw *hw, + uint32_t hash_value) { - u32 hash_bit, hash_reg; - u32 mta_reg; + uint32_t hash_bit, hash_reg; + uint32_t mta_reg; - /* The MTA is a register array of 128 32-bit registers. - * It is treated like an array of 4096 bits. We want to set + /* The MTA is a register array of 128 32-bit registers. + * It is treated like an array of 4096 bits. We want to set * bit BitArray[hash_value]. So we figure out what register * the bit is in, read it, OR in the new bit, then write - * back the new value. The register is determined by the - * upper 7 bits of the hash value and the bit within that + * back the new value. The register is determined by the + * upper 7 bits of the hash value and the bit within that * register are determined by the lower 5 bits of the value. */ hash_reg = (hash_value >> 5) & 0x7F; @@ -452,21 +583,25 @@ ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value) * index - Receive address register to write *****************************************************************************/ void -ixgb_rar_set(struct ixgb_hw *hw, u8 * addr, u32 index) +ixgb_rar_set(struct ixgb_hw *hw, + uint8_t *addr, + uint32_t index) { - u32 rar_low, rar_high; + uint32_t rar_low, rar_high; DEBUGFUNC("ixgb_rar_set"); /* HW expects these in little endian so we reverse the byte order - * from network order (big endian) to little endian + * from network order (big endian) to little endian */ - rar_low = ((u32) addr[0] | - ((u32) addr[1] << 8) | - ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); + rar_low = ((uint32_t) addr[0] | + ((uint32_t)addr[1] << 8) | + ((uint32_t)addr[2] << 16) | + ((uint32_t)addr[3] << 24)); - rar_high = ((u32) addr[4] | - ((u32) addr[5] << 8) | IXGB_RAH_AV); + rar_high = ((uint32_t) addr[4] | + ((uint32_t)addr[5] << 8) | + IXGB_RAH_AV); IXGB_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low); IXGB_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high); @@ -481,7 +616,9 @@ ixgb_rar_set(struct ixgb_hw *hw, u8 * addr, u32 index) * value - Value to write into VLAN filter table *****************************************************************************/ void -ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value) +ixgb_write_vfta(struct ixgb_hw *hw, + uint32_t offset, + uint32_t value) { IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value); return; @@ -492,12 +629,12 @@ ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value) * * hw - Struct containing variables accessed by shared code *****************************************************************************/ -void +static void ixgb_clear_vfta(struct ixgb_hw *hw) { - u32 offset; + uint32_t offset; - for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++) + for(offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++) IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0); return; } @@ -508,11 +645,11 @@ ixgb_clear_vfta(struct ixgb_hw *hw) * hw - Struct containing variables accessed by shared code *****************************************************************************/ -boolean_t -ixgb_setup_fc(struct ixgb_hw * hw) +static boolean_t +ixgb_setup_fc(struct ixgb_hw *hw) { - u32 ctrl_reg; - u32 pap_reg = 0; /* by default, assume no pause time */ + uint32_t ctrl_reg; + uint32_t pap_reg = 0; /* by default, assume no pause time */ boolean_t status = TRUE; DEBUGFUNC("ixgb_setup_fc"); @@ -534,6 +671,8 @@ ixgb_setup_fc(struct ixgb_hw * hw) */ switch (hw->fc.type) { case ixgb_fc_none: /* 0 */ + /* Set CMDC bit to disable Rx Flow control */ + ctrl_reg |= (IXGB_CTRL0_CMDC); break; case ixgb_fc_rx_pause: /* 1 */ /* RX Flow control is enabled, and TX Flow control is @@ -573,18 +712,18 @@ ixgb_setup_fc(struct ixgb_hw * hw) * these registers will be set to a default threshold that may be * adjusted later by the driver's runtime code. However, if the * ability to transmit pause frames in not enabled, then these - * registers will be set to 0. + * registers will be set to 0. */ - if (!(hw->fc.type & ixgb_fc_tx_pause)) { + if(!(hw->fc.type & ixgb_fc_tx_pause)) { IXGB_WRITE_REG(hw, FCRTL, 0); IXGB_WRITE_REG(hw, FCRTH, 0); } else { - /* We need to set up the Receive Threshold high and low water - * marks as well as (optionally) enabling the transmission of XON frames. - */ - if (hw->fc.send_xon) { + /* We need to set up the Receive Threshold high and low water + * marks as well as (optionally) enabling the transmission of XON + * frames. */ + if(hw->fc.send_xon) { IXGB_WRITE_REG(hw, FCRTL, - (hw->fc.low_water | IXGB_FCRTL_XONE)); + (hw->fc.low_water | IXGB_FCRTL_XONE)); } else { IXGB_WRITE_REG(hw, FCRTL, hw->fc.low_water); } @@ -603,18 +742,20 @@ ixgb_setup_fc(struct ixgb_hw * hw) * * Returns: Data word (16 bits) from MDI device. * - * This routine uses the new protocol MDI Single Command and Address Operation. + * The 82597EX has support for several MDI access methods. This routine + * uses the new protocol MDI Single Command and Address Operation. * This requires that first an address cycle command is sent, followed by a * read command. *****************************************************************************/ -u16 -ixgb_read_phy_reg(struct ixgb_hw * hw, - u32 reg_address, - u32 phy_address, u32 device_type) +static uint16_t +ixgb_read_phy_reg(struct ixgb_hw *hw, + uint32_t reg_address, + uint32_t phy_address, + uint32_t device_type) { - u32 i; - u32 data; - u32 command = 0; + uint32_t i; + uint32_t data; + uint32_t command = 0; ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS); ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS); @@ -635,7 +776,8 @@ ixgb_read_phy_reg(struct ixgb_hw * hw, ** from the CPU Write to the Ready bit assertion. **************************************************************/ - for (i = 0; i < 10; i++) { + for(i = 0; i < 10; i++) + { udelay(10); command = IXGB_READ_REG(hw, MSCA); @@ -661,7 +803,8 @@ ixgb_read_phy_reg(struct ixgb_hw * hw, ** from the CPU Write to the Ready bit assertion. **************************************************************/ - for (i = 0; i < 10; i++) { + for(i = 0; i < 10; i++) + { udelay(10); command = IXGB_READ_REG(hw, MSCA); @@ -673,11 +816,11 @@ ixgb_read_phy_reg(struct ixgb_hw * hw, ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0); /* Operation is complete, get the data from the MDIO Read/Write Data - * register and return. + * register and return. */ data = IXGB_READ_REG(hw, MSRWD); data >>= IXGB_MSRWD_READ_DATA_SHIFT; - return ((u16) data); + return((uint16_t) data); } /****************************************************************************** @@ -692,41 +835,45 @@ ixgb_read_phy_reg(struct ixgb_hw * hw, * * Returns: void. * - * This routine uses the new protocol MDI Single Command and Address Operation. + * The 82597EX has support for several MDI access methods. This routine + * uses the new protocol MDI Single Command and Address Operation. * This requires that first an address cycle command is sent, followed by a * write command. *****************************************************************************/ -void +static void ixgb_write_phy_reg(struct ixgb_hw *hw, - u32 reg_address, - u32 phy_address, u32 device_type, u16 data) + uint32_t reg_address, + uint32_t phy_address, + uint32_t device_type, + uint16_t data) { - u32 i; - u32 command = 0; + uint32_t i; + uint32_t command = 0; ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS); ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS); ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE); /* Put the data in the MDIO Read/Write Data register */ - IXGB_WRITE_REG(hw, MSRWD, (u32) data); + IXGB_WRITE_REG(hw, MSRWD, (uint32_t)data); /* Setup and write the address cycle command */ - command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) | - (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) | - (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) | - (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND)); + command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) | + (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) | + (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) | + (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND)); IXGB_WRITE_REG(hw, MSCA, command); - /************************************************************** - ** Check every 10 usec to see if the address cycle completed - ** The COMMAND bit will clear when the operation is complete. - ** This may take as long as 64 usecs (we'll wait 100 usecs max) - ** from the CPU Write to the Ready bit assertion. - **************************************************************/ + /************************************************************** + ** Check every 10 usec to see if the address cycle completed + ** The COMMAND bit will clear when the operation is complete. + ** This may take as long as 64 usecs (we'll wait 100 usecs max) + ** from the CPU Write to the Ready bit assertion. + **************************************************************/ - for (i = 0; i < 10; i++) { + for(i = 0; i < 10; i++) + { udelay(10); command = IXGB_READ_REG(hw, MSCA); @@ -738,21 +885,22 @@ ixgb_write_phy_reg(struct ixgb_hw *hw, ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0); /* Address cycle complete, setup and write the write command */ - command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) | - (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) | - (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) | - (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND)); + command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) | + (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) | + (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) | + (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND)); IXGB_WRITE_REG(hw, MSCA, command); - /************************************************************** - ** Check every 10 usec to see if the read command completed - ** The COMMAND bit will clear when the operation is complete. - ** The write may take as long as 64 usecs (we'll wait 100 usecs max) - ** from the CPU Write to the Ready bit assertion. - **************************************************************/ + /************************************************************** + ** Check every 10 usec to see if the read command completed + ** The COMMAND bit will clear when the operation is complete. + ** The write may take as long as 64 usecs (we'll wait 100 usecs max) + ** from the CPU Write to the Ready bit assertion. + **************************************************************/ - for (i = 0; i < 10; i++) { + for(i = 0; i < 10; i++) + { udelay(10); command = IXGB_READ_REG(hw, MSCA); @@ -776,8 +924,8 @@ ixgb_write_phy_reg(struct ixgb_hw *hw, void ixgb_check_for_link(struct ixgb_hw *hw) { - u32 status_reg; - u32 xpcss_reg; + uint32_t status_reg; + uint32_t xpcss_reg; DEBUGFUNC("ixgb_check_for_link"); @@ -792,47 +940,59 @@ ixgb_check_for_link(struct ixgb_hw *hw) DEBUGOUT("XPCSS Not Aligned while Status:LU is set.\n"); hw->link_up = ixgb_link_reset(hw); } else { + /* + * 82597EX errata. Since the lane deskew problem may prevent + * link, reset the link before reporting link down. + */ hw->link_up = ixgb_link_reset(hw); } - /* Anything else for 10 Gig?? */ } -boolean_t -ixgb_check_for_bad_link(struct ixgb_hw *hw) +/****************************************************************************** + * Check for a bad link condition that may have occured. + * The indication is that the RFC / LFC registers may be incrementing + * continually. A full adapter reset is required to recover. + * + * hw - Struct containing variables accessed by hw code + * + * Called by any function that needs to check the link status of the adapter. + *****************************************************************************/ +boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw) { - u32 newLFC, newRFC; + uint32_t newLFC, newRFC; boolean_t bad_link_returncode = FALSE; - /* check for a bad reset that may have occured - * the indication is that the RFC / LFC registers may be incrementing - * continually. Do a full adapter reset to recover - */ - newLFC = IXGB_READ_REG(hw, LFC); - newRFC = IXGB_READ_REG(hw, RFC); - if ((hw->lastLFC + 250 < newLFC) || (hw->lastRFC + 250 < newRFC)) { - DEBUGOUT("BAD LINK! too many LFC/RFC since last check\n"); - bad_link_returncode = TRUE; + if (hw->phy_type == ixgb_phy_type_txn17401) { + newLFC = IXGB_READ_REG(hw, LFC); + newRFC = IXGB_READ_REG(hw, RFC); + if ((hw->lastLFC + 250 < newLFC) + || (hw->lastRFC + 250 < newRFC)) { + DEBUGOUT + ("BAD LINK! too many LFC/RFC since last check\n"); + bad_link_returncode = TRUE; + } + hw->lastLFC = newLFC; + hw->lastRFC = newRFC; } - hw->lastLFC = newLFC; - hw->lastRFC = newRFC; + return bad_link_returncode; } /****************************************************************************** - * Clears all hardware statistics counters. + * Clears all hardware statistics counters. * * hw - Struct containing variables accessed by shared code *****************************************************************************/ -void +static void ixgb_clear_hw_cntrs(struct ixgb_hw *hw) { - volatile u32 temp_reg; + volatile uint32_t temp_reg; DEBUGFUNC("ixgb_clear_hw_cntrs"); /* if we are stopped or resetting exit gracefully */ - if (hw->adapter_stopped) { + if(hw->adapter_stopped) { DEBUGOUT("Exiting because the adapter is stopped!!!\n"); return; } @@ -908,7 +1068,7 @@ ixgb_clear_hw_cntrs(struct ixgb_hw *hw) void ixgb_led_on(struct ixgb_hw *hw) { - u32 ctrl0_reg = IXGB_READ_REG(hw, CTRL0); + uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0); /* To turn on the LED, clear software-definable pin 0 (SDP0). */ ctrl0_reg &= ~IXGB_CTRL0_SDP0; @@ -924,7 +1084,7 @@ ixgb_led_on(struct ixgb_hw *hw) void ixgb_led_off(struct ixgb_hw *hw) { - u32 ctrl0_reg = IXGB_READ_REG(hw, CTRL0); + uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0); /* To turn off the LED, set software-definable pin 0 (SDP0). */ ctrl0_reg |= IXGB_CTRL0_SDP0; @@ -940,16 +1100,16 @@ ixgb_led_off(struct ixgb_hw *hw) static void ixgb_get_bus_info(struct ixgb_hw *hw) { - u32 status_reg; + uint32_t status_reg; status_reg = IXGB_READ_REG(hw, STATUS); hw->bus.type = (status_reg & IXGB_STATUS_PCIX_MODE) ? - ixgb_bus_type_pcix : ixgb_bus_type_pci; + ixgb_bus_type_pcix : ixgb_bus_type_pci; if (hw->bus.type == ixgb_bus_type_pci) { hw->bus.speed = (status_reg & IXGB_STATUS_PCI_SPD) ? - ixgb_bus_speed_66 : ixgb_bus_speed_33; + ixgb_bus_speed_66 : ixgb_bus_speed_33; } else { switch (status_reg & IXGB_STATUS_PCIX_SPD_MASK) { case IXGB_STATUS_PCIX_SPD_66: @@ -968,7 +1128,7 @@ ixgb_get_bus_info(struct ixgb_hw *hw) } hw->bus.width = (status_reg & IXGB_STATUS_BUS64) ? - ixgb_bus_width_64 : ixgb_bus_width_32; + ixgb_bus_width_64 : ixgb_bus_width_32; return; } @@ -976,11 +1136,11 @@ ixgb_get_bus_info(struct ixgb_hw *hw) /****************************************************************************** * Tests a MAC address to ensure it is a valid Individual Address * - * mac_addr - pointer to MAC address. + * mac_addr - pointer to MAC address. * *****************************************************************************/ -boolean_t -mac_addr_valid(u8 * mac_addr) +static boolean_t +mac_addr_valid(uint8_t *mac_addr) { boolean_t is_valid = TRUE; DEBUGFUNC("mac_addr_valid"); @@ -997,9 +1157,11 @@ mac_addr_valid(u8 * mac_addr) } /* Reject the zero address */ else if (mac_addr[0] == 0 && - mac_addr[1] == 0 && - mac_addr[2] == 0 && - mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { + mac_addr[1] == 0 && + mac_addr[2] == 0 && + mac_addr[3] == 0 && + mac_addr[4] == 0 && + mac_addr[5] == 0) { DEBUGOUT("MAC address is all zeros\n"); is_valid = FALSE; } @@ -1007,22 +1169,24 @@ mac_addr_valid(u8 * mac_addr) } /****************************************************************************** - * Resets the 10GbE link. Waits the settle time and returns the state of + * Resets the 10GbE link. Waits the settle time and returns the state of * the link. * * hw - Struct containing variables accessed by shared code *****************************************************************************/ boolean_t -ixgb_link_reset(struct ixgb_hw * hw) +ixgb_link_reset(struct ixgb_hw *hw) { boolean_t link_status = FALSE; - u8 wait_retries = MAX_RESET_ITERATIONS; - u8 lrst_retries = MAX_RESET_ITERATIONS; + uint8_t wait_retries = MAX_RESET_ITERATIONS; + uint8_t lrst_retries = MAX_RESET_ITERATIONS; do { + /* Reset the link */ IXGB_WRITE_REG(hw, CTRL0, IXGB_READ_REG(hw, CTRL0) | IXGB_CTRL0_LRST); + /* Wait for link-up and lane re-alignment */ do { udelay(IXGB_DELAY_USECS_AFTER_LINK_RESET); link_status = @@ -1030,6 +1194,7 @@ ixgb_link_reset(struct ixgb_hw * hw) && (IXGB_READ_REG(hw, XPCSS) & IXGB_XPCSS_ALIGN_STATUS)) ? TRUE : FALSE; } while (!link_status && --wait_retries); + } while (!link_status && --lrst_retries); return link_status; @@ -1043,13 +1208,20 @@ ixgb_link_reset(struct ixgb_hw * hw) void ixgb_optics_reset(struct ixgb_hw *hw) { - u16 mdio_reg; - - ixgb_write_phy_reg(hw, - TXN17401_PMA_PMD_CR1, - IXGB_PHY_ADDRESS, - TXN17401_PMA_PMD_DID, TXN17401_PMA_PMD_CR1_RESET); - mdio_reg = ixgb_read_phy_reg(hw, - TXN17401_PMA_PMD_CR1, - IXGB_PHY_ADDRESS, TXN17401_PMA_PMD_DID); + if (hw->phy_type == ixgb_phy_type_txn17401) { + uint16_t mdio_reg; + + ixgb_write_phy_reg(hw, + MDIO_PMA_PMD_CR1, + IXGB_PHY_ADDRESS, + MDIO_PMA_PMD_DID, + MDIO_PMA_PMD_CR1_RESET); + + mdio_reg = ixgb_read_phy_reg( hw, + MDIO_PMA_PMD_CR1, + IXGB_PHY_ADDRESS, + MDIO_PMA_PMD_DID); + } + + return; }