net/dpaa2: support Rx packet parsing
authorHemant Agrawal <hemant.agrawal@nxp.com>
Tue, 11 Apr 2017 13:49:30 +0000 (19:19 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 19 Apr 2017 13:37:37 +0000 (15:37 +0200)
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
doc/guides/nics/features/dpaa2.ini
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h [new file with mode: 0644]
drivers/net/dpaa2/dpaa2_ethdev.c
drivers/net/dpaa2/dpaa2_rxtx.c

index a6b7964..0746d4b 100644 (file)
@@ -10,6 +10,7 @@ Promiscuous mode     = Y
 RSS hash             = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
+Packet type parsing  = Y
 Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h b/drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
new file mode 100644 (file)
index 0000000..9324c6a
--- /dev/null
@@ -0,0 +1,257 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+ *   Copyright (c) 2016 NXP. 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 Freescale Semiconductor, Inc 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.
+ */
+
+/**
+ * @file
+ *
+ * DPNI packet parse results - implementation internal
+ */
+
+#ifndef _DPAA2_HW_DPNI_ANNOT_H_
+#define _DPAA2_HW_DPNI_ANNOT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Annotation valid bits in FD FRC */
+#define DPAA2_FD_FRC_FASV      0x8000
+#define DPAA2_FD_FRC_FAEADV    0x4000
+#define DPAA2_FD_FRC_FAPRV     0x2000
+#define DPAA2_FD_FRC_FAIADV    0x1000
+#define DPAA2_FD_FRC_FASWOV    0x0800
+#define DPAA2_FD_FRC_FAICFDV   0x0400
+
+/* Annotation bits in FD CTRL */
+#define DPAA2_FD_CTRL_ASAL     0x00020000      /* ASAL = 128 */
+#define DPAA2_FD_CTRL_PTA      0x00800000
+#define DPAA2_FD_CTRL_PTV1     0x00400000
+
+/* Frame annotation status */
+struct dpaa2_fas {
+       uint8_t reserved;
+       uint8_t ppid;
+       __le16 ifpid;
+       __le32 status;
+} __packed;
+
+/**
+ * HW Packet Annotation  Register structures
+ */
+struct dpaa2_annot_hdr {
+       /**<    word1: Frame Annotation Status (8 bytes)*/
+       uint64_t word1;
+
+       /**<    word2: Time Stamp (8 bytes)*/
+       uint64_t word2;
+
+       /**<    word3: Next Hdr + FAF Extension + FAF (2 + 2 + 4 bytes)*/
+       uint64_t word3;
+
+       /**<    word4: Frame Annotation Flags-FAF (8 bytes) */
+       uint64_t word4;
+
+       /**<    word5:
+        *      ShimOffset_1 + ShimOffset_2 + IPPIDOffset + EthOffset +
+        *      LLC+SNAPOffset + VLANTCIOffset_1 + VLANTCIOffset_n +
+        *      LastETypeOffset (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 bytes)
+        */
+       uint64_t word5;
+
+       /**<    word6:
+        *      PPPoEOffset + MPLSOffset_1 + MPLSOffset_n + ARPorIPOffset_1
+        *      + IPOffset_norMInEncapO + GREOffset + L4Offset +
+        *      GTPorESPorIPSecOffset(1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 bytes)
+        */
+       uint64_t word6;
+
+       /**<    word7:
+        *      RoutingHdrOfset1 + RoutingHdrOfset2 + NxtHdrOffset
+        *      + IPv6FragOffset + GrossRunningSum
+        *      + RunningSum(1 + 1 + 1 + 1 + 2 + 2 bytes)
+        */
+       uint64_t word7;
+
+       /**<    word8:
+        *      ParseErrorcode + Soft Parsing Context (1 + 7 bytes)
+        */
+       uint64_t word8;
+};
+
+/**
+ * Internal Macros to get/set Packet annotation header
+ */
+
+/** General Macro to define a particular bit position*/
+#define BIT_POS(x)                     ((uint64_t)1 << ((x)))
+/** Set a bit in the variable */
+#define BIT_SET_AT_POS(var, pos)       ((var) |= (pos))
+/** Reset the bit in the variable */
+#define BIT_RESET_AT_POS(var, pos)     ((var) &= ~(pos))
+/** Check the bit is set in the variable */
+#define BIT_ISSET_AT_POS(var, pos)     (((var) & (pos)) ? 1 : 0)
+/**
+ * Macrso to define bit position in word3
+ */
+#define NEXT_HDR(var)                  ((uint64_t)(var) & 0xFFFF000000000000)
+#define FAF_EXTN_IPV6_ROUTE_HDR_PRESENT(var)   BIT_POS(16)
+#define FAF_EXTN_RESERVED(var)         ((uint64_t)(var) & 0x00007FFF00000000)
+#define FAF_USER_DEFINED_RESERVED(var) ((uint64_t)(var) & 0x00000000FF000000)
+#define SHIM_SHELL_SOFT_PARSING_ERRROR         BIT_POS(23)
+#define PARSING_ERROR                          BIT_POS(22)
+#define L2_ETH_MAC_PRESENT                     BIT_POS(21)
+#define L2_ETH_MAC_UNICAST                     BIT_POS(20)
+#define L2_ETH_MAC_MULTICAST                   BIT_POS(19)
+#define L2_ETH_MAC_BROADCAST                   BIT_POS(18)
+#define L2_ETH_FRAME_IS_BPDU                   BIT_POS(17)
+#define L2_ETH_FCOE_PRESENT                    BIT_POS(16)
+#define L2_ETH_FIP_PRESENT                     BIT_POS(15)
+#define L2_ETH_PARSING_ERROR                   BIT_POS(14)
+#define L2_LLC_SNAP_PRESENT                    BIT_POS(13)
+#define L2_UNKNOWN_LLC_OUI                     BIT_POS(12)
+#define L2_LLC_SNAP_ERROR                      BIT_POS(11)
+#define L2_VLAN_1_PRESENT                      BIT_POS(10)
+#define L2_VLAN_N_PRESENT                      BIT_POS(9)
+#define L2_VLAN_CFI_BIT_PRESENT                        BIT_POS(8)
+#define L2_VLAN_PARSING_ERROR                  BIT_POS(7)
+#define L2_PPPOE_PPP_PRESENT                   BIT_POS(6)
+#define L2_PPPOE_PPP_PARSING_ERROR             BIT_POS(5)
+#define L2_MPLS_1_PRESENT                      BIT_POS(4)
+#define L2_MPLS_N_PRESENT                      BIT_POS(3)
+#define L2_MPLS_PARSING_ERROR                  BIT_POS(2)
+#define L2_ARP_PRESENT                         BIT_POS(1)
+#define L2_ARP_PARSING_ERROR                   BIT_POS(0)
+/**
+ * Macrso to define bit position in word4
+ */
+#define L2_UNKNOWN_PROTOCOL                    BIT_POS(63)
+#define L2_SOFT_PARSING_ERROR                  BIT_POS(62)
+#define L3_IPV4_1_PRESENT                      BIT_POS(61)
+#define L3_IPV4_1_UNICAST                      BIT_POS(60)
+#define L3_IPV4_1_MULTICAST                    BIT_POS(59)
+#define L3_IPV4_1_BROADCAST                    BIT_POS(58)
+#define L3_IPV4_N_PRESENT                      BIT_POS(57)
+#define L3_IPV4_N_UNICAST                      BIT_POS(56)
+#define L3_IPV4_N_MULTICAST                    BIT_POS(55)
+#define L3_IPV4_N_BROADCAST                    BIT_POS(54)
+#define L3_IPV6_1_PRESENT                      BIT_POS(53)
+#define L3_IPV6_1_UNICAST                      BIT_POS(52)
+#define L3_IPV6_1_MULTICAST                    BIT_POS(51)
+#define L3_IPV6_N_PRESENT                      BIT_POS(50)
+#define L3_IPV6_N_UNICAST                      BIT_POS(49)
+#define L3_IPV6_N_MULTICAST                    BIT_POS(48)
+#define L3_IP_1_OPT_PRESENT                    BIT_POS(47)
+#define L3_IP_1_UNKNOWN_PROTOCOL               BIT_POS(46)
+#define L3_IP_1_MORE_FRAGMENT                  BIT_POS(45)
+#define L3_IP_1_FIRST_FRAGMENT                 BIT_POS(44)
+#define L3_IP_1_PARSING_ERROR                  BIT_POS(43)
+#define L3_IP_N_OPT_PRESENT                    BIT_POS(42)
+#define L3_IP_N_UNKNOWN_PROTOCOL               BIT_POS(41)
+#define L3_IP_N_MORE_FRAGMENT                  BIT_POS(40)
+#define L3_IP_N_FIRST_FRAGMENT                 BIT_POS(39)
+#define L3_PROTO_ICMP_PRESENT                  BIT_POS(38)
+#define L3_PROTO_IGMP_PRESENT                  BIT_POS(37)
+#define L3_PROTO_ICMPV6_PRESENT                        BIT_POS(36)
+#define L3_PROTO_UDP_LIGHT_PRESENT             BIT_POS(35)
+#define L3_IP_N_PARSING_ERROR                  BIT_POS(34)
+#define L3_MIN_ENCAP_PRESENT                   BIT_POS(33)
+#define L3_MIN_ENCAP_SBIT_PRESENT              BIT_POS(32)
+#define L3_MIN_ENCAP_PARSING_ERROR             BIT_POS(31)
+#define L3_PROTO_GRE_PRESENT                   BIT_POS(30)
+#define L3_PROTO_GRE_RBIT_PRESENT              BIT_POS(29)
+#define L3_PROTO_GRE_PARSING_ERROR             BIT_POS(28)
+#define L3_IP_UNKNOWN_PROTOCOL                 BIT_POS(27)
+#define L3_SOFT_PARSING_ERROR                  BIT_POS(26)
+#define L3_PROTO_UDP_PRESENT                   BIT_POS(25)
+#define L3_PROTO_UDP_PARSING_ERROR             BIT_POS(24)
+#define L3_PROTO_TCP_PRESENT                   BIT_POS(23)
+#define L3_PROTO_TCP_OPT_PRESENT               BIT_POS(22)
+#define L3_PROTO_TCP_CTRL_BIT_6_TO_11_PRESENT  BIT_POS(21)
+#define L3_PROTO_TCP_CTRL_BIT_3_TO_5_PRESENT   BIT_POS(20)
+#define L3_PROTO_TCP_PARSING_ERROR             BIT_POS(19)
+#define L3_PROTO_IPSEC_PRESENT                 BIT_POS(18)
+#define L3_PROTO_IPSEC_ESP_PRESENT             BIT_POS(17)
+#define L3_PROTO_IPSEC_AH_PRESENT              BIT_POS(16)
+#define L3_PROTO_IPSEC_PARSING_ERROR           BIT_POS(15)
+#define L3_PROTO_SCTP_PRESENT                  BIT_POS(14)
+#define L3_PROTO_SCTP_PARSING_ERROR            BIT_POS(13)
+#define L3_PROTO_DCCP_PRESENT                  BIT_POS(12)
+#define L3_PROTO_DCCP_PARSING_ERROR            BIT_POS(11)
+#define L4_UNKNOWN_PROTOCOL                    BIT_POS(10)
+#define L4_SOFT_PARSING_ERROR                  BIT_POS(9)
+#define L3_PROTO_GTP_PRESENT                   BIT_POS(8)
+#define L3_PROTO_GTP_PARSING_ERROR             BIT_POS(7)
+#define L3_PROTO_ESP_PRESENT                   BIT_POS(6)
+#define L3_PROTO_ESP_PARSING_ERROR             BIT_POS(5)
+#define L3_PROTO_ISCSI_PRESENT                 BIT_POS(4)
+#define L3_PROTO_CAPWAN__CTRL_PRESENT          BIT_POS(3)
+#define L3_PROTO_CAPWAN__DATA_PRESENT          BIT_POS(2)
+#define L5_SOFT_PARSING_ERROR                  BIT_POS(1)
+#define L3_IPV6_ROUTE_HDR_PRESENT              BIT_POS(0)
+
+/* Debug frame, otherwise supposed to be discarded */
+#define DPAA2_ETH_FAS_DISC           0x80000000
+/* MACSEC frame */
+#define DPAA2_ETH_FAS_MS               0x40000000
+#define DPAA2_ETH_FAS_PTP             0x08000000
+/* Ethernet multicast frame */
+#define DPAA2_ETH_FAS_MC               0x04000000
+/* Ethernet broadcast frame */
+#define DPAA2_ETH_FAS_BC               0x02000000
+#define DPAA2_ETH_FAS_KSE             0x00040000
+#define DPAA2_ETH_FAS_EOFHE         0x00020000
+#define DPAA2_ETH_FAS_MNLE           0x00010000
+#define DPAA2_ETH_FAS_TIDE           0x00008000
+#define DPAA2_ETH_FAS_PIEE           0x00004000
+/* Frame length error */
+#define DPAA2_ETH_FAS_FLE             0x00002000
+/* Frame physical error; our favourite pastime */
+#define DPAA2_ETH_FAS_FPE             0x00001000
+#define DPAA2_ETH_FAS_PTE             0x00000080
+#define DPAA2_ETH_FAS_ISP             0x00000040
+#define DPAA2_ETH_FAS_PHE             0x00000020
+#define DPAA2_ETH_FAS_BLE             0x00000010
+/* L3 csum validation performed */
+#define DPAA2_ETH_FAS_L3CV           0x00000008
+/* L3 csum error */
+#define DPAA2_ETH_FAS_L3CE           0x00000004
+/* L4 csum validation performed */
+#define DPAA2_ETH_FAS_L4CV           0x00000002
+/* L4 csum error */
+#define DPAA2_ETH_FAS_L4CE           0x00000001
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 9c47c69..c92b865 100644 (file)
@@ -310,6 +310,28 @@ dpaa2_dev_tx_queue_release(void *q __rte_unused)
        PMD_INIT_FUNC_TRACE();
 }
 
