Print this page
XXXX Intel X540 support
        
*** 28,82 ****
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.
  
  ******************************************************************************/
! /*$FreeBSD$*/
  
  #include "ixgbe_type.h"
  #include "ixgbe_api.h"
  #include "ixgbe_common.h"
  #include "ixgbe_phy.h"
  
- s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw);
- s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
-                                       ixgbe_link_speed *speed,
-                                       bool *autoneg);
- enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw);
- void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
- void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
- void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
- s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
-                                      ixgbe_link_speed speed, bool autoneg,
-                                      bool autoneg_wait_to_complete);
- s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
-                                      ixgbe_link_speed speed, bool autoneg,
-                                      bool autoneg_wait_to_complete);
- s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
-                                 bool autoneg_wait_to_complete);
- s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
-                                      ixgbe_link_speed speed,
-                                      bool autoneg,
-                                      bool autoneg_wait_to_complete);
  static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
                                                 ixgbe_link_speed speed,
                                                 bool autoneg,
                                                 bool autoneg_wait_to_complete);
- s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw);
- void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw);
- s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
- s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
- s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
- s32 ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw);
- s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
- s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw);
- u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
- s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval);
  static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
! bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
  
- 
  void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
  {
          struct ixgbe_mac_info *mac = &hw->mac;
  
          DEBUGFUNC("ixgbe_init_mac_link_ops_82599");
--- 28,55 ----
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.
  
  ******************************************************************************/
! /*$FreeBSD: src/sys/dev/ixgbe/ixgbe_82599.c,v 1.8 2012/07/05 20:51:44 jfv Exp $*/
  
  #include "ixgbe_type.h"
+ #include "ixgbe_82599.h"
  #include "ixgbe_api.h"
  #include "ixgbe_common.h"
  #include "ixgbe_phy.h"
  
  static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
                                           ixgbe_link_speed speed,
                                           bool autoneg,
                                           bool autoneg_wait_to_complete);
  static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
! static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
!                                    u16 offset, u16 *data);
! static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
!                                           u16 words, u16 *data);
  
  void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
  {
          struct ixgbe_mac_info *mac = &hw->mac;
  
          DEBUGFUNC("ixgbe_init_mac_link_ops_82599");
*** 150,163 ****
                  phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;
                  phy->ops.check_link = &ixgbe_check_phy_link_tnx;
                  phy->ops.get_firmware_version =
                               &ixgbe_get_phy_firmware_version_tnx;
                  break;
-         case ixgbe_phy_aq:
-                 phy->ops.get_firmware_version =
-                              &ixgbe_get_phy_firmware_version_generic;
-                 break;
          default:
                  break;
          }
  init_phy_ops_out:
          return ret_val;
--- 123,132 ----
*** 181,191 ****
                                                                &data_offset);
                  if (ret_val != IXGBE_SUCCESS)
                          goto setup_sfp_out;
  
                  /* PHY config will finish before releasing the semaphore */
!                 ret_val = ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
                  if (ret_val != IXGBE_SUCCESS) {
                          ret_val = IXGBE_ERR_SWFW_SYNC;
                          goto setup_sfp_out;
                  }
  
--- 150,161 ----
                                                                &data_offset);
                  if (ret_val != IXGBE_SUCCESS)
                          goto setup_sfp_out;
  
                  /* PHY config will finish before releasing the semaphore */
!                 ret_val = hw->mac.ops.acquire_swfw_sync(hw,
!                                                         IXGBE_GSSR_MAC_CSR_SM);
                  if (ret_val != IXGBE_SUCCESS) {
                          ret_val = IXGBE_ERR_SWFW_SYNC;
                          goto setup_sfp_out;
                  }
  
*** 195,205 ****
                          IXGBE_WRITE_FLUSH(hw);
                          hw->eeprom.ops.read(hw, ++data_offset, &data_value);
                  }
  
                  /* Release the semaphore */
!                 ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
                  /* Delay obtaining semaphore again to allow FW access */
                  msec_delay(hw->eeprom.semaphore_delay);
  
                  /* Now restart DSP by setting Restart_AN and clearing LMS */
                  IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
--- 165,175 ----
                          IXGBE_WRITE_FLUSH(hw);
                          hw->eeprom.ops.read(hw, ++data_offset, &data_value);
                  }
  
                  /* Release the semaphore */
!                 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
                  /* Delay obtaining semaphore again to allow FW access */
                  msec_delay(hw->eeprom.semaphore_delay);
  
                  /* Now restart DSP by setting Restart_AN and clearing LMS */
                  IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
*** 239,248 ****
--- 209,219 ----
  
  s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
  {
          struct ixgbe_mac_info *mac = &hw->mac;
          struct ixgbe_phy_info *phy = &hw->phy;
+         struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
          s32 ret_val;
  
          DEBUGFUNC("ixgbe_init_ops_82599");
  
          ret_val = ixgbe_init_phy_ops_generic(hw);
*** 256,290 ****
          mac->ops.reset_hw = &ixgbe_reset_hw_82599;
          mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_gen2;
          mac->ops.get_media_type = &ixgbe_get_media_type_82599;
          mac->ops.get_supported_physical_layer =
                                      &ixgbe_get_supported_physical_layer_82599;
          mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_82599;
          mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82599;
          mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82599;
!         mac->ops.start_hw = &ixgbe_start_hw_rev_1_82599;
          mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic;
          mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic;
          mac->ops.get_device_caps = &ixgbe_get_device_caps_generic;
          mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic;
          mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic;
  
          /* RAR, Multicast, VLAN */
          mac->ops.set_vmdq = &ixgbe_set_vmdq_generic;
          mac->ops.clear_vmdq = &ixgbe_clear_vmdq_generic;
          mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_generic;
          mac->rar_highwater = 1;
          mac->ops.set_vfta = &ixgbe_set_vfta_generic;
          mac->ops.clear_vfta = &ixgbe_clear_vfta_generic;
          mac->ops.init_uta_tables = &ixgbe_init_uta_tables_generic;
          mac->ops.setup_sfp = &ixgbe_setup_sfp_modules_82599;
          mac->ops.set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing;
          mac->ops.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing;
  
          /* Link */
          mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82599;
          mac->ops.check_link            = &ixgbe_check_mac_link_generic;
          ixgbe_init_mac_link_ops_82599(hw);
  
          mac->mcft_size        = 128;
          mac->vft_size         = 128;
          mac->num_rar_entries  = 128;
--- 227,266 ----
          mac->ops.reset_hw = &ixgbe_reset_hw_82599;
          mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_gen2;
          mac->ops.get_media_type = &ixgbe_get_media_type_82599;
          mac->ops.get_supported_physical_layer =
                                      &ixgbe_get_supported_physical_layer_82599;
+         mac->ops.disable_sec_rx_path = &ixgbe_disable_sec_rx_path_generic;
+         mac->ops.enable_sec_rx_path = &ixgbe_enable_sec_rx_path_generic;
          mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_82599;
          mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82599;
          mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82599;
!         mac->ops.start_hw = &ixgbe_start_hw_82599;
          mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic;
          mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic;
          mac->ops.get_device_caps = &ixgbe_get_device_caps_generic;
          mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic;
          mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic;
  
          /* RAR, Multicast, VLAN */
          mac->ops.set_vmdq = &ixgbe_set_vmdq_generic;
+         mac->ops.set_vmdq_san_mac = &ixgbe_set_vmdq_san_mac_generic;
          mac->ops.clear_vmdq = &ixgbe_clear_vmdq_generic;
          mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_generic;
          mac->rar_highwater = 1;
          mac->ops.set_vfta = &ixgbe_set_vfta_generic;
+         mac->ops.set_vlvf = &ixgbe_set_vlvf_generic;
          mac->ops.clear_vfta = &ixgbe_clear_vfta_generic;
          mac->ops.init_uta_tables = &ixgbe_init_uta_tables_generic;
          mac->ops.setup_sfp = &ixgbe_setup_sfp_modules_82599;
          mac->ops.set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing;
          mac->ops.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing;
  
          /* Link */
          mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82599;
          mac->ops.check_link = &ixgbe_check_mac_link_generic;
+         mac->ops.setup_rxpba = &ixgbe_set_rxpba_generic;
          ixgbe_init_mac_link_ops_82599(hw);
  
          mac->mcft_size          = 128;
          mac->vft_size           = 128;
          mac->num_rar_entries    = 128;
*** 291,300 ****
--- 267,289 ----
          mac->rx_pb_size         = 512;
          mac->max_tx_queues      = 128;
          mac->max_rx_queues      = 128;
          mac->max_msix_vectors   = ixgbe_get_pcie_msix_count_generic(hw);
  
+         mac->arc_subsystem_valid = (IXGBE_READ_REG(hw, IXGBE_FWSM) &
+                                    IXGBE_FWSM_MODE_MASK) ? TRUE : FALSE;
+ 
+         hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
+ 
+         /* EEPROM */
+         eeprom->ops.read = &ixgbe_read_eeprom_82599;
+         eeprom->ops.read_buffer = &ixgbe_read_eeprom_buffer_82599;
+ 
+         /* Manageability interface */
+         mac->ops.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic;
+ 
+ 
          return ret_val;
  }
  
  /**
   *  ixgbe_get_link_capabilities_82599 - Determines link capabilities
*** 314,324 ****
          DEBUGFUNC("ixgbe_get_link_capabilities_82599");
  
  
          /* Check if 1G SFP module. */
          if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
