net/sfc: use compat for 128-bit unsigned integer
[dpdk.git] / drivers / net / ixgbe / ixgbe_fdir.c
index c773701..a0fab50 100644 (file)
@@ -1,34 +1,5 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN 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.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2015 Intel Corporation
  */
 
 #include <stdio.h>
@@ -41,8 +12,8 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
+#include <rte_vxlan.h>
+#include <rte_ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ixgbe_logs.h"
 #define IXGBE_FDIRCMD_CMD_INTERVAL_US   10
 
 #define IXGBE_FDIR_FLOW_TYPES ( \
-       (1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
-       (1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
-       (1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
-       (1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
-       (1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
-       (1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
-       (1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
-       (1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER))
+       (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
+       (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
+       (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
+       (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
+       (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
+       (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
+       (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
+       (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER))
 
 #define IPV6_ADDR_TO_MASK(ipaddr, ipv6m) do { \
        uint8_t ipv6_addr[16]; \
        rte_memcpy((ipaddr), ipv6_addr, sizeof(ipv6_addr));\
 } while (0)
 
-#define DEFAULT_VXLAN_PORT 4789
 #define IXGBE_FDIRIP6M_INNER_MAC_SHIFT 4
 
 static int fdir_erase_filter_82599(struct ixgbe_hw *hw, uint32_t fdirhash);
@@ -117,10 +87,6 @@ static int fdir_set_input_mask_x550(struct rte_eth_dev *dev);
 static int ixgbe_set_fdir_flex_conf(struct rte_eth_dev *dev,
                const struct rte_eth_fdir_flex_conf *conf, uint32_t *fdirctrl);
 static int fdir_enable_82599(struct ixgbe_hw *hw, uint32_t fdirctrl);
-static int ixgbe_fdir_filter_to_atr_input(
-               const struct rte_eth_fdir_filter *fdir_filter,
-               union ixgbe_atr_input *input,
-               enum rte_fdir_mode mode);
 static uint32_t ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *atr_input,
                                 uint32_t key);
 static uint32_t atr_compute_sig_hash_82599(union ixgbe_atr_input *input,
@@ -134,15 +100,7 @@ static int fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
 static int fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
                union ixgbe_atr_input *input, u8 queue, uint32_t fdircmd,
                uint32_t fdirhash);
-static int ixgbe_add_del_fdir_filter(struct rte_eth_dev *dev,
-                             const struct rte_eth_fdir_filter *fdir_filter,
-                             bool del,
-                             bool update);
 static int ixgbe_fdir_flush(struct rte_eth_dev *dev);
-static void ixgbe_fdir_info_get(struct rte_eth_dev *dev,
-                       struct rte_eth_fdir_info *fdir_info);
-static void ixgbe_fdir_stats_get(struct rte_eth_dev *dev,
-                       struct rte_eth_fdir_stats *fdir_stats);
 
 /**
  * This function is based on ixgbe_fdir_enable_82599() in base/ixgbe_82599.c.
@@ -395,7 +353,7 @@ fdir_set_input_mask_x550(struct rte_eth_dev *dev)
 
        /* set the default UDP port for VxLAN */
        if (mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
-               IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, DEFAULT_VXLAN_PORT);
+               IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, RTE_VXLAN_DEFAULT_PORT);
 
        /* some bits must be set for mac vlan or tunnel mode */
        fdirm |= IXGBE_FDIRM_L4P | IXGBE_FDIRM_L3P;
@@ -423,9 +381,12 @@ fdir_set_input_mask_x550(struct rte_eth_dev *dev)
                                IXGBE_FDIRIP6M_TNI_VNI;
 
        if (mode == RTE_FDIR_MODE_PERFECT_TUNNEL) {
-               mac_mask = info->mask.mac_addr_byte_mask;
-               fdiripv6m |= (mac_mask << IXGBE_FDIRIP6M_INNER_MAC_SHIFT)
-                               & IXGBE_FDIRIP6M_INNER_MAC;
+               fdiripv6m |= IXGBE_FDIRIP6M_INNER_MAC;
+               mac_mask = info->mask.mac_addr_byte_mask &
+                       (IXGBE_FDIRIP6M_INNER_MAC >>
+                       IXGBE_FDIRIP6M_INNER_MAC_SHIFT);
+               fdiripv6m &= ~((mac_mask << IXGBE_FDIRIP6M_INNER_MAC_SHIFT) &
+                               IXGBE_FDIRIP6M_INNER_MAC);
 
                switch (info->mask.tunnel_type_mask) {
                case 0:
@@ -710,105 +671,6 @@ ixgbe_fdir_configure(struct rte_eth_dev *dev)
        return 0;
 }
 
-/*
- * Convert DPDK rte_eth_fdir_filter struct to ixgbe_atr_input union that is used
- * by the IXGBE driver code.
- */
-static int
-ixgbe_fdir_filter_to_atr_input(const struct rte_eth_fdir_filter *fdir_filter,
-               union ixgbe_atr_input *input, enum rte_fdir_mode mode)
-{
-       input->formatted.vlan_id = fdir_filter->input.flow_ext.vlan_tci;
-       input->formatted.flex_bytes = (uint16_t)(
-               (fdir_filter->input.flow_ext.flexbytes[1] << 8 & 0xFF00) |
-               (fdir_filter->input.flow_ext.flexbytes[0] & 0xFF));
-
-       switch (fdir_filter->input.flow_type) {
-       case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
-               input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4;
-               break;
-       case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
-               input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4;
-               break;
-       case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
-               input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4;
-               break;
-       case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
-               input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_IPV4;
-               break;
-       case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
-               input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_UDPV6;
-               break;
-       case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
-               input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV6;
-               break;
-       case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
-               input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV6;
-               break;
-       case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
-               input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_IPV6;
-               break;
-       default:
-               break;
-       }
-
-       switch (fdir_filter->input.flow_type) {
-       case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
-       case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
-               input->formatted.src_port =
-                       fdir_filter->input.flow.udp4_flow.src_port;
-               input->formatted.dst_port =
-                       fdir_filter->input.flow.udp4_flow.dst_port;
-               /* fall-through */
-       /*for SCTP flow type, port and verify_tag are meaningless in ixgbe.*/
-       case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
-       case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
-               input->formatted.src_ip[0] =
-                       fdir_filter->input.flow.ip4_flow.src_ip;
-               input->formatted.dst_ip[0] =
-                       fdir_filter->input.flow.ip4_flow.dst_ip;
-               break;
-
-       case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
-       case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
-               input->formatted.src_port =
-                       fdir_filter->input.flow.udp6_flow.src_port;
-               input->formatted.dst_port =
-                       fdir_filter->input.flow.udp6_flow.dst_port;
-               /* fall-through */
-       /*for SCTP flow type, port and verify_tag are meaningless in ixgbe.*/
-       case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
-       case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
-               rte_memcpy(input->formatted.src_ip,
-                          fdir_filter->input.flow.ipv6_flow.src_ip,
-                          sizeof(input->formatted.src_ip));
-               rte_memcpy(input->formatted.dst_ip,
-                          fdir_filter->input.flow.ipv6_flow.dst_ip,
-                          sizeof(input->formatted.dst_ip));
-               break;
-       default:
-               break;
-       }
-
-       if (mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
-               rte_memcpy(
-                       input->formatted.inner_mac,
-                       fdir_filter->input.flow.mac_vlan_flow.mac_addr.addr_bytes,
-                       sizeof(input->formatted.inner_mac));
-       } else if (mode == RTE_FDIR_MODE_PERFECT_TUNNEL) {
-               rte_memcpy(
-                       input->formatted.inner_mac,
-                       fdir_filter->input.flow.tunnel_flow.mac_addr.addr_bytes,
-                       sizeof(input->formatted.inner_mac));
-               input->formatted.tunnel_type =
-                       fdir_filter->input.flow.tunnel_flow.tunnel_type;
-               input->formatted.tni_vni =
-                       fdir_filter->input.flow.tunnel_flow.tunnel_id;
-       }
-
-       return 0;
-}
-
 /*
  * The below function is taken from the FreeBSD IXGBE drivers release
  * 2.3.8. The only change is not to mask hash_result with IXGBE_ATR_HASH_MASK
@@ -1030,8 +892,7 @@ fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), 0);
                } else {
                        /* tunnel mode */
-                       if (input->formatted.tunnel_type !=
-                               RTE_FDIR_TUNNEL_TYPE_NVGRE)
+                       if (input->formatted.tunnel_type)
                                tunnel_type = 0x80000000;
                        tunnel_type |= addr_high;
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), addr_low);
@@ -1039,6 +900,9 @@ fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2),
                                        input->formatted.tni_vni);
                }
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, 0);
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRIPDA, 0);
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, 0);
        }
 
        /* record vlan (little-endian) and flex_bytes(big-endian) */
@@ -1214,31 +1078,6 @@ ixgbe_remove_fdir_filter(struct ixgbe_hw_fdir_info *fdir_info,
        return 0;
 }
 
-static int
-ixgbe_interpret_fdir_filter(struct rte_eth_dev *dev,
-                           const struct rte_eth_fdir_filter *fdir_filter,
-                           struct ixgbe_fdir_rule *rule)
-{
-       enum rte_fdir_mode fdir_mode = dev->data->dev_conf.fdir_conf.mode;
-       int err;
-
-       memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
-
-       err = ixgbe_fdir_filter_to_atr_input(fdir_filter,
-                                            &rule->ixgbe_fdir,
-                                            fdir_mode);
-       if (err)
-               return err;
-
-       rule->mode = fdir_mode;
-       if (fdir_filter->action.behavior == RTE_ETH_FDIR_REJECT)
-               rule->fdirflags = IXGBE_FDIRCMD_DROP;
-       rule->queue = fdir_filter->action.rx_queue;
-       rule->soft_id = fdir_filter->soft_id;
-
-       return 0;
-}
-
 int
 ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
                          struct ixgbe_fdir_rule *rule,
@@ -1272,9 +1111,13 @@ ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
             hw->mac.type == ixgbe_mac_X550EM_x ||
             hw->mac.type == ixgbe_mac_X550EM_a) &&
            (rule->ixgbe_fdir.formatted.flow_type ==
-            IXGBE_ATR_FLOW_TYPE_IPV4) &&
+            IXGBE_ATR_FLOW_TYPE_IPV4 ||
+            rule->ixgbe_fdir.formatted.flow_type ==
+            IXGBE_ATR_FLOW_TYPE_IPV6) &&
            (info->mask.src_port_mask != 0 ||
-            info->mask.dst_port_mask != 0)) {
+            info->mask.dst_port_mask != 0) &&
+           (rule->mode != RTE_FDIR_MODE_PERFECT_MAC_VLAN &&
+            rule->mode != RTE_FDIR_MODE_PERFECT_TUNNEL)) {
                PMD_DRV_LOG(ERR, "By this device,"
                            " IPv4 is not supported without"
                            " L4 protocol and ports masked!");
@@ -1345,7 +1188,7 @@ ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
                                   0);
                if (!node)
                        return -ENOMEM;