+static const uint32_t *
+dpaa2_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+       static const uint32_t ptypes[] = {
+               /*todo -= add more types */
+               RTE_PTYPE_L2_ETHER,
+               RTE_PTYPE_L3_IPV4,
+               RTE_PTYPE_L3_IPV4_EXT,
+               RTE_PTYPE_L3_IPV6,
+               RTE_PTYPE_L3_IPV6_EXT,
+               RTE_PTYPE_L4_TCP,
+               RTE_PTYPE_L4_UDP,
+               RTE_PTYPE_L4_SCTP,
+               RTE_PTYPE_L4_ICMP,
+               RTE_PTYPE_UNKNOWN
+       };
+
+       if (dev->rx_pkt_burst == dpaa2_dev_rx)
+               return ptypes;
+       return NULL;
+}
+
 static int
 dpaa2_dev_start(struct rte_eth_dev *dev)
 {
@@ -517,6 +539,7 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {
        .promiscuous_enable   = dpaa2_dev_promiscuous_enable,
        .promiscuous_disable  = dpaa2_dev_promiscuous_disable,
        .dev_infos_get     = dpaa2_dev_info_get,
+       .dev_supported_ptypes_get = dpaa2_supported_ptypes_get,
        .mtu_set           = dpaa2_dev_mtu_set,
        .rx_queue_setup    = dpaa2_dev_rx_queue_setup,
        .rx_queue_release  = dpaa2_dev_rx_queue_release,
index 25574c0..c1ea33a 100644 (file)
 #include <dpaa2_hw_mempool.h>
 
 #include "dpaa2_ethdev.h"
+#include "base/dpaa2_hw_dpni_annot.h"
+
+static inline uint32_t __attribute__((hot))
+dpaa2_dev_rx_parse(uint64_t hw_annot_addr)
+{
+       uint32_t pkt_type = RTE_PTYPE_UNKNOWN;
+       struct dpaa2_annot_hdr *annotation =
+                       (struct dpaa2_annot_hdr *)hw_annot_addr;
+
+       PMD_RX_LOG(DEBUG, "annotation = 0x%lx   ", annotation->word4);
+
+       if (BIT_ISSET_AT_POS(annotation->word3, L2_ARP_PRESENT)) {
+               pkt_type = RTE_PTYPE_L2_ETHER_ARP;
+               goto parse_done;
+       } else if (BIT_ISSET_AT_POS(annotation->word3, L2_ETH_MAC_PRESENT)) {
+               pkt_type = RTE_PTYPE_L2_ETHER;
+       } else {
+               goto parse_done;
+       }
+
+       if (BIT_ISSET_AT_POS(annotation->word4, L3_IPV4_1_PRESENT |
+                            L3_IPV4_N_PRESENT)) {
+               pkt_type |= RTE_PTYPE_L3_IPV4;
+               if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_1_OPT_PRESENT |
+                       L3_IP_N_OPT_PRESENT))
+                       pkt_type |= RTE_PTYPE_L3_IPV4_EXT;
+
+       } else if (BIT_ISSET_AT_POS(annotation->word4, L3_IPV6_1_PRESENT |
+                 L3_IPV6_N_PRESENT)) {
+               pkt_type |= RTE_PTYPE_L3_IPV6;
+               if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_1_OPT_PRESENT |
+                   L3_IP_N_OPT_PRESENT))
+                       pkt_type |= RTE_PTYPE_L3_IPV6_EXT;
+       } else {
+               goto parse_done;
+       }
+
+       if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_1_FIRST_FRAGMENT |
+           L3_IP_1_MORE_FRAGMENT |
+           L3_IP_N_FIRST_FRAGMENT |
+           L3_IP_N_MORE_FRAGMENT)) {
+               pkt_type |= RTE_PTYPE_L4_FRAG;
+               goto parse_done;
+       } else {
+               pkt_type |= RTE_PTYPE_L4_NONFRAG;
+       }
+
+       if (BIT_ISSET_AT_POS(annotation->word4, L3_PROTO_UDP_PRESENT))
+               pkt_type |= RTE_PTYPE_L4_UDP;
+
+       else if (BIT_ISSET_AT_POS(annotation->word4, L3_PROTO_TCP_PRESENT))
+               pkt_type |= RTE_PTYPE_L4_TCP;
+
+       else if (BIT_ISSET_AT_POS(annotation->word4, L3_PROTO_SCTP_PRESENT))
+               pkt_type |= RTE_PTYPE_L4_SCTP;
+
+       else if (BIT_ISSET_AT_POS(annotation->word4, L3_PROTO_ICMP_PRESENT))
+               pkt_type |= RTE_PTYPE_L4_ICMP;
+
+       else if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_UNKNOWN_PROTOCOL))
+               pkt_type |= RTE_PTYPE_UNKNOWN;
+
+parse_done:
+       return pkt_type;
+}
+
+static inline void __attribute__((hot))
+dpaa2_dev_rx_offload(uint64_t hw_annot_addr, struct rte_mbuf *mbuf)
+{
+       struct dpaa2_annot_hdr *annotation =
+               (struct dpaa2_annot_hdr *)hw_annot_addr;
+
+       if (BIT_ISSET_AT_POS(annotation->word3,
+                            L2_VLAN_1_PRESENT | L2_VLAN_N_PRESENT))
+               mbuf->ol_flags |= PKT_RX_VLAN_PKT;
+
+       if (BIT_ISSET_AT_POS(annotation->word8, DPAA2_ETH_FAS_L3CE))
+               mbuf->ol_flags |= PKT_RX_IP_CKSUM_BAD;
+
+       if (BIT_ISSET_AT_POS(annotation->word8, DPAA2_ETH_FAS_L4CE))
+               mbuf->ol_flags |= PKT_RX_L4_CKSUM_BAD;
+}
 
 static inline struct rte_mbuf *__attribute__((hot))
 eth_fd_to_mbuf(const struct qbman_fd *fd)
@@ -66,7 +148,14 @@ eth_fd_to_mbuf(const struct qbman_fd *fd)
        mbuf->data_len = DPAA2_GET_FD_LEN(fd);
        mbuf->pkt_len = mbuf->data_len;
 
-       mbuf->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4;
+       /* Parse the packet */
+       /* parse results are after the private - sw annotation area */
+       mbuf->packet_type = dpaa2_dev_rx_parse(
+                       (uint64_t)(DPAA2_GET_FD_ADDR(fd))
+                        + DPAA2_FD_PTA_SIZE);
+
+       dpaa2_dev_rx_offload((uint64_t)(DPAA2_GET_FD_ADDR(fd)) +
+                            DPAA2_FD_PTA_SIZE, mbuf);
 
        mbuf->next = NULL;
        rte_mbuf_refcnt_set(mbuf, 1);