!             hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) {
                  *speed = IXGBE_LINK_SPEED_1GB_FULL;
                  *negotiation = TRUE;
                  goto out;
          }
  
--- 303,315 ----
          DEBUGFUNC("ixgbe_get_link_capabilities_82599");
  
  
          /* Check if 1G SFP module. */
          if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
!             hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
!             hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
!             hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
                  *speed = IXGBE_LINK_SPEED_1GB_FULL;
                  *negotiation = TRUE;
                  goto out;
          }
  
*** 410,420 ****
  
          /* Detect if there is a copper PHY attached. */
          switch (hw->phy.type) {
          case ixgbe_phy_cu_unknown:
          case ixgbe_phy_tn:
-         case ixgbe_phy_aq:
                  media_type = ixgbe_media_type_copper;
                  goto out;
          default:
                  break;
          }
--- 401,410 ----
*** 961,971 ****
  
          /* Setup the PHY according to input speed */
          status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
                                                autoneg_wait_to_complete);
          /* Set up MAC */
!         (void) ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
  
          return status;
  }
  
  /**
--- 951,961 ----
  
          /* 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_82599(hw, autoneg_wait_to_complete);
  
          return status;
  }
  
  /**
*** 976,996 ****
   *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
   *  reset.
   **/
  s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
  {
!         s32 status = IXGBE_SUCCESS;
!         u32 ctrl;
!         u32 i;
!         u32 autoc;
!         u32 autoc2;
  
          DEBUGFUNC("ixgbe_reset_hw_82599");
  
          /* Call adapter stop to disable tx/rx and clear interrupts */
!         hw->mac.ops.stop_adapter(hw);
  
          /* PHY ops must be identified and initialized prior to reset */
  
          /* Identify PHY and related function pointers */
          status = hw->phy.ops.init(hw);
  
--- 966,990 ----
   *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
   *  reset.
   **/
  s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
  {
!         ixgbe_link_speed link_speed;
!         s32 status;
!         u32 ctrl, i, autoc, autoc2;
!         bool link_up = FALSE;
  
          DEBUGFUNC("ixgbe_reset_hw_82599");
  
          /* Call adapter stop to disable tx/rx and clear interrupts */
!         status = hw->mac.ops.stop_adapter(hw);
!         if (status != IXGBE_SUCCESS)
!                 goto reset_hw_out;
  
+         /* flush pending Tx transactions */
+         ixgbe_clear_tx_pending(hw);
+ 
          /* PHY ops must be identified and initialized prior to reset */
  
          /* Identify PHY and related function pointers */
          status = hw->phy.ops.init(hw);
  
*** 1008,1059 ****
  
          /* Reset PHY */
          if (hw->phy.reset_disable == FALSE && hw->phy.ops.reset != NULL)
                  hw->phy.ops.reset(hw);
  
-         /*
-          * Prevent the PCI-E bus from from hanging by disabling PCI-E master
-          * access and verify no pending requests before reset
-          */
-         (void) 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
           */
!         ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
!         IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
          IXGBE_WRITE_FLUSH(hw);
  
          /* Poll for reset bit to self-clear indicating reset is complete */
          for (i = 0; i < 10; i++) {
                  usec_delay(1);
                  ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
!                 if (!(ctrl & IXGBE_CTRL_RST))
                          break;
          }
!         if (ctrl & IXGBE_CTRL_RST) {
                  status = IXGBE_ERR_RESET_FAILED;
                  DEBUGOUT("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;
-                 usec_delay(1);
                  goto mac_reset_top;
          }
  
-         msec_delay(50);
- 
          /*
           * Store the original AUTOC/AUTOC2 values if they have not been
           * stored off yet.  Otherwise restore the stored original
           * values since the reset operation sets back to defaults.
           */
--- 1002,1054 ----
  
          /* Reset PHY */
          if (hw->phy.reset_disable == FALSE && hw->phy.ops.reset != NULL)
                  hw->phy.ops.reset(hw);
  
  mac_reset_top:
          /*
!          * Issue global reset to the MAC.  Needs to be SW reset if link is up.
!          * If link reset is used when link is up, it might reset the PHY when
!          * mng is using it.  If link is down or the flag to force full link
!          * reset is set, then perform link reset.
           */
!         ctrl = IXGBE_CTRL_LNK_RST;
!         if (!hw->force_full_reset) {
!                 hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
!                 if (link_up)
!                         ctrl = IXGBE_CTRL_RST;
!         }
! 
!         ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
!         IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
          IXGBE_WRITE_FLUSH(hw);
  
          /* Poll for reset bit to self-clear indicating reset is complete */
          for (i = 0; i < 10; i++) {
                  usec_delay(1);
                  ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
!                 if (!(ctrl & IXGBE_CTRL_RST_MASK))
                          break;
          }
! 
!         if (ctrl & IXGBE_CTRL_RST_MASK) {
                  status = IXGBE_ERR_RESET_FAILED;
                  DEBUGOUT("Reset polling failed to complete.\n");
          }
  
+         msec_delay(50);
+ 
          /*
           * 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.
           */
          if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
                  hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
                  goto mac_reset_top;
          }
  
          /*
           * Store the original AUTOC/AUTOC2 values if they have not been
           * stored off yet.  Otherwise restore the stored original
           * values since the reset operation sets back to defaults.
           */
*** 1094,1103 ****
--- 1089,1101 ----
          /* Add the SAN MAC address to the RAR only if it's a valid address */
          if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
                  hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
                                      hw->mac.san_addr, 0, IXGBE_RAH_AV);
  
+                 /* Save the SAN MAC RAR index */
+                 hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
+ 
                  /* Reserve the last RAR for the SAN MAC address */
                  hw->mac.num_rar_entries--;
          }
  
          /* Store the alternative WWNN/WWPN prefix */
*** 1130,1140 ****
                          break;
                  usec_delay(10);
          }
          if (i >= IXGBE_FDIRCMD_CMD_POLL) {
                  DEBUGOUT("Flow Director previous command isn't complete, "
!                          "aborting table re-initialization. \n");
                  return IXGBE_ERR_FDIR_REINIT_FAILED;
          }
  
          IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
          IXGBE_WRITE_FLUSH(hw);
