ixgbe: Add support for VXLAN RX offloads
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / intel / ixgbe / ixgbe_82599.c
index 6b87d963461462cc92885aa057b19adbb18125c0..dd7062fed61adfff717d56db55d6b275059b7c07 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2014 Intel Corporation.
+  Copyright(c) 1999 - 2015 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,
@@ -504,16 +504,12 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
  **/
 static void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw)
 {
-       u32 autoc2_reg, fwsm;
+       u32 autoc2_reg;
        u16 ee_ctrl_2 = 0;
 
        hw->eeprom.ops.read(hw, IXGBE_EEPROM_CTRL_2, &ee_ctrl_2);
 
-       /* Check to see if MNG FW could be enabled */
-       fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM(hw));
-
-       if (((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT) &&
-           !hw->wol_enabled &&
+       if (!ixgbe_mng_present(hw) && !hw->wol_enabled &&
            ee_ctrl_2 & IXGBE_EEPROM_CCD_BIT) {
                autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
                autoc2_reg |= IXGBE_AUTOC2_LINK_DISABLE_ON_D3_MASK;
@@ -1245,6 +1241,25 @@ mac_reset_top:
        return status;
 }
 
+/**
+ * ixgbe_fdir_check_cmd_complete - poll to check whether FDIRCMD is complete
+ * @hw: pointer to hardware structure
+ * @fdircmd: current value of FDIRCMD register
+ */
+static s32 ixgbe_fdir_check_cmd_complete(struct ixgbe_hw *hw, u32 *fdircmd)
+{
+       int i;
+
+       for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
+               *fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
+               if (!(*fdircmd & IXGBE_FDIRCMD_CMD_MASK))
+                       return 0;
+               udelay(10);
+       }
+
+       return IXGBE_ERR_FDIR_CMD_INCOMPLETE;
+}
+
 /**
  *  ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
  *  @hw: pointer to hardware structure
@@ -1253,6 +1268,8 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
 {
        int i;
        u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
+       u32 fdircmd;
+       s32 err;
 
        fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
 
@@ -1260,15 +1277,10 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
         * Before starting reinitialization process,
         * FDIRCMD.CMD must be zero.
         */
-       for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
-               if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
-                     IXGBE_FDIRCMD_CMD_MASK))
-                       break;
-               udelay(10);
-       }
-       if (i >= IXGBE_FDIRCMD_CMD_POLL) {
-               hw_dbg(hw, "Flow Director previous command isn't complete, aborting table re-initialization.\n");
-               return IXGBE_ERR_FDIR_REINIT_FAILED;
+       err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
+       if (err) {
+               hw_dbg(hw, "Flow Director previous command did not complete, aborting table re-initialization.\n");
+               return err;
        }
 
        IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
@@ -1394,14 +1406,12 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl)
        /*
         * 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) |
@@ -1509,20 +1519,28 @@ static u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
  *  @input: unique input dword
  *  @common: compressed common input dword
  *  @queue: queue index to direct traffic to
+ *
+ * Note that the tunnel bit in input must not be set when the hardware
+ * tunneling support does not exist.
  **/
 s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
                                          union ixgbe_atr_hash_dword input,
                                          union ixgbe_atr_hash_dword common,
                                          u8 queue)
 {
-       u64  fdirhashcmd;
-       u32  fdircmd;
+       u64 fdirhashcmd;
+       u8 flow_type;
+       bool tunnel;
+       u32 fdircmd;
 
        /*
         * Get the flow_type in order to program FDIRCMD properly
         * lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6
         */
-       switch (input.formatted.flow_type) {
+       tunnel = !!(input.formatted.flow_type & IXGBE_ATR_L4TYPE_TUNNEL_MASK);
+       flow_type = input.formatted.flow_type &
+                   (IXGBE_ATR_L4TYPE_TUNNEL_MASK - 1);
+       switch (flow_type) {
        case IXGBE_ATR_FLOW_TYPE_TCPV4:
        case IXGBE_ATR_FLOW_TYPE_UDPV4:
        case IXGBE_ATR_FLOW_TYPE_SCTPV4:
@@ -1538,8 +1556,10 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
        /* 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)flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
        fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
+       if (tunnel)
+               fdircmd |= IXGBE_FDIRCMD_TUNNEL_FILTER;
 
        /*
         * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
@@ -1760,6 +1780,7 @@ s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
                                          u16 soft_id, u8 queue)
 {
        u32 fdirport, fdirvlan, fdirhash, fdircmd;
+       s32 err;
 
        /* currently IPv6 is not supported, must be programmed with 0 */
        IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0),
@@ -1808,6 +1829,11 @@ s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
        fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT;
 
        IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
+       err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
+       if (err) {
+               hw_dbg(hw, "Flow Director command did not complete!\n");
+               return err;
+       }
 
        return 0;
 }
@@ -1817,9 +1843,8 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
                                          u16 soft_id)
 {
        u32 fdirhash;
-       u32 fdircmd = 0;
-       u32 retry_count;
-       s32 err = 0;
+       u32 fdircmd;
+       s32 err;
 
        /* configure FDIRHASH register */
        fdirhash = input->formatted.bkt_hash;
@@ -1832,18 +1857,12 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *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 */
-               udelay(10);
-               /* verify query completed successfully */
-               fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
-               if (!(fdircmd & IXGBE_FDIRCMD_CMD_MASK))
-                       break;
+       err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
+       if (err) {
+               hw_dbg(hw, "Flow Director command did not complete!\n");
+               return err;
        }
 
-       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);
@@ -1852,7 +1871,7 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
                                IXGBE_FDIRCMD_CMD_REMOVE_FLOW);
        }
 
-       return err;
+       return 0;
 }
 
 /**