-               (void)rte_memcpy(&node->ixgbe_fdir,
+               rte_memcpy(&node->ixgbe_fdir,
                                 &rule->ixgbe_fdir,
                                 sizeof(union ixgbe_atr_input));
                node->fdirflags = fdircmd_flags;
@@ -1380,29 +1223,6 @@ ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
        return err;
 }
 
-/* ixgbe_add_del_fdir_filter - add or remove a flow diretor filter.
- * @dev: pointer to the structure rte_eth_dev
- * @fdir_filter: fdir filter entry
- * @del: 1 - delete, 0 - add
- * @update: 1 - update
- */
-static int
-ixgbe_add_del_fdir_filter(struct rte_eth_dev *dev,
-                         const struct rte_eth_fdir_filter *fdir_filter,
-                         bool del,
-                         bool update)
-{
-       struct ixgbe_fdir_rule rule;
-       int err;
-
-       err = ixgbe_interpret_fdir_filter(dev, fdir_filter, &rule);
-
-       if (err)
-               return err;
-
-       return ixgbe_fdir_filter_program(dev, &rule, del, update);
-}
-
 static int
 ixgbe_fdir_flush(struct rte_eth_dev *dev)
 {
@@ -1426,13 +1246,13 @@ ixgbe_fdir_flush(struct rte_eth_dev *dev)
 }
 
 #define FDIRENTRIES_NUM_SHIFT 10