--- 1128,1138 ----
                          break;
                  usec_delay(10);
          }
          if (i >= IXGBE_FDIRCMD_CMD_POLL) {
                  DEBUGOUT("Flow Director previous command isn't complete, "
!                          "aborting table re-initialization.\n");
                  return IXGBE_ERR_FDIR_REINIT_FAILED;
          }
  
          IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
          IXGBE_WRITE_FLUSH(hw);
*** 1174,1251 ****
                  DEBUGOUT("Flow Director Signature poll time exceeded!\n");
                  return IXGBE_ERR_FDIR_REINIT_FAILED;
          }
  
          /* Clear FDIR statistics registers (read to clear) */
!         (void) IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT);
!         (void) IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT);
!         (void) IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
!         (void) IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
!         (void) IXGBE_READ_REG(hw, IXGBE_FDIRLEN);
  
          return IXGBE_SUCCESS;
  }
  
  /**
!  *  ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters
   *  @hw: pointer to hardware structure
!  *  @pballoc: which mode to allocate filters with
   **/
! s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc)
  {
-         u32 fdirctrl = 0;
-         u32 pbsize;
          int i;
  
!         DEBUGFUNC("ixgbe_init_fdir_signature_82599");
  
-         /*
-          * Before enabling Flow Director, the Rx Packet Buffer size
-          * must be reduced.  The new value is the current size minus
-          * flow director memory usage size.
-          */
-         pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc));
-         IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
-             (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize));
- 
-         /*
-          * The defaults in the HW for RX PB 1-7 are not zero and so should be
-          * intialized to zero for non DCB mode otherwise actual total RX PB
-          * would be bigger than programmed and filter space would run into
-          * the PB 0 region.
-          */
-         for (i = 1; i < 8; i++)
-                 IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
- 
-         /* Send interrupt when 64 filters are left */
-         fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
- 
-         /* Set the maximum length per hash bucket to 0xA filters */
-         fdirctrl |= 0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT;
- 
-         switch (pballoc) {
-         case IXGBE_FDIR_PBALLOC_64K:
-                 /* 8k - 1 signature filters */
-                 fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
-                 break;
-         case IXGBE_FDIR_PBALLOC_128K:
-                 /* 16k - 1 signature filters */
-                 fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
-                 break;
-         case IXGBE_FDIR_PBALLOC_256K:
-                 /* 32k - 1 signature filters */
-                 fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
-                 break;
-         default:
-                 /* bad value */
-                 return IXGBE_ERR_CONFIG;
-         };
- 
-         /* Move the flexible bytes to use the ethertype - shift 6 words */
-         fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
- 
- 
          /* Prime the keys for hashing */
          IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY);
          IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, IXGBE_ATR_SIGNATURE_HASH_KEY);
  
          /*
--- 1172,1201 ----
                  DEBUGOUT("Flow Director Signature poll time exceeded!\n");
                  return IXGBE_ERR_FDIR_REINIT_FAILED;
          }
  
          /* Clear FDIR statistics registers (read to clear) */
!         IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT);
!         IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT);
!         IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
!         IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
!         IXGBE_READ_REG(hw, IXGBE_FDIRLEN);
  
          return IXGBE_SUCCESS;
  }
  
  /**
!  *  ixgbe_fdir_enable_82599 - Initialize Flow Director control registers
   *  @hw: pointer to hardware structure
!  *  @fdirctrl: value to write to flow director control register
   **/
! static void ixgbe_fdir_enable_82599(struct ixgbe_hw *hw, u32 fdirctrl)
  {
          int i;
  
!         DEBUGFUNC("ixgbe_fdir_enable_82599");
  
          /* Prime the keys for hashing */
          IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY);
          IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, IXGBE_ATR_SIGNATURE_HASH_KEY);
  
          /*
*** 1267,1467 ****
                  if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
                                     IXGBE_FDIRCTRL_INIT_DONE)
                          break;
                  msec_delay(1);
          }
-         if (i >= IXGBE_FDIR_INIT_DONE_POLL)
-                 DEBUGOUT("Flow Director Signature poll time exceeded!\n");
  
!         return IXGBE_SUCCESS;
  }
  
  /**
!  *  ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters
   *  @hw: pointer to hardware structure
!  *  @pballoc: which mode to allocate filters with
   **/
! s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
  {
!         u32 fdirctrl = 0;
!         u32 pbsize;
!         int i;
  
-         DEBUGFUNC("ixgbe_init_fdir_perfect_82599");
- 
          /*
!          * Before enabling Flow Director, the Rx Packet Buffer size
!          * must be reduced.  The new value is the current size minus
!          * flow director memory usage size.
           */
!         pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc));
!         IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
!             (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize));
  
!         /*
!          * The defaults in the HW for RX PB 1-7 are not zero and so should be
!          * intialized to zero for non DCB mode otherwise actual total RX PB
!          * would be bigger than programmed and filter space would run into
!          * the PB 0 region.
!          */
!         for (i = 1; i < 8; i++)
!                 IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
  
-         /* Send interrupt when 64 filters are left */
-         fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
- 
-         /* Initialize the drop queue to Rx queue 127 */
-         fdirctrl |= (127 << IXGBE_FDIRCTRL_DROP_Q_SHIFT);
- 
-         switch (pballoc) {
-         case IXGBE_FDIR_PBALLOC_64K:
-                 /* 2k - 1 perfect filters */
-                 fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
-                 break;
-         case IXGBE_FDIR_PBALLOC_128K:
-                 /* 4k - 1 perfect filters */
-                 fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
-                 break;
-         case IXGBE_FDIR_PBALLOC_256K:
-                 /* 8k - 1 perfect filters */
-                 fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
-                 break;
-         default:
-                 /* bad value */
-                 return IXGBE_ERR_CONFIG;
-         };
- 
-         /* Turn perfect match filtering on */
-         fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH;
-         fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS;
- 
-         /* Move the flexible bytes to use the ethertype - shift 6 words */
-         fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
- 
-         /* Prime the keys for hashing */
-         IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY);
-         IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY,IXGBE_ATR_SIGNATURE_HASH_KEY);
- 
-         /*
-          * Poll init-done after we write the register.  Estimated times:
-          *      10G: PBALLOC = 11b, timing is 60us
-          *       1G: PBALLOC = 11b, timing is 600us
-          *     100M: PBALLOC = 11b, timing is 6ms
-          *
-          *     Multiple these timings by 4 if under full Rx load
-          *
-          * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
-          * 1 msec per poll time.  If we're at line rate and drop to 100M, then
-          * this might not finish in our poll time, but we can live with that
-          * for now.
-          */
- 
-         /* Set the maximum length per hash bucket to 0xA filters */
-         fdirctrl |= (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT);
- 
-         IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
-         IXGBE_WRITE_FLUSH(hw);
-         for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
-                 if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
-                                    IXGBE_FDIRCTRL_INIT_DONE)
-                         break;
-                 msec_delay(1);
-         }
-         if (i >= IXGBE_FDIR_INIT_DONE_POLL)
-                 DEBUGOUT("Flow Director Perfect poll time exceeded!\n");
- 
          return IXGBE_SUCCESS;
  }
  
  /**
!  *  ixgbe_atr_compute_hash_82599 - Compute the hashes for SW ATR
!  *  @stream: input bitstream to compute the hash on
!  *  @key: 32-bit hash key
   **/
