diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_82598.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82598.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index d0f1d9d2c41..fc41329399b 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 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, @@ -627,7 +627,6 @@ out: return 0; } - /** * ixgbe_setup_mac_link_82598 - Set MAC link speed * @hw: pointer to hardware structure @@ -698,7 +697,6 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, /* Setup the PHY according to input speed */ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, autoneg_wait_to_complete); - /* Set up MAC */ ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete); @@ -770,7 +768,6 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) goto no_phy_reset; - hw->phy.ops.reset(hw); } @@ -779,12 +776,9 @@ no_phy_reset: * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - status = ixgbe_disable_pcie_master(hw); - if (status != 0) { - status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); - } + ixgbe_disable_pcie_master(hw); +mac_reset_top: /* * Issue global reset to the MAC. This needs to be a SW reset. * If link reset is used, it might reset the MAC when mng is using it @@ -805,6 +799,19 @@ no_phy_reset: hw_dbg(hw, "Reset polling failed to complete.\n"); } + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. We use 1usec since that is + * what is needed for ixgbe_disable_pcie_master(). The second reset + * then clears out any effects of those events. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + udelay(1); + goto mac_reset_top; + } + msleep(50); gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); @@ -824,15 +831,15 @@ no_phy_reset: IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); } + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + /* * Store MAC address from RAR0, clear receive address registers, and * clear the multicast table */ hw->mac.ops.init_rx_addrs(hw); - /* Store the permanent mac address */ - hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); - reset_hw_out: if (phy_status) status = phy_status; @@ -849,6 +856,13 @@ reset_hw_out: static s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) { u32 rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); rar_high &= ~IXGBE_RAH_VIND_MASK; @@ -868,14 +882,17 @@ static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) u32 rar_high; u32 rar_entries = hw->mac.num_rar_entries; - if (rar < rar_entries) { - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); - if (rar_high & IXGBE_RAH_VIND_MASK) { - rar_high &= ~IXGBE_RAH_VIND_MASK; - IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); - } - } else { + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); + if (rar_high & IXGBE_RAH_VIND_MASK) { + rar_high &= ~IXGBE_RAH_VIND_MASK; + IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); } return 0; @@ -994,13 +1011,12 @@ static s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val) } /** - * ixgbe_read_i2c_eeprom_82598 - Read 8 bit EEPROM word of an SFP+ module - * over I2C interface through an intermediate phy. + * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface. * @hw: pointer to hardware structure * @byte_offset: EEPROM byte offset to read * @eeprom_data: value read * - * Performs byte read operation to SFP module's EEPROM over I2C interface. + * Performs 8 byte read operation to SFP module's EEPROM over I2C interface. **/ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data) @@ -1179,13 +1195,14 @@ static struct ixgbe_mac_operations mac_ops_82598 = { .set_vmdq = &ixgbe_set_vmdq_82598, .clear_vmdq = &ixgbe_clear_vmdq_82598, .init_rx_addrs = &ixgbe_init_rx_addrs_generic, - .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic, .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, .enable_mc = &ixgbe_enable_mc_generic, .disable_mc = &ixgbe_disable_mc_generic, .clear_vfta = &ixgbe_clear_vfta_82598, .set_vfta = &ixgbe_set_vfta_82598, .fc_enable = &ixgbe_fc_enable_82598, + .acquire_swfw_sync = &ixgbe_acquire_swfw_sync, + .release_swfw_sync = &ixgbe_release_swfw_sync, }; static struct ixgbe_eeprom_operations eeprom_ops_82598 = { |