-static void
+void
 ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct ixgbe_hw_fdir_info *info =
                        IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
-       uint32_t fdirctrl, max_num;
+       uint32_t fdirctrl, max_num, i;
        uint8_t offset;
 
        fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
@@ -1464,9 +1284,11 @@ ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info
 
        if (fdir_info->mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN ||
            fdir_info->mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
-               fdir_info->flow_types_mask[0] = 0;
+               fdir_info->flow_types_mask[0] = 0ULL;
        else
                fdir_info->flow_types_mask[0] = IXGBE_FDIR_FLOW_TYPES;
+       for (i = 1; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+               fdir_info->flow_types_mask[i] = 0ULL;
 
        fdir_info->flex_payload_unit = sizeof(uint16_t);
        fdir_info->max_flex_payload_segment_num = 1;
@@ -1483,7 +1305,7 @@ ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info
                        (uint8_t)((info->mask.flex_bytes_mask & 0xFF00) >> 8);
 }
 
-static void
+void
 ixgbe_fdir_stats_get(struct rte_eth_dev *dev, struct rte_eth_fdir_stats *fdir_stats)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -1538,62 +1360,6 @@ ixgbe_fdir_stats_get(struct rte_eth_dev *dev, struct rte_eth_fdir_stats *fdir_st
 
 }
 
-/*
- * ixgbe_fdir_ctrl_func - deal with all operations on flow director.
- * @dev: pointer to the structure rte_eth_dev
- * @filter_op:operation will be taken
- * @arg: a pointer to specific structure corresponding to the filter_op
- */
-int
-ixgbe_fdir_ctrl_func(struct rte_eth_dev *dev,
-                       enum rte_filter_op filter_op, void *arg)
-{
-       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       int ret = 0;
-
-       if (hw->mac.type != ixgbe_mac_82599EB &&
-               hw->mac.type != ixgbe_mac_X540 &&
-               hw->mac.type != ixgbe_mac_X550 &&
-               hw->mac.type != ixgbe_mac_X550EM_x &&
-               hw->mac.type != ixgbe_mac_X550EM_a)
-               return -ENOTSUP;
-
-       if (filter_op == RTE_ETH_FILTER_NOP)
-               return 0;
-
-       if (arg == NULL && filter_op != RTE_ETH_FILTER_FLUSH)
-               return -EINVAL;
-
-       switch (filter_op) {
-       case RTE_ETH_FILTER_ADD:
-               ret = ixgbe_add_del_fdir_filter(dev,
-                       (struct rte_eth_fdir_filter *)arg, FALSE, FALSE);
-               break;
-       case RTE_ETH_FILTER_UPDATE:
-               ret = ixgbe_add_del_fdir_filter(dev,
-                       (struct rte_eth_fdir_filter *)arg, FALSE, TRUE);
-               break;
-       case RTE_ETH_FILTER_DELETE:
-               ret = ixgbe_add_del_fdir_filter(dev,
-                       (struct rte_eth_fdir_filter *)arg, TRUE, FALSE);
-               break;
-       case RTE_ETH_FILTER_FLUSH:
-               ret = ixgbe_fdir_flush(dev);
-               break;
-       case RTE_ETH_FILTER_INFO:
-               ixgbe_fdir_info_get(dev, (struct rte_eth_fdir_info *)arg);
-               break;
-       case RTE_ETH_FILTER_STATS:
-               ixgbe_fdir_stats_get(dev, (struct rte_eth_fdir_stats *)arg);
-               break;
-       default:
-               PMD_DRV_LOG(ERR, "unknown operation %u", filter_op);
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
 /* restore flow director filter */
 void
 ixgbe_fdir_filter_restore(struct rte_eth_dev *dev)