! u32 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *atr_input,
!                                  u32 key)
  {
!         /*
!          * The algorithm is as follows:
!          *    Hash[15:0] = Sum { S[n] x K[n+16] }, n = 0...350
!          *    where Sum {A[n]}, n = 0...n is bitwise XOR of A[0], A[1]...A[n]
!          *    and A[n] x B[n] is bitwise AND between same length strings
!          *
!          *    K[n] is 16 bits, defined as:
!          *       for n modulo 32 >= 15, K[n] = K[n % 32 : (n % 32) - 15]
!          *       for n modulo 32 < 15, K[n] =
!          *             K[(n % 32:0) | (31:31 - (14 - (n % 32)))]
!          *
!          *    S[n] is 16 bits, defined as:
!          *       for n >= 15, S[n] = S[n:n - 15]
!          *       for n < 15, S[n] = S[(n:0) | (350:350 - (14 - n))]
!          *
!          *    To simplify for programming, the algorithm is implemented
!          *    in software this way:
!          *
!          *    key[31:0], hi_hash_dword[31:0], lo_hash_dword[31:0], hash[15:0]
!          *
!          *    for (i = 0; i < 352; i+=32)
!          *        hi_hash_dword[31:0] ^= Stream[(i+31):i];
!          *
!          *    lo_hash_dword[15:0]  ^= Stream[15:0];
!          *    lo_hash_dword[15:0]  ^= hi_hash_dword[31:16];
!          *    lo_hash_dword[31:16] ^= hi_hash_dword[15:0];
!          *
!          *    hi_hash_dword[31:0]  ^= Stream[351:320];
!          *
!          *    if(key[0])
!          *        hash[15:0] ^= Stream[15:0];
!          *
!          *    for (i = 0; i < 16; i++) {
!          *        if (key[i])
!          *            hash[15:0] ^= lo_hash_dword[(i+15):i];
!          *        if (key[i + 16])
!          *            hash[15:0] ^= hi_hash_dword[(i+15):i];
!          *    }
!          *
!          */
!         __be32 common_hash_dword = 0;
!         u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
!         u32 hash_result = 0;
!         u8 i;
  
-         /* record the flow_vm_vlan bits as they are a key part to the hash */
-         flow_vm_vlan = IXGBE_NTOHL(atr_input->dword_stream[0]);
- 
-         /* generate common hash dword */
-         for (i = 10; i; i -= 2)
-                 common_hash_dword ^= atr_input->dword_stream[i] ^
-                                      atr_input->dword_stream[i - 1];
- 
-         hi_hash_dword = IXGBE_NTOHL(common_hash_dword);
- 
-         /* low dword is word swapped version of common */
-         lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16);
- 
-         /* apply flow ID/VM pool/VLAN ID bits to hash words */
-         hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16);
- 
-         /* Process bits 0 and 16 */
-         if (key & 0x0001) hash_result ^= lo_hash_dword;
-         if (key & 0x00010000) hash_result ^= hi_hash_dword;
- 
          /*
!          * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
!          * delay this because bit 0 of the stream should not be processed
!          * so we do not add the vlan until after bit 0 was processed
           */
!         lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
  
  
!         /* process the remaining 30 bits in the key 2 bits at a time */
!         for (i = 15; i; i-- ) {
!                 if (key & (0x0001 << i)) hash_result ^= lo_hash_dword >> i;
!                 if (key & (0x00010000 << i)) hash_result ^= hi_hash_dword >> i;
!         }
! 
!         return hash_result & IXGBE_ATR_HASH_MASK;
  }
  
  /*
   * These defines allow us to quickly generate all of the necessary instructions
   * in the function below by simply calling out IXGBE_COMPUTE_SIG_HASH_ITERATION
--- 1217,1287 ----
                  if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
                                     IXGBE_FDIRCTRL_INIT_DONE)
                          break;
                  msec_delay(1);
          }
  
!         if (i >= IXGBE_FDIR_INIT_DONE_POLL)
!                 DEBUGOUT("Flow Director poll time exceeded!\n");
  }
  
  /**
!  *  ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters
   *  @hw: pointer to hardware structure
!  *  @fdirctrl: value to write to flow director control register, initially
!  *           contains just the value of the Rx packet buffer allocation
   **/
! s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl)
  {
!         DEBUGFUNC("ixgbe_init_fdir_signature_82599");
  
          /*
!          * Continue setup of fdirctrl register bits:
!          *  Move the flexible bytes to use the ethertype - shift 6 words
!          *  Set the maximum length per hash bucket to 0xA filters
!          *  Send interrupt when 64 filters are left
           */
!         fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) |
!                     (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) |
!                     (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT);
  
!         /* write hashes and fdirctrl register, poll for completion */
!         ixgbe_fdir_enable_82599(hw, fdirctrl);
  
          return IXGBE_SUCCESS;
  }
  
  /**
!  *  ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters
!  *  @hw: pointer to hardware structure
!  *  @fdirctrl: value to write to flow director control register, initially
!  *           contains just the value of the Rx packet buffer allocation
   **/
! s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl)
  {
!         DEBUGFUNC("ixgbe_init_fdir_perfect_82599");
  
          /*
!          * Continue setup of fdirctrl register bits:
!          *  Turn perfect match filtering on
!          *  Report hash in RSS field of Rx wb descriptor
!          *  Initialize the drop queue
!          *  Move the flexible bytes to use the ethertype - shift 6 words
!          *  Set the maximum length per hash bucket to 0xA filters
!          *  Send interrupt when 64 (0x4 * 16) filters are left
           */
!         fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH |
!                     IXGBE_FDIRCTRL_REPORT_STATUS |
!                     (IXGBE_FDIR_DROP_QUEUE << IXGBE_FDIRCTRL_DROP_Q_SHIFT) |
!                     (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) |
!                     (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) |
!                     (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT);
  
+         /* write hashes and fdirctrl register, poll for completion */
+         ixgbe_fdir_enable_82599(hw, fdirctrl);
  
!         return IXGBE_SUCCESS;
  }
  
  /*
   * These defines allow us to quickly generate all of the necessary instructions
   * in the function below by simply calling out IXGBE_COMPUTE_SIG_HASH_ITERATION
*** 1468,1478 ****
   * for values 0 through 15
   */
  #define IXGBE_ATR_COMMON_HASH_KEY \
                  (IXGBE_ATR_BUCKET_HASH_KEY & IXGBE_ATR_SIGNATURE_HASH_KEY)
  #define IXGBE_COMPUTE_SIG_HASH_ITERATION(_n) \
! { \
          u32 n = (_n); \
          if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << n)) \
                  common_hash ^= lo_hash_dword >> n; \
          else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \
                  bucket_hash ^= lo_hash_dword >> n; \
--- 1288,1298 ----
   * for values 0 through 15
   */
  #define IXGBE_ATR_COMMON_HASH_KEY \
                  (IXGBE_ATR_BUCKET_HASH_KEY & IXGBE_ATR_SIGNATURE_HASH_KEY)
  #define IXGBE_COMPUTE_SIG_HASH_ITERATION(_n) \
! do { \
          u32 n = (_n); \
          if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << n)) \
                  common_hash ^= lo_hash_dword >> n; \
          else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \
                  bucket_hash ^= lo_hash_dword >> n; \
*** 1482,1492 ****
                  common_hash ^= hi_hash_dword >> n; \
          else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \
                  bucket_hash ^= hi_hash_dword >> n; \
          else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << (n + 16))) \
                  sig_hash ^= hi_hash_dword << (16 - n); \
! }
  
  /**
   *  ixgbe_atr_compute_sig_hash_82599 - Compute the signature hash
   *  @stream: input bitstream to compute the hash on
   *
--- 1302,1312 ----
                  common_hash ^= hi_hash_dword >> n; \
          else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \
                  bucket_hash ^= hi_hash_dword >> n; \
          else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << (n + 16))) \
                  sig_hash ^= hi_hash_dword << (16 - n); \
! } while (0);
  
  /**
   *  ixgbe_atr_compute_sig_hash_82599 - Compute the signature hash
   *  @stream: input bitstream to compute the hash on
   *
*** 1494,1504 ****
   *  several optomizations such as unwinding all of the loops, letting the
   *  compiler work out all of the conditional ifs since the keys are static
   *  defines, and computing two keys at once since the hashed dword stream
   *  will be the same for both keys.
   **/
! static u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
                                              union ixgbe_atr_hash_dword common)
  {
          u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
          u32 sig_hash = 0, bucket_hash = 0, common_hash = 0;
  
--- 1314,1324 ----
   *  several optomizations such as unwinding all of the loops, letting the
   *  compiler work out all of the conditional ifs since the keys are static
   *  defines, and computing two keys at once since the hashed dword stream
   *  will be the same for both keys.
   **/
! u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
                                       union ixgbe_atr_hash_dword common)
  {
          u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
          u32 sig_hash = 0, bucket_hash = 0, common_hash = 0;
  
*** 1553,1563 ****
  }
  
  /**
   *  ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter
   *  @hw: pointer to hardware structure
!  *  @stream: input bitstream
   *  @queue: queue index to direct traffic to
   **/
  s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
                                            union ixgbe_atr_hash_dword input,
                                            union ixgbe_atr_hash_dword common,
--- 1373,1384 ----
  }
  
  /**
   *  ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter
   *  @hw: pointer to hardware structure
!  *  @input: unique input dword
!  *  @common: compressed common input dword
   *  @queue: queue index to direct traffic to
   **/
  s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
                                            union ixgbe_atr_hash_dword input,
                                            union ixgbe_atr_hash_dword common,
*** 1602,1625 ****
          DEBUGOUT2("Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd);
  
          return IXGBE_SUCCESS;
  }
  
  /**
   *  ixgbe_get_fdirtcpm_82599 - generate a tcp port from atr_input_masks
   *  @input_mask: mask to be bit swapped
   *
   *  The source and destination port masks for flow director are bit swapped
   *  in that bit 15 effects bit 0, 14 effects 1, 13, 2 etc.  In order to
   *  generate a correctly swapped value we need to bit swap the mask and that
   *  is what is accomplished by this function.
   **/
! static u32 ixgbe_get_fdirtcpm_82599(struct ixgbe_atr_input_masks *input_masks)
  {
!         u32 mask = IXGBE_NTOHS(input_masks->dst_port_mask);
          mask <<= IXGBE_FDIRTCPM_DPORTM_SHIFT;
!         mask |= IXGBE_NTOHS(input_masks->src_port_mask);
          mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1);
          mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2);
          mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4);
          return ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8);
  }
--- 1423,1541 ----
          DEBUGOUT2("Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd);
  
          return IXGBE_SUCCESS;
  }
  
+ #define IXGBE_COMPUTE_BKT_HASH_ITERATION(_n) \
+ do { \
+         u32 n = (_n); \
+         if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \
+                 bucket_hash ^= lo_hash_dword >> n; \
+         if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \
+                 bucket_hash ^= hi_hash_dword >> n; \
+ } while (0);
+ 
  /**
+  *  ixgbe_atr_compute_perfect_hash_82599 - Compute the perfect filter hash
+  *  @atr_input: input bitstream to compute the hash on
+  *  @input_mask: mask for the input bitstream
+  *
+  *  This function serves two main purposes.  First it applys the input_mask
+  *  to the atr_input resulting in a cleaned up atr_input data stream.
+  *  Secondly it computes the hash and stores it in the bkt_hash field at
+  *  the end of the input byte stream.  This way it will be available for
+  *  future use without needing to recompute the hash.
+  **/
+ void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
+                                           union ixgbe_atr_input *input_mask)
+ {
+ 
+         u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
+         u32 bucket_hash = 0;
+ 
+         /* Apply masks to input data */
+         input->dword_stream[0]  &= input_mask->dword_stream[0];
+         input->dword_stream[1]  &= input_mask->dword_stream[1];
+         input->dword_stream[2]  &= input_mask->dword_stream[2];
+         input->dword_stream[3]  &= input_mask->dword_stream[3];
+         input->dword_stream[4]  &= input_mask->dword_stream[4];
+         input->dword_stream[5]  &= input_mask->dword_stream[5];
+         input->dword_stream[6]  &= input_mask->dword_stream[6];
+         input->dword_stream[7]  &= input_mask->dword_stream[7];
+         input->dword_stream[8]  &= input_mask->dword_stream[8];
+         input->dword_stream[9]  &= input_mask->dword_stream[9];
+         input->dword_stream[10] &= input_mask->dword_stream[10];
+ 
+         /* record the flow_vm_vlan bits as they are a key part to the hash */
+         flow_vm_vlan = IXGBE_NTOHL(input->dword_stream[0]);
+ 
+         /* generate common hash dword */
+         hi_hash_dword = IXGBE_NTOHL(input->dword_stream[1] ^
+                                     input->dword_stream[2] ^
+                                     input->dword_stream[3] ^
+                                     input->dword_stream[4] ^
+                                     input->dword_stream[5] ^
+                                     input->dword_stream[6] ^
+                                     input->dword_stream[7] ^
+                                     input->dword_stream[8] ^
+                                     input->dword_stream[9] ^
+                                     input->dword_stream[10]);
+ 
+         /* low dword is word swapped version of common */
+         lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16);
+ 
+         /* apply flow ID/VM pool/VLAN ID bits to hash words */
+         hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16);
+ 
+         /* Process bits 0 and 16 */
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(0);
+ 
+         /*
+          * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
+          * delay this because bit 0 of the stream should not be processed
+          * so we do not add the vlan until after bit 0 was processed
+          */
+         lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
+ 
+         /* Process remaining 30 bit of the key */
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(1);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(2);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(3);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(4);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(5);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(6);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(7);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(8);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(9);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(10);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(11);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(12);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(13);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(14);
+         IXGBE_COMPUTE_BKT_HASH_ITERATION(15);
+ 
+         /*
+          * Limit hash to 13 bits since max bucket count is 8K.
+          * Store result at the end of the input stream.
+          */
+         input->formatted.bkt_hash = bucket_hash & 0x1FFF;
+ }
+ 
+ /**
   *  ixgbe_get_fdirtcpm_82599 - generate a tcp port from atr_input_masks
   *  @input_mask: mask to be bit swapped
   *
   *  The source and destination port masks for flow director are bit swapped
   *  in that bit 15 effects bit 0, 14 effects 1, 13, 2 etc.  In order to
   *  generate a correctly swapped value we need to bit swap the mask and that
   *  is what is accomplished by this function.
   **/
! static u32 ixgbe_get_fdirtcpm_82599(union ixgbe_atr_input *input_mask)
  {
!         u32 mask = IXGBE_NTOHS(input_mask->formatted.dst_port);
          mask <<= IXGBE_FDIRTCPM_DPORTM_SHIFT;
!         mask |= IXGBE_NTOHS(input_mask->formatted.src_port);
          mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1);
          mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2);
          mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4);
          return ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8);
  }
*** 1637,1801 ****
  
  #define IXGBE_WRITE_REG_BE32(a, reg, value) \
          IXGBE_WRITE_REG((a), (reg), IXGBE_STORE_AS_BE32(IXGBE_NTOHL(value)))
  
  #define IXGBE_STORE_AS_BE16(_value) \
!         (((u16)(_value) >> 8) | ((u16)(_value) << 8))
  
! 
! /**
!  *  ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
!  *  @hw: pointer to hardware structure
!  *  @input: input bitstream
!  *  @input_masks: masks for the input bitstream
!  *  @soft_id: software index for the filters
!  *  @queue: queue index to direct traffic to
!  *
!  *  Note that the caller to this function must lock before calling, since the
!  *  hardware writes must be protected from one another.
!  **/
! s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
!                                       union ixgbe_atr_input *input,
!                                       struct ixgbe_atr_input_masks *input_masks,
!                                       u16 soft_id, u8 queue)
  {
!         u32 fdirhash;
!         u32 fdircmd;
!         u32 fdirport, fdirtcpm;
!         u32 fdirvlan;
!         /* start with VLAN, flex bytes, VM pool, and IPv6 destination masked */
!         u32 fdirm = IXGBE_FDIRM_VLANID | IXGBE_FDIRM_VLANP | IXGBE_FDIRM_FLEX |
!                     IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6;
  
!         DEBUGFUNC("ixgbe_fdir_add_perfect_filter_82599");
  
          /*
-          * Check flow_type formatting, and bail out before we touch the hardware
-          * if there's a configuration issue
-          */
-         switch (input->formatted.flow_type) {
-         case IXGBE_ATR_FLOW_TYPE_IPV4:
-                 /* use the L4 protocol mask for raw IPv4/IPv6 traffic */
-                 fdirm |= IXGBE_FDIRM_L4P;
-                 /* FALLTHRU */
-         case IXGBE_ATR_FLOW_TYPE_SCTPV4:
-                 if (input_masks->dst_port_mask || input_masks->src_port_mask) {
-                         DEBUGOUT(" Error on src/dst port mask\n");
-                         return IXGBE_ERR_CONFIG;
-                 }
-                 break;
-         case IXGBE_ATR_FLOW_TYPE_TCPV4:
-                 break;
-         case IXGBE_ATR_FLOW_TYPE_UDPV4:
-                 break;
-         default:
-                 DEBUGOUT(" Error on flow type input\n");
-                 return IXGBE_ERR_CONFIG;
-         }
- 
-         /*
           * Program the relevant mask registers.  If src/dst_port or src/dst_addr
           * are zero, then assume a full mask for that field.  Also assume that
           * a VLAN of 0 is unspecified, so mask that out as well.  L4type
           * cannot be masked out in this implementation.
           *
           * This also assumes IPv4 only.  IPv6 masking isn't supported at this
           * point in time.
           */
  
!         /* Program FDIRM */
!         switch (IXGBE_NTOHS(input_masks->vlan_id_mask) & 0xEFFF) {
!         case 0xEFFF:
!                 /* Unmask VLAN ID - bit 0 and fall through to unmask prio */
!                 fdirm &= ~IXGBE_FDIRM_VLANID;
!                 /* FALLTHRU */
!         case 0xE000:
!                 /* Unmask VLAN prio - bit 1 */
!                 fdirm &= ~IXGBE_FDIRM_VLANP;
                  break;
!         case 0x0FFF:
!                 /* Unmask VLAN ID - bit 0 */
!                 fdirm &= ~IXGBE_FDIRM_VLANID;
                  break;
          case 0x0000:
!                 /* do nothing, vlans already masked */
                  break;
          default:
                  DEBUGOUT(" Error on VLAN mask\n");
                  return IXGBE_ERR_CONFIG;
          }
  
!         if (input_masks->flex_mask & 0xFFFF) {
!                 if ((input_masks->flex_mask & 0xFFFF) != 0xFFFF) {
                          DEBUGOUT(" Error on flexible byte mask\n");
                          return IXGBE_ERR_CONFIG;
                  }
-                 /* Unmask Flex Bytes - bit 4 */
-                 fdirm &= ~IXGBE_FDIRM_FLEX;
-         }
  
          /* Now mask VM pool and destination IPv6 - bits 5 and 2 */
          IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
  
          /* store the TCP/UDP port masks, bit reversed from port layout */
!         fdirtcpm = ixgbe_get_fdirtcpm_82599(input_masks);
  
          /* write both the same so that UDP and TCP use the same mask */
          IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm);
          IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm);
  
          /* store source and destination IP masks (big-enian) */
          IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M,
!                              ~input_masks->src_ip_mask[0]);
          IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M,
!                              ~input_masks->dst_ip_mask[0]);
  
!         /* Apply masks to input data */
!         input->formatted.vlan_id &= input_masks->vlan_id_mask;
!         input->formatted.flex_bytes &= input_masks->flex_mask;
!         input->formatted.src_port &= input_masks->src_port_mask;
!         input->formatted.dst_port &= input_masks->dst_port_mask;
!         input->formatted.src_ip[0] &= input_masks->src_ip_mask[0];
!         input->formatted.dst_ip[0] &= input_masks->dst_ip_mask[0];
  
!         /* record vlan (little-endian) and flex_bytes(big-endian) */
!         fdirvlan =
!                 IXGBE_STORE_AS_BE16(IXGBE_NTOHS(input->formatted.flex_bytes));
!         fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT;
!         fdirvlan |= IXGBE_NTOHS(input->formatted.vlan_id);
!         IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan);
  
          /* record source and destination port (little-endian)*/
          fdirport = IXGBE_NTOHS(input->formatted.dst_port);
          fdirport <<= IXGBE_FDIRPORT_DESTINATION_SHIFT;
          fdirport |= IXGBE_NTOHS(input->formatted.src_port);
          IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport);
  
!         /* record the first 32 bits of the destination address (big-endian) */
!         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA, input->formatted.dst_ip[0]);
  
!         /* record the source address (big-endian) */
!         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[0]);
  
          /* configure FDIRCMD register */
          fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
                    IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
          fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
          fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
  
!         /* we only want the bucket hash so drop the upper 16 bits */
!         fdirhash = ixgbe_atr_compute_hash_82599(input,
!                                                 IXGBE_ATR_BUCKET_HASH_KEY);
          fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
  
          IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
!         IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
  
!         return IXGBE_SUCCESS;
  }
  
  /**
   *  ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
   *  @hw: pointer to hardware structure
   *  @reg: analog register to read
   *  @val: read value
   *
--- 1553,1825 ----
  
  #define IXGBE_WRITE_REG_BE32(a, reg, value) \
          IXGBE_WRITE_REG((a), (reg), IXGBE_STORE_AS_BE32(IXGBE_NTOHL(value)))
  
  #define IXGBE_STORE_AS_BE16(_value) \
!         IXGBE_NTOHS(((u16)(_value) >> 8) | ((u16)(_value) << 8))
  
! s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
!                                     union ixgbe_atr_input *input_mask)
  {
!         /* mask IPv6 since it is currently not supported */
!         u32 fdirm = IXGBE_FDIRM_DIPv6;
!         u32 fdirtcpm;
  
!         DEBUGFUNC("ixgbe_fdir_set_atr_input_mask_82599");
  
          /*
           * Program the relevant mask registers.  If src/dst_port or src/dst_addr
           * are zero, then assume a full mask for that field.  Also assume that
           * a VLAN of 0 is unspecified, so mask that out as well.  L4type
           * cannot be masked out in this implementation.
           *
           * This also assumes IPv4 only.  IPv6 masking isn't supported at this
           * point in time.
           */
  
!         /* verify bucket hash is cleared on hash generation */
!         if (input_mask->formatted.bkt_hash)
!                 DEBUGOUT(" bucket hash should always be 0 in mask\n");
! 
!         /* Program FDIRM and verify partial masks */
!         switch (input_mask->formatted.vm_pool & 0x7F) {
!         case 0x0:
!                 fdirm |= IXGBE_FDIRM_POOL;
!         case 0x7F:
                  break;
!         default:
!                 DEBUGOUT(" Error on vm pool mask\n");
!                 return IXGBE_ERR_CONFIG;
!         }
! 
!         switch (input_mask->formatted.flow_type & IXGBE_ATR_L4TYPE_MASK) {
!         case 0x0:
!                 fdirm |= IXGBE_FDIRM_L4P;
!                 if (input_mask->formatted.dst_port ||
!                     input_mask->formatted.src_port) {
!                         DEBUGOUT(" Error on src/dst port mask\n");
!                         return IXGBE_ERR_CONFIG;
!                 }
!         case IXGBE_ATR_L4TYPE_MASK:
                  break;
+         default:
+                 DEBUGOUT(" Error on flow type mask\n");
+                 return IXGBE_ERR_CONFIG;
+         }
+ 
+         switch (IXGBE_NTOHS(input_mask->formatted.vlan_id) & 0xEFFF) {
          case 0x0000:
!                 /* mask VLAN ID, fall through to mask VLAN priority */
!                 fdirm |= IXGBE_FDIRM_VLANID;
!         case 0x0FFF:
!                 /* mask VLAN priority */
!                 fdirm |= IXGBE_FDIRM_VLANP;
                  break;
+         case 0xE000:
+                 /* mask VLAN ID only, fall through */
+                 fdirm |= IXGBE_FDIRM_VLANID;
+         case 0xEFFF:
+                 /* no VLAN fields masked */
+                 break;
          default:
                  DEBUGOUT(" Error on VLAN mask\n");
                  return IXGBE_ERR_CONFIG;
          }
  
!         switch (input_mask->formatted.flex_bytes & 0xFFFF) {
!         case 0x0000:
!                 /* Mask Flex Bytes, fall through */
!                 fdirm |= IXGBE_FDIRM_FLEX;
!         case 0xFFFF:
!                 break;
!         default:
                  DEBUGOUT(" Error on flexible byte mask\n");
                  return IXGBE_ERR_CONFIG;
          }
  
          /* Now mask VM pool and destination IPv6 - bits 5 and 2 */
          IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
  
          /* store the TCP/UDP port masks, bit reversed from port layout */
!         fdirtcpm = ixgbe_get_fdirtcpm_82599(input_mask);
  
          /* write both the same so that UDP and TCP use the same mask */
          IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm);
          IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm);
  
          /* store source and destination IP masks (big-enian) */
          IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M,
!                              ~input_mask->formatted.src_ip[0]);
          IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M,
!                              ~input_mask->formatted.dst_ip[0]);
  
!         return IXGBE_SUCCESS;
! }
  
! s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
!                                           union ixgbe_atr_input *input,
!                                           u16 soft_id, u8 queue)
! {
!         u32 fdirport, fdirvlan, fdirhash, fdircmd;
  
+         DEBUGFUNC("ixgbe_fdir_write_perfect_filter_82599");
+ 
+         /* currently IPv6 is not supported, must be programmed with 0 */
+         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0),
+                              input->formatted.src_ip[0]);
+         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(1),
+                              input->formatted.src_ip[1]);
+         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(2),
+                              input->formatted.src_ip[2]);
+ 
+         /* record the source address (big-endian) */
+         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[0]);
+ 
+         /* record the first 32 bits of the destination address (big-endian) */
+         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA, input->formatted.dst_ip[0]);
+ 
          /* record source and destination port (little-endian)*/
          fdirport = IXGBE_NTOHS(input->formatted.dst_port);
          fdirport <<= IXGBE_FDIRPORT_DESTINATION_SHIFT;
          fdirport |= IXGBE_NTOHS(input->formatted.src_port);
          IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport);
  
!         /* record vlan (little-endian) and flex_bytes(big-endian) */
!         fdirvlan = IXGBE_STORE_AS_BE16(input->formatted.flex_bytes);
!         fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT;
!         fdirvlan |= IXGBE_NTOHS(input->formatted.vlan_id);
!         IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan);
  
!         /* configure FDIRHASH register */
!         fdirhash = input->formatted.bkt_hash;
!         fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
!         IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
  
+         /*
+          * flush all previous writes to make certain registers are
+          * programmed prior to issuing the command
+          */
+         IXGBE_WRITE_FLUSH(hw);
+ 
          /* configure FDIRCMD register */
          fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
                    IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
+         if (queue == IXGBE_FDIR_DROP_QUEUE)
+                 fdircmd |= IXGBE_FDIRCMD_DROP;
          fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
          fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
+         fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT;
  
!         IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
! 
!         return IXGBE_SUCCESS;
! }
! 
! s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
!                                           union ixgbe_atr_input *input,
!                                           u16 soft_id)
! {
!         u32 fdirhash;
!         u32 fdircmd = 0;
!         u32 retry_count;
!         s32 err = IXGBE_SUCCESS;
! 
!         /* configure FDIRHASH register */
!         fdirhash = input->formatted.bkt_hash;
          fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
+         IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
  
+         /* flush hash to HW */
+         IXGBE_WRITE_FLUSH(hw);
+ 
+         /* Query if filter is present */
+         IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT);
+ 
+         for (retry_count = 10; retry_count; retry_count--) {
+                 /* allow 10us for query to process */
+                 usec_delay(10);
+                 /* verify query completed successfully */
+                 fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
+                 if (!(fdircmd & IXGBE_FDIRCMD_CMD_MASK))
+                         break;
+         }
+ 
+         if (!retry_count)
+                 err = IXGBE_ERR_FDIR_REINIT_FAILED;
+ 
+         /* if filter exists in hardware then remove it */
+         if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) {
                  IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
!                 IXGBE_WRITE_FLUSH(hw);
!                 IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
!                                 IXGBE_FDIRCMD_CMD_REMOVE_FLOW);
!         }
  
!         return err;
  }
  
  /**
+  *  ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
+  *  @hw: pointer to hardware structure
+  *  @input: input bitstream
+  *  @input_mask: mask for the input bitstream
+  *  @soft_id: software index for the filters
+  *  @queue: queue index to direct traffic to
+  *
+  *  Note that the caller to this function must lock before calling, since the
+  *  hardware writes must be protected from one another.
+  **/
+ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
+                                         union ixgbe_atr_input *input,
+                                         union ixgbe_atr_input *input_mask,
+                                         u16 soft_id, u8 queue)
+ {
+         s32 err = IXGBE_ERR_CONFIG;
+ 
+         DEBUGFUNC("ixgbe_fdir_add_perfect_filter_82599");
+ 
+         /*
+          * Check flow_type formatting, and bail out before we touch the hardware
+          * if there's a configuration issue
+          */
+         switch (input->formatted.flow_type) {
+         case IXGBE_ATR_FLOW_TYPE_IPV4:
+                 input_mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK;
+                 if (input->formatted.dst_port || input->formatted.src_port) {
+                         DEBUGOUT(" Error on src/dst port\n");
+                         return IXGBE_ERR_CONFIG;
+                 }
+                 break;
+         case IXGBE_ATR_FLOW_TYPE_SCTPV4:
+                 if (input->formatted.dst_port || input->formatted.src_port) {
+                         DEBUGOUT(" Error on src/dst port\n");
+                         return IXGBE_ERR_CONFIG;
+                 }
+         case IXGBE_ATR_FLOW_TYPE_TCPV4:
+         case IXGBE_ATR_FLOW_TYPE_UDPV4:
+                 input_mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK |
+                                                   IXGBE_ATR_L4TYPE_MASK;
+                 break;
+         default:
+                 DEBUGOUT(" Error on flow type input\n");
+                 return err;
+         }
+ 
+         /* program input mask into the HW */
+         err = ixgbe_fdir_set_input_mask_82599(hw, input_mask);
+         if (err)
+                 return err;
+ 
+         /* apply mask and compute/store hash */
+         ixgbe_atr_compute_perfect_hash_82599(input, input_mask);
+ 
+         /* program filters to filter memory */
+         return ixgbe_fdir_write_perfect_filter_82599(hw, input,
+                                                      soft_id, queue);
+ }
+ 
+ /**
   *  ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
   *  @hw: pointer to hardware structure
   *  @reg: analog register to read
   *  @val: read value
   *
*** 1838,1859 ****
  
          return IXGBE_SUCCESS;
  }
  
  /**
!  *  ixgbe_start_hw_rev_1_82599 - Prepare hardware for Tx/Rx
   *  @hw: pointer to hardware structure
   *
   *  Starts the hardware using the generic start_hw function
   *  and the generation start_hw function.
   *  Then performs revision-specific operations, if any.
   **/
! s32 ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw)
  {
          s32 ret_val = IXGBE_SUCCESS;
  
!         DEBUGFUNC("ixgbe_start_hw_rev_1__82599");
  
          ret_val = ixgbe_start_hw_generic(hw);
          if (ret_val != IXGBE_SUCCESS)
                  goto out;
  
--- 1862,1883 ----
  
          return IXGBE_SUCCESS;
  }
  
  /**
!  *  ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
   *  @hw: pointer to hardware structure
   *
   *  Starts the hardware using the generic start_hw function
   *  and the generation start_hw function.
   *  Then performs revision-specific operations, if any.
   **/
! s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
  {
          s32 ret_val = IXGBE_SUCCESS;
  
!         DEBUGFUNC("ixgbe_start_hw_82599");
  
          ret_val = ixgbe_start_hw_generic(hw);
          if (ret_val != IXGBE_SUCCESS)
                  goto out;
  
*** 1889,1899 ****
          if (status != IXGBE_SUCCESS) {
                  /* 82599 10GBASE-T requires an external PHY */
                  if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)
                          goto out;
                  else
!                         status = ixgbe_identify_sfp_module_generic(hw);
          }
  
          /* Set PHY type none if no PHY detected */
          if (hw->phy.type == ixgbe_phy_unknown) {
                  hw->phy.type = ixgbe_phy_none;
--- 1913,1923 ----
          if (status != IXGBE_SUCCESS) {
                  /* 82599 10GBASE-T requires an external PHY */
                  if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)
                          goto out;
                  else
!                         status = ixgbe_identify_module_generic(hw);
          }
  
          /* Set PHY type none if no PHY detected */
          if (hw->phy.type == ixgbe_phy_unknown) {
                  hw->phy.type = ixgbe_phy_none;
*** 1930,1940 ****
  
          hw->phy.ops.identify(hw);
  
          switch (hw->phy.type) {
          case ixgbe_phy_tn:
-         case ixgbe_phy_aq:
          case ixgbe_phy_cu_unknown:
                  hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
                  IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
                  if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
                          physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
--- 1954,1963 ----
*** 2014,2023 ****
--- 2037,2048 ----
                          physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
                  else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
                          physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
                  else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
                          physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
+                 else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE)
+                         physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_SX;
                  break;
          default:
                  break;
          }
  
*** 2032,2076 ****
   *
   *  Enables the Rx DMA unit for 82599
   **/
  s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
  {
- #define IXGBE_MAX_SECRX_POLL 30
-         int i;
-         int secrxreg;
  
          DEBUGFUNC("ixgbe_enable_rx_dma_82599");
  
          /*
           * Workaround for 82599 silicon errata when enabling the Rx datapath.
           * If traffic is incoming before we enable the Rx unit, it could hang
           * the Rx DMA unit.  Therefore, make sure the security engine is
           * completely disabled prior to enabling the Rx unit.
           */
-         secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
-         secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
-         IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
-         for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
-                 secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
-                 if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
-                         break;
-                 else
-                         /* Use interrupt-safe sleep just in case */
-                         usec_delay(10);
-         }
  
!         /* For informational purposes only */
!         if (i >= IXGBE_MAX_SECRX_POLL)
!                 DEBUGOUT("Rx unit being enabled before security "
!                          "path fully disabled.  Continuing with init.\n");
  
          IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
-         secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
-         secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
-         IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
-         IXGBE_WRITE_FLUSH(hw);
  
          return IXGBE_SUCCESS;
  }
  
  /**
   *  ixgbe_verify_fw_version_82599 - verify fw version for 82599
--- 2057,2082 ----
   *
   *  Enables the Rx DMA unit for 82599
   **/
  s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
  {
  
          DEBUGFUNC("ixgbe_enable_rx_dma_82599");
  
          /*
           * Workaround for 82599 silicon errata when enabling the Rx datapath.
           * If traffic is incoming before we enable the Rx unit, it could hang
           * the Rx DMA unit.  Therefore, make sure the security engine is
           * completely disabled prior to enabling the Rx unit.
           */
  
!         hw->mac.ops.disable_sec_rx_path(hw);
  
          IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
  
+         hw->mac.ops.enable_sec_rx_path(hw);
+ 
          return IXGBE_SUCCESS;
  }
  
  /**
   *  ixgbe_verify_fw_version_82599 - verify fw version for 82599
*** 2110,2121 ****
          if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF))
                  goto fw_version_out;
  
          /* get the firmware version */
          hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset +
!                                  IXGBE_FW_PATCH_VERSION_4),
!                                  &fw_version);
  
          if (fw_version > 0x5)
                  status = IXGBE_SUCCESS;
  
  fw_version_out:
--- 2116,2126 ----
          if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF))
                  goto fw_version_out;
  
          /* get the firmware version */
          hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset +
!                             IXGBE_FW_PATCH_VERSION_4), &fw_version);
  
          if (fw_version > 0x5)
                  status = IXGBE_SUCCESS;
  
  fw_version_out:
*** 2164,2169 ****
--- 2169,2240 ----
  
  out:
          return lesm_enabled;
  }
  
+ /**
+  *  ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using
+  *  fastest available method
+  *
+  *  @hw: pointer to hardware structure
+  *  @offset: offset of  word in EEPROM to read
+  *  @words: number of words
+  *  @data: word(s) read from the EEPROM
+  *
+  *  Retrieves 16 bit word(s) read from EEPROM
+  **/
+ static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
+                                           u16 words, u16 *data)
+ {
+         struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+         s32 ret_val = IXGBE_ERR_CONFIG;
+ 
+         DEBUGFUNC("ixgbe_read_eeprom_buffer_82599");
+ 
+         /*
+          * If EEPROM is detected and can be addressed using 14 bits,
+          * use EERD otherwise use bit bang
+          */
+         if ((eeprom->type == ixgbe_eeprom_spi) &&
+             (offset + (words - 1) <= IXGBE_EERD_MAX_ADDR))
+                 ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words,
+                                                          data);
+         else
+                 ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset,
+                                                                     words,
+                                                                     data);
+ 
+         return ret_val;
+ }
+ 
+ /**
+  *  ixgbe_read_eeprom_82599 - Read EEPROM word using
+  *  fastest available method
+  *
+  *  @hw: pointer to hardware structure
+  *  @offset: offset of  word in the EEPROM to read
+  *  @data: word read from the EEPROM
+  *
+  *  Reads a 16 bit word from the EEPROM
+  **/
+ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
+                                    u16 offset, u16 *data)
+ {
+         struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+         s32 ret_val = IXGBE_ERR_CONFIG;
+ 
+         DEBUGFUNC("ixgbe_read_eeprom_82599");
+ 
+         /*
+          * If EEPROM is detected and can be addressed using 14 bits,
+          * use EERD otherwise use bit bang
+          */
+         if ((eeprom->type == ixgbe_eeprom_spi) &&
+             (offset <= IXGBE_EERD_MAX_ADDR))
+                 ret_val = ixgbe_read_eerd_generic(hw, offset, data);
+         else
+                 ret_val = ixgbe_read_eeprom_bit_bang_generic(hw, offset, data);
+ 
+         return ret_val;
+ }
+