LCOV - code coverage report
Current view: top level - drivers/net/ice/base - ice_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 1153 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 58 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 1115 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2001-2023 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "ice_common.h"
       6                 :            : #include "ice_flow.h"
       7                 :            : 
       8                 :            : /* Size of known protocol header fields */
       9                 :            : #define ICE_FLOW_FLD_SZ_ETH_TYPE        2
      10                 :            : #define ICE_FLOW_FLD_SZ_VLAN            2
      11                 :            : #define ICE_FLOW_FLD_SZ_IPV4_ADDR       4
      12                 :            : #define ICE_FLOW_FLD_SZ_IPV6_ADDR       16
      13                 :            : #define ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR 4
      14                 :            : #define ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR 6
      15                 :            : #define ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR 8
      16                 :            : #define ICE_FLOW_FLD_SZ_IPV4_ID         2
      17                 :            : #define ICE_FLOW_FLD_SZ_IPV6_ID         4
      18                 :            : #define ICE_FLOW_FLD_SZ_IP_CHKSUM       2
      19                 :            : #define ICE_FLOW_FLD_SZ_TCP_CHKSUM      2
      20                 :            : #define ICE_FLOW_FLD_SZ_UDP_CHKSUM      2
      21                 :            : #define ICE_FLOW_FLD_SZ_SCTP_CHKSUM     4
      22                 :            : #define ICE_FLOW_FLD_SZ_IP_DSCP         1
      23                 :            : #define ICE_FLOW_FLD_SZ_IP_TTL          1
      24                 :            : #define ICE_FLOW_FLD_SZ_IP_PROT         1
      25                 :            : #define ICE_FLOW_FLD_SZ_PORT            2
      26                 :            : #define ICE_FLOW_FLD_SZ_TCP_FLAGS       1
      27                 :            : #define ICE_FLOW_FLD_SZ_ICMP_TYPE       1
      28                 :            : #define ICE_FLOW_FLD_SZ_ICMP_CODE       1
      29                 :            : #define ICE_FLOW_FLD_SZ_ARP_OPER        2
      30                 :            : #define ICE_FLOW_FLD_SZ_GRE_KEYID       4
      31                 :            : #define ICE_FLOW_FLD_SZ_GTP_TEID        4
      32                 :            : #define ICE_FLOW_FLD_SZ_GTP_QFI         2
      33                 :            : #define ICE_FLOW_FLD_SZ_PPPOE_SESS_ID   2
      34                 :            : #define ICE_FLOW_FLD_SZ_PFCP_SEID 8
      35                 :            : #define ICE_FLOW_FLD_SZ_L2TPV3_SESS_ID  4
      36                 :            : #define ICE_FLOW_FLD_SZ_ESP_SPI 4
      37                 :            : #define ICE_FLOW_FLD_SZ_AH_SPI  4
      38                 :            : #define ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI   4
      39                 :            : #define ICE_FLOW_FLD_SZ_VXLAN_VNI       4
      40                 :            : #define ICE_FLOW_FLD_SZ_ECPRI_TP0_PC_ID 2
      41                 :            : #define ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID  2
      42                 :            : #define ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID      2
      43                 :            : 
      44                 :            : /* Describe properties of a protocol header field */
      45                 :            : struct ice_flow_field_info {
      46                 :            :         enum ice_flow_seg_hdr hdr;
      47                 :            :         s16 off;        /* Offset from start of a protocol header, in bits */
      48                 :            :         u16 size;       /* Size of fields in bits */
      49                 :            :         u16 mask;       /* 16-bit mask for field */
      50                 :            : };
      51                 :            : 
      52                 :            : #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
      53                 :            :         .hdr = _hdr, \
      54                 :            :         .off = (_offset_bytes) * BITS_PER_BYTE, \
      55                 :            :         .size = (_size_bytes) * BITS_PER_BYTE, \
      56                 :            :         .mask = 0, \
      57                 :            : }
      58                 :            : 
      59                 :            : #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
      60                 :            :         .hdr = _hdr, \
      61                 :            :         .off = (_offset_bytes) * BITS_PER_BYTE, \
      62                 :            :         .size = (_size_bytes) * BITS_PER_BYTE, \
      63                 :            :         .mask = _mask, \
      64                 :            : }
      65                 :            : 
      66                 :            : /* Table containing properties of supported protocol header fields */
      67                 :            : static const
      68                 :            : struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
      69                 :            :         /* Ether */
      70                 :            :         /* ICE_FLOW_FIELD_IDX_ETH_DA */
      71                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
      72                 :            :         /* ICE_FLOW_FIELD_IDX_ETH_SA */
      73                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
      74                 :            :         /* ICE_FLOW_FIELD_IDX_S_VLAN */
      75                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, ICE_FLOW_FLD_SZ_VLAN),
      76                 :            :         /* ICE_FLOW_FIELD_IDX_C_VLAN */
      77                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, ICE_FLOW_FLD_SZ_VLAN),
      78                 :            :         /* ICE_FLOW_FIELD_IDX_ETH_TYPE */
      79                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ICE_FLOW_FLD_SZ_ETH_TYPE),
      80                 :            :         /* IPv4 / IPv6 */
      81                 :            :         /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
      82                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, ICE_FLOW_FLD_SZ_IP_DSCP,
      83                 :            :                               0x00fc),
      84                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
      85                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, ICE_FLOW_FLD_SZ_IP_DSCP,
      86                 :            :                               0x0ff0),
      87                 :            :         /* ICE_FLOW_FIELD_IDX_IPV4_TTL */
      88                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8,
      89                 :            :                               ICE_FLOW_FLD_SZ_IP_TTL, 0xff00),
      90                 :            :         /* ICE_FLOW_FIELD_IDX_IPV4_PROT */
      91                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8,
      92                 :            :                               ICE_FLOW_FLD_SZ_IP_PROT, 0x00ff),
      93                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_TTL */
      94                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6,
      95                 :            :                               ICE_FLOW_FLD_SZ_IP_TTL, 0x00ff),
      96                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_PROT */
      97                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6,
      98                 :            :                               ICE_FLOW_FLD_SZ_IP_PROT, 0xff00),
      99                 :            :         /* ICE_FLOW_FIELD_IDX_IPV4_SA */
     100                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, ICE_FLOW_FLD_SZ_IPV4_ADDR),
     101                 :            :         /* ICE_FLOW_FIELD_IDX_IPV4_DA */
     102                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, ICE_FLOW_FLD_SZ_IPV4_ADDR),
     103                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_SA */
     104                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, ICE_FLOW_FLD_SZ_IPV6_ADDR),
     105                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_DA */
     106                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR),
     107                 :            :         /* ICE_FLOW_FIELD_IDX_IPV4_CHKSUM */
     108                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 10, ICE_FLOW_FLD_SZ_IP_CHKSUM),
     109                 :            :         /* ICE_FLOW_FIELD_IDX_IPV4_FRAG */
     110                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
     111                 :            :                           ICE_FLOW_FLD_SZ_IPV4_ID),
     112                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_FRAG */
     113                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
     114                 :            :                           ICE_FLOW_FLD_SZ_IPV6_ID),
     115                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA */
     116                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
     117                 :            :                           ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
     118                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA */
     119                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
     120                 :            :                           ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
     121                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA */
     122                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
     123                 :            :                           ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
     124                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA */
     125                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
     126                 :            :                           ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
     127                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA */
     128                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
     129                 :            :                           ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
     130                 :            :         /* ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA */
     131                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
     132                 :            :                           ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
     133                 :            :         /* Transport */
     134                 :            :         /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
     135                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, ICE_FLOW_FLD_SZ_PORT),
     136                 :            :         /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */
     137                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, ICE_FLOW_FLD_SZ_PORT),
     138                 :            :         /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */
     139                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, ICE_FLOW_FLD_SZ_PORT),
     140                 :            :         /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */
     141                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, ICE_FLOW_FLD_SZ_PORT),
     142                 :            :         /* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */
     143                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, ICE_FLOW_FLD_SZ_PORT),
     144                 :            :         /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
     145                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, ICE_FLOW_FLD_SZ_PORT),
     146                 :            :         /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
     147                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, ICE_FLOW_FLD_SZ_TCP_FLAGS),
     148                 :            :         /* ICE_FLOW_FIELD_IDX_TCP_CHKSUM */
     149                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 16, ICE_FLOW_FLD_SZ_TCP_CHKSUM),
     150                 :            :         /* ICE_FLOW_FIELD_IDX_UDP_CHKSUM */
     151                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 6, ICE_FLOW_FLD_SZ_UDP_CHKSUM),
     152                 :            :         /* ICE_FLOW_FIELD_IDX_SCTP_CHKSUM */
     153                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 8,
     154                 :            :                           ICE_FLOW_FLD_SZ_SCTP_CHKSUM),
     155                 :            :         /* ARP */
     156                 :            :         /* ICE_FLOW_FIELD_IDX_ARP_SIP */
     157                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, ICE_FLOW_FLD_SZ_IPV4_ADDR),
     158                 :            :         /* ICE_FLOW_FIELD_IDX_ARP_DIP */
     159                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, ICE_FLOW_FLD_SZ_IPV4_ADDR),
     160                 :            :         /* ICE_FLOW_FIELD_IDX_ARP_SHA */
     161                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
     162                 :            :         /* ICE_FLOW_FIELD_IDX_ARP_DHA */
     163                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
     164                 :            :         /* ICE_FLOW_FIELD_IDX_ARP_OP */
     165                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, ICE_FLOW_FLD_SZ_ARP_OPER),
     166                 :            :         /* ICMP */
     167                 :            :         /* ICE_FLOW_FIELD_IDX_ICMP_TYPE */
     168                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, ICE_FLOW_FLD_SZ_ICMP_TYPE),
     169                 :            :         /* ICE_FLOW_FIELD_IDX_ICMP_CODE */
     170                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, ICE_FLOW_FLD_SZ_ICMP_CODE),
     171                 :            :         /* GRE */
     172                 :            :         /* ICE_FLOW_FIELD_IDX_GRE_KEYID */
     173                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12, ICE_FLOW_FLD_SZ_GRE_KEYID),
     174                 :            :         /* GTP */
     175                 :            :         /* ICE_FLOW_FIELD_IDX_GTPC_TEID */
     176                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12,
     177                 :            :                           ICE_FLOW_FLD_SZ_GTP_TEID),
     178                 :            :         /* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */
     179                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12,
     180                 :            :                           ICE_FLOW_FLD_SZ_GTP_TEID),
     181                 :            :         /* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */
     182                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12,
     183                 :            :                           ICE_FLOW_FLD_SZ_GTP_TEID),
     184                 :            :         /* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */
     185                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22,
     186                 :            :                               ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
     187                 :            :         /* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
     188                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12,
     189                 :            :                           ICE_FLOW_FLD_SZ_GTP_TEID),
     190                 :            :         /* ICE_FLOW_FIELD_IDX_GTPU_UP_QFI */
     191                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_UP, 22,
     192                 :            :                               ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
     193                 :            :         /* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
     194                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12,
     195                 :            :                           ICE_FLOW_FLD_SZ_GTP_TEID),
     196                 :            :         /* ICE_FLOW_FIELD_IDX_GTPU_DWN_QFI */
     197                 :            :         ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_DWN, 22,
     198                 :            :                               ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
     199                 :            :         /* PPPoE */
     200                 :            :         /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
     201                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2,
     202                 :            :                           ICE_FLOW_FLD_SZ_PPPOE_SESS_ID),
     203                 :            :         /* PFCP */
     204                 :            :         /* ICE_FLOW_FIELD_IDX_PFCP_SEID */
     205                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12,
     206                 :            :                           ICE_FLOW_FLD_SZ_PFCP_SEID),
     207                 :            :         /* L2TPV3 */
     208                 :            :         /* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
     209                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0,
     210                 :            :                           ICE_FLOW_FLD_SZ_L2TPV3_SESS_ID),
     211                 :            :         /* ESP */
     212                 :            :         /* ICE_FLOW_FIELD_IDX_ESP_SPI */
     213                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0,
     214                 :            :                           ICE_FLOW_FLD_SZ_ESP_SPI),
     215                 :            :         /* AH */
     216                 :            :         /* ICE_FLOW_FIELD_IDX_AH_SPI */
     217                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4,
     218                 :            :                           ICE_FLOW_FLD_SZ_AH_SPI),
     219                 :            :         /* NAT_T_ESP */
     220                 :            :         /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
     221                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8,
     222                 :            :                           ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI),
     223                 :            :         /* ICE_FLOW_FIELD_IDX_VXLAN_VNI */
     224                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VXLAN, 12,
     225                 :            :                           ICE_FLOW_FLD_SZ_VXLAN_VNI),
     226                 :            :         /* ECPRI_TP0 */
     227                 :            :         /* ICE_FLOW_FIELD_IDX_ECPRI_TP0_PC_ID */
     228                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ECPRI_TP0, 4,
     229                 :            :                           ICE_FLOW_FLD_SZ_ECPRI_TP0_PC_ID),
     230                 :            :         /* UDP_ECPRI_TP0 */
     231                 :            :         /* ICE_FLOW_FIELD_IDX_UDP_ECPRI_TP0_PC_ID */
     232                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP_ECPRI_TP0, 12,
     233                 :            :                           ICE_FLOW_FLD_SZ_ECPRI_TP0_PC_ID),
     234                 :            :         /* L2TPV2 */
     235                 :            :         /* ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID */
     236                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 12,
     237                 :            :                           ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID),
     238                 :            :         /* L2TPV2_LEN */
     239                 :            :         /* ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID */
     240                 :            :         ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 14,
     241                 :            :                           ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID),
     242                 :            : };
     243                 :            : 
     244                 :            : /* Bitmaps indicating relevant packet types for a particular protocol header
     245                 :            :  *
     246                 :            :  * Packet types for packets with an Outer/First/Single MAC header
     247                 :            :  */
     248                 :            : static const u32 ice_ptypes_mac_ofos[] = {
     249                 :            :         0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
     250                 :            :         0x0000077E, 0x000003FF, 0x00000000, 0x00000000,
     251                 :            :         0x00400000, 0x03FFF000, 0xFFFFFFE0, 0x00100707,
     252                 :            :         0xFFFFF000, 0x000003FF, 0x00000000, 0x00000000,
     253                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     254                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     255                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     256                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     257                 :            : };
     258                 :            : 
     259                 :            : /* Packet types for packets with an Innermost/Last MAC VLAN header */
     260                 :            : static const u32 ice_ptypes_macvlan_il[] = {
     261                 :            :         0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
     262                 :            :         0x0000077E, 0x00000000, 0x00000000, 0x00000000,
     263                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     264                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     265                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     266                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     267                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     268                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     269                 :            : };
     270                 :            : 
     271                 :            : /* Packet types for packets with an Outer/First/Single non-frag IPv4 header,
     272                 :            :  * does NOT include IPV4 other PTYPEs
     273                 :            :  */
     274                 :            : static const u32 ice_ptypes_ipv4_ofos[] = {
     275                 :            :         0x1D800000, 0xBFBF7800, 0x000001DF, 0x00000000,
     276                 :            :         0x00000000, 0x00000155, 0x00000000, 0x00000000,
     277                 :            :         0x00000000, 0x000FC000, 0x000002A0, 0x00100000,
     278                 :            :         0x00015000, 0x00000000, 0x00000000, 0x00000000,
     279                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     280                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     281                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     282                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     283                 :            : };
     284                 :            : 
     285                 :            : /* Packet types for packets with an Outer/First/Single non-frag IPv4 header,
     286                 :            :  * includes IPV4 other PTYPEs
     287                 :            :  */
     288                 :            : static const u32 ice_ptypes_ipv4_ofos_all[] = {
     289                 :            :         0x1D800000, 0x27BF7800, 0x00000000, 0x00000000,
     290                 :            :         0x00000000, 0x00000155, 0x00000000, 0x00000000,
     291                 :            :         0x00000000, 0x000FC000, 0x83E0FAA0, 0x00000101,
     292                 :            :         0x3FFD5000, 0x00000000, 0x02FBEFBC, 0x00000000,
     293                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     294                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     295                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     296                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     297                 :            : };
     298                 :            : 
     299                 :            : /* Packet types for packets with an Innermost/Last IPv4 header */
     300                 :            : static const u32 ice_ptypes_ipv4_il[] = {
     301                 :            :         0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
     302                 :            :         0x0000000E, 0x00000000, 0x00000000, 0x00000000,
     303                 :            :         0x00000000, 0x00000000, 0x001FF800, 0x00100000,
     304                 :            :         0xC0FC0000, 0x0000000F, 0xBC0BC0BC, 0x00000BC0,
     305                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     306                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     307                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     308                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     309                 :            : };
     310                 :            : 
     311                 :            : /* Packet types for packets with an Outer/First/Single non-frag IPv6 header,
     312                 :            :  * does NOT include IVP6 other PTYPEs
     313                 :            :  */
     314                 :            : static const u32 ice_ptypes_ipv6_ofos[] = {
     315                 :            :         0x00000000, 0x00000000, 0x76000000, 0x10002000,
     316                 :            :         0x00000000, 0x000002AA, 0x00000000, 0x00000000,
     317                 :            :         0x00000000, 0x03F00000, 0x00000540, 0x00000000,
     318                 :            :         0x0002A000, 0x00000000, 0x00000000, 0x00000000,
     319                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     320                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     321                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     322                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     323                 :            : };
     324                 :            : 
     325                 :            : /* Packet types for packets with an Outer/First/Single non-frag IPv6 header,
     326                 :            :  * includes IPV6 other PTYPEs
     327                 :            :  */
     328                 :            : static const u32 ice_ptypes_ipv6_ofos_all[] = {
     329                 :            :         0x00000000, 0x00000000, 0x76000000, 0xFEFDE000,
     330                 :            :         0x0000077E, 0x000002AA, 0x00000000, 0x00000000,
     331                 :            :         0x00000000, 0x03F00000, 0x7C1F0540, 0x00000206,
     332                 :            :         0xC002A000, 0x000003FF, 0xBC000000, 0x0002FBEF,
     333                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     334                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     335                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     336                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     337                 :            : };
     338                 :            : 
     339                 :            : /* Packet types for packets with an Innermost/Last IPv6 header */
     340                 :            : static const u32 ice_ptypes_ipv6_il[] = {
     341                 :            :         0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
     342                 :            :         0x00000770, 0x00000000, 0x00000000, 0x00000000,
     343                 :            :         0x00000000, 0x00000000, 0x7FE00000, 0x00000000,
     344                 :            :         0x3F000000, 0x000003F0, 0x02F02F00, 0x0002F02F,
     345                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     346                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     347                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     348                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     349                 :            : };
     350                 :            : 
     351                 :            : /* Packet types for packets with an Outer/First/Single
     352                 :            :  * non-frag IPv4 header - no L4
     353                 :            :  */
     354                 :            : static const u32 ice_ptypes_ipv4_ofos_no_l4[] = {
     355                 :            :         0x10800000, 0x04000800, 0x00000000, 0x00000000,
     356                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     357                 :            :         0x00000000, 0x000cc000, 0x000002A0, 0x00000000,
     358                 :            :         0x00015000, 0x00000000, 0x00000000, 0x00000000,
     359                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     360                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     361                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     362                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     363                 :            : };
     364                 :            : 
     365                 :            : /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
     366                 :            : static const u32 ice_ptypes_ipv4_il_no_l4[] = {
     367                 :            :         0x60000000, 0x18043008, 0x80000002, 0x6010c021,
     368                 :            :         0x00000008, 0x00000000, 0x00000000, 0x00000000,
     369                 :            :         0x00000000, 0x00000000, 0x00139800, 0x00000000,
     370                 :            :         0xC08C0000, 0x00000008, 0x00000000, 0x00000000,
     371                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     372                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     373                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     374                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     375                 :            : };
     376                 :            : 
     377                 :            : /* Packet types for packets with an Outer/First/Single
     378                 :            :  * non-frag IPv6 header - no L4
     379                 :            :  */
     380                 :            : static const u32 ice_ptypes_ipv6_ofos_no_l4[] = {
     381                 :            :         0x00000000, 0x00000000, 0x42000000, 0x10002000,
     382                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     383                 :            :         0x00000000, 0x02300000, 0x00000540, 0x00000000,
     384                 :            :         0x0002A000, 0x00000000, 0x00000000, 0x00000000,
     385                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     386                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     387                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     388                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     389                 :            : };
     390                 :            : 
     391                 :            : /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
     392                 :            : static const u32 ice_ptypes_ipv6_il_no_l4[] = {
     393                 :            :         0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
     394                 :            :         0x00000430, 0x00000000, 0x00000000, 0x00000000,
     395                 :            :         0x00000000, 0x00000000, 0x4e600000, 0x00000000,
     396                 :            :         0x23000000, 0x00000230, 0x00000000, 0x00000000,
     397                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     398                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     399                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     400                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     401                 :            : };
     402                 :            : 
     403                 :            : /* Packet types for packets with an Outermost/First ARP header */
     404                 :            : static const u32 ice_ptypes_arp_of[] = {
     405                 :            :         0x00000800, 0x00000000, 0x00000000, 0x00000000,
     406                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     407                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     408                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     409                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     410                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     411                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     412                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     413                 :            : };
     414                 :            : 
     415                 :            : /* UDP Packet types for non-tunneled packets or tunneled
     416                 :            :  * packets with inner UDP.
     417                 :            :  */
     418                 :            : static const u32 ice_ptypes_udp_il[] = {
     419                 :            :         0x81000000, 0x20204040, 0x04000010, 0x80810102,
     420                 :            :         0x00000040, 0x00000000, 0x00000000, 0x00000000,
     421                 :            :         0x00000000, 0x00410000, 0x908427E0, 0x00100007,
     422                 :            :         0x0413F000, 0x00000041, 0x10410410, 0x00004104,
     423                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     424                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     425                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     426                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     427                 :            : };
     428                 :            : 
     429                 :            : /* Packet types for packets with an Innermost/Last TCP header */
     430                 :            : static const u32 ice_ptypes_tcp_il[] = {
     431                 :            :         0x04000000, 0x80810102, 0x10000040, 0x02040408,
     432                 :            :         0x00000102, 0x00000000, 0x00000000, 0x00000000,
     433                 :            :         0x00000000, 0x00820000, 0x21084000, 0x00000000,
     434                 :            :         0x08200000, 0x00000082, 0x20820820, 0x00008208,
     435                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     436                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     437                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     438                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     439                 :            : };
     440                 :            : 
     441                 :            : /* Packet types for packets with an Innermost/Last SCTP header */
     442                 :            : static const u32 ice_ptypes_sctp_il[] = {
     443                 :            :         0x08000000, 0x01020204, 0x20000081, 0x04080810,
     444                 :            :         0x00000204, 0x00000000, 0x00000000, 0x00000000,
     445                 :            :         0x00000000, 0x01040000, 0x00000000, 0x00000000,
     446                 :            :         0x10400000, 0x00000104, 0x00000000, 0x00000000,
     447                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     448                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     449                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     450                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     451                 :            : };
     452                 :            : 
     453                 :            : /* Packet types for packets with an Outermost/First ICMP header */
     454                 :            : static const u32 ice_ptypes_icmp_of[] = {
     455                 :            :         0x10000000, 0x00000000, 0x00000000, 0x00000000,
     456                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     457                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     458                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     459                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     460                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     461                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     462                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     463                 :            : };
     464                 :            : 
     465                 :            : /* Packet types for packets with an Innermost/Last ICMP header */
     466                 :            : static const u32 ice_ptypes_icmp_il[] = {
     467                 :            :         0x00000000, 0x02040408, 0x40000102, 0x08101020,
     468                 :            :         0x00000408, 0x00000000, 0x00000000, 0x00000000,
     469                 :            :         0x00000000, 0x00000000, 0x42108000, 0x00000000,
     470                 :            :         0x20800000, 0x00000208, 0x00000000, 0x00000000,
     471                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     472                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     473                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     474                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     475                 :            : };
     476                 :            : 
     477                 :            : /* Packet types for packets with an Outermost/First GRE header */
     478                 :            : static const u32 ice_ptypes_gre_of[] = {
     479                 :            :         0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
     480                 :            :         0x0000017E, 0x00000000, 0x00000000, 0x00000000,
     481                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     482                 :            :         0x00000000, 0x00000000, 0xBEFBEFBC, 0x0002FBEF,
     483                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     484                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     485                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     486                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     487                 :            : };
     488                 :            : 
     489                 :            : /* Packet types for packets with an Innermost/Last MAC header */
     490                 :            : static const u32 ice_ptypes_mac_il[] = {
     491                 :            :         0x00000000, 0x20000000, 0x00000000, 0x00000000,
     492                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     493                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     494                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     495                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     496                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     497                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     498                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     499                 :            : };
     500                 :            : 
     501                 :            : /* Packet types for GTPC */
     502                 :            : static const u32 ice_ptypes_gtpc[] = {
     503                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     504                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     505                 :            :         0x00000000, 0x00000000, 0x000001E0, 0x00000000,
     506                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     507                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     508                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     509                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     510                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     511                 :            : };
     512                 :            : 
     513                 :            : /* Packet types for VXLAN with VNI */
     514                 :            : static const u32 ice_ptypes_vxlan_vni[] = {
     515                 :            :         0x00000000, 0xBFBFF800, 0x00EFDFDF, 0xFEFDE000,
     516                 :            :         0x03BF7F7E, 0x00000000, 0x00000000, 0x00000000,
     517                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     518                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     519                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     520                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     521                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     522                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     523                 :            : };
     524                 :            : 
     525                 :            : /* Packet types for GTPC with TEID */
     526                 :            : static const u32 ice_ptypes_gtpc_tid[] = {
     527                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     528                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     529                 :            :         0x00000000, 0x00000000, 0x00000060, 0x00000000,
     530                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     531                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     532                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     533                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     534                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     535                 :            : };
     536                 :            : 
     537                 :            : /* Packet types for GTPU */
     538                 :            : static const struct ice_ptype_attributes ice_attr_gtpu_session[] = {
     539                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_SESSION },
     540                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_SESSION },
     541                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
     542                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_SESSION },
     543                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_SESSION },
     544                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_SESSION },
     545                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_SESSION },
     546                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
     547                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_SESSION },
     548                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_SESSION },
     549                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_SESSION },
     550                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_SESSION },
     551                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
     552                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_SESSION },
     553                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_SESSION },
     554                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_SESSION },
     555                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_SESSION },
     556                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
     557                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_SESSION },
     558                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_SESSION },
     559                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_SESSION },
     560                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_SESSION },
     561                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_SESSION },
     562                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_SESSION },
     563                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_SESSION },
     564                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_SESSION },
     565                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_SESSION },
     566                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_SESSION },
     567                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_SESSION },
     568                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_SESSION },
     569                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_SESSION },
     570                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_SESSION },
     571                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_SESSION },
     572                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_SESSION },
     573                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_SESSION },
     574                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_SESSION },
     575                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_SESSION },
     576                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_SESSION },
     577                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_SESSION },
     578                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_SESSION },
     579                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_SESSION },
     580                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_SESSION },
     581                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_SESSION },
     582                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_SESSION },
     583                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_SESSION },
     584                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_SESSION },
     585                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_SESSION },
     586                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_SESSION },
     587                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_SESSION },
     588                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_SESSION },
     589                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_SESSION },
     590                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_SESSION },
     591                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_SESSION },
     592                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_SESSION },
     593                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_SESSION },
     594                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_SESSION },
     595                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_SESSION },
     596                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_SESSION },
     597                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_SESSION },
     598                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_SESSION },
     599                 :            : };
     600                 :            : 
     601                 :            : static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
     602                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_PDU_EH },
     603                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     604                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
     605                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     606                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_PDU_EH },
     607                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_PDU_EH },
     608                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     609                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
     610                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     611                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_PDU_EH },
     612                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_PDU_EH },
     613                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     614                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
     615                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     616                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     617                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_PDU_EH },
     618                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     619                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
     620                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     621                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     622                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     623                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     624                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     625                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     626                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     627                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     628                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     629                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     630                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     631                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_PDU_EH },
     632                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     633                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     634                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     635                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     636                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     637                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     638                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     639                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     640                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     641                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_PDU_EH },
     642                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     643                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     644                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     645                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     646                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     647                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     648                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     649                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     650                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     651                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_PDU_EH },
     652                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     653                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     654                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     655                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     656                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     657                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_PDU_EH },
     658                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     659                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_PDU_EH },
     660                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_PDU_EH },
     661                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_PDU_EH },
     662                 :            : };
     663                 :            : 
     664                 :            : static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
     665                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
     666                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     667                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
     668                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     669                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
     670                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
     671                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     672                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
     673                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     674                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
     675                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
     676                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     677                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
     678                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     679                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     680                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
     681                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     682                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
     683                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     684                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     685                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     686                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     687                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     688                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     689                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     690                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     691                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     692                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     693                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     694                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_DOWNLINK },
     695                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     696                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     697                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     698                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     699                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     700                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     701                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     702                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     703                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     704                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_DOWNLINK },
     705                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     706                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     707                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     708                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     709                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     710                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     711                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     712                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     713                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     714                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_DOWNLINK },
     715                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     716                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     717                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     718                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     719                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     720                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
     721                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     722                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
     723                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_DOWNLINK },
     724                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_DOWNLINK },
     725                 :            : };
     726                 :            : 
     727                 :            : static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
     728                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_UPLINK },
     729                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_UPLINK },
     730                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
     731                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_UPLINK },
     732                 :            :         { ICE_MAC_IPV4_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_UPLINK },
     733                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_UPLINK },
     734                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_UPLINK },
     735                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
     736                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_UPLINK },
     737                 :            :         { ICE_MAC_IPV6_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_UPLINK },
     738                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_UPLINK },
     739                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_UPLINK },
     740                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
     741                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_UPLINK },
     742                 :            :         { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
     743                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_UPLINK },
     744                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_UPLINK },
     745                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
     746                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_UPLINK },
     747                 :            :         { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
     748                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_UPLINK },
     749                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_UPLINK },
     750                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_UPLINK },
     751                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_UPLINK },
     752                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_UPLINK },
     753                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_UPLINK },
     754                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_UPLINK },
     755                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_UPLINK },
     756                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_UPLINK },
     757                 :            :         { MAC_IPV4_TUN_IPV4_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_UPLINK },
     758                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_UPLINK },
     759                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_UPLINK },
     760                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_UPLINK },
     761                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_UPLINK },
     762                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_UPLINK },
     763                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_UPLINK },
     764                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_UPLINK },
     765                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_UPLINK },
     766                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_UPLINK },
     767                 :            :         { MAC_IPV4_TUN_IPV6_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_UPLINK },
     768                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_UPLINK },
     769                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_UPLINK },
     770                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_UPLINK },
     771                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_UPLINK },
     772                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_UPLINK },
     773                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_UPLINK },
     774                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_UPLINK },
     775                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_UPLINK },
     776                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_UPLINK },
     777                 :            :         { MAC_IPV6_TUN_IPV4_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_UPLINK },
     778                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_FRAG,     ICE_PTYPE_ATTR_GTP_UPLINK },
     779                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_PAY,      ICE_PTYPE_ATTR_GTP_UPLINK },
     780                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_UDP_PAY,  ICE_PTYPE_ATTR_GTP_UPLINK },
     781                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_TCP,      ICE_PTYPE_ATTR_GTP_UPLINK },
     782                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV4_ICMP,     ICE_PTYPE_ATTR_GTP_UPLINK },
     783                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_FRAG,     ICE_PTYPE_ATTR_GTP_UPLINK },
     784                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_PAY,      ICE_PTYPE_ATTR_GTP_UPLINK },
     785                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_UDP_PAY,  ICE_PTYPE_ATTR_GTP_UPLINK },
     786                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_TCP,      ICE_PTYPE_ATTR_GTP_UPLINK },
     787                 :            :         { MAC_IPV6_TUN_IPV6_GTPU_IPV6_ICMPV6,   ICE_PTYPE_ATTR_GTP_UPLINK },
     788                 :            : };
     789                 :            : 
     790                 :            : static const u32 ice_ptypes_gtpu[] = {
     791                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     792                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     793                 :            :         0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
     794                 :            :         0x00000000, 0x0000003F, 0xBEFBEFBC, 0x0002FBEF,
     795                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     796                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     797                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     798                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     799                 :            : };
     800                 :            : 
     801                 :            : /* Packet types for PPPoE */
     802                 :            : static const u32 ice_ptypes_pppoe[] = {
     803                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     804                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     805                 :            :         0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
     806                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     807                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     808                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     809                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     810                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     811                 :            : };
     812                 :            : 
     813                 :            : /* Packet types for packets with PFCP NODE header */
     814                 :            : static const u32 ice_ptypes_pfcp_node[] = {
     815                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     816                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     817                 :            :         0x00000000, 0x00000000, 0x80000000, 0x00000002,
     818                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     819                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     820                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     821                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     822                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     823                 :            : };
     824                 :            : 
     825                 :            : /* Packet types for packets with PFCP SESSION header */
     826                 :            : static const u32 ice_ptypes_pfcp_session[] = {
     827                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     828                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     829                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000005,
     830                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     831                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     832                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     833                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     834                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     835                 :            : };
     836                 :            : 
     837                 :            : /* Packet types for L2TPv3 */
     838                 :            : static const u32 ice_ptypes_l2tpv3[] = {
     839                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     840                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     841                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000300,
     842                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     843                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     844                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     845                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     846                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     847                 :            : };
     848                 :            : 
     849                 :            : /* Packet types for ESP */
     850                 :            : static const u32 ice_ptypes_esp[] = {
     851                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     852                 :            :         0x00000000, 0x00000003, 0x00000000, 0x00000000,
     853                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     854                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     855                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     856                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     857                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     858                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     859                 :            : };
     860                 :            : 
     861                 :            : /* Packet types for AH */
     862                 :            : static const u32 ice_ptypes_ah[] = {
     863                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     864                 :            :         0x00000000, 0x0000000C, 0x00000000, 0x00000000,
     865                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     866                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     867                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     868                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     869                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     870                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     871                 :            : };
     872                 :            : 
     873                 :            : /* Packet types for packets with NAT_T ESP header */
     874                 :            : static const u32 ice_ptypes_nat_t_esp[] = {
     875                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     876                 :            :         0x00000000, 0x00000030, 0x00000000, 0x00000000,
     877                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     878                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     879                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     880                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     881                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     882                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     883                 :            : };
     884                 :            : 
     885                 :            : static const u32 ice_ptypes_mac_non_ip_ofos[] = {
     886                 :            :         0x00000846, 0x00000000, 0x00000000, 0x00000000,
     887                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     888                 :            :         0x00400000, 0x03FFF000, 0x00000000, 0x00000000,
     889                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     890                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     891                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     892                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     893                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     894                 :            : };
     895                 :            : 
     896                 :            : static const u32 ice_ptypes_gtpu_no_ip[] = {
     897                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     898                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     899                 :            :         0x00000000, 0x00000000, 0x00000600, 0x00000000,
     900                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     901                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     902                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     903                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     904                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     905                 :            : };
     906                 :            : 
     907                 :            : static const u32 ice_ptypes_ecpri_tp0[] = {
     908                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     909                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     910                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000400,
     911                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     912                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     913                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     914                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     915                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     916                 :            : };
     917                 :            : 
     918                 :            : static const u32 ice_ptypes_udp_ecpri_tp0[] = {
     919                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     920                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     921                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00100000,
     922                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     923                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     924                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     925                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     926                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     927                 :            : };
     928                 :            : 
     929                 :            : static const u32 ice_ptypes_l2tpv2[] = {
     930                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     931                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     932                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     933                 :            :         0xFFFFF000, 0x000003FF, 0x00000000, 0x00000000,
     934                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     935                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     936                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     937                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     938                 :            : };
     939                 :            : 
     940                 :            : static const u32 ice_ptypes_ppp[] = {
     941                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     942                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     943                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     944                 :            :         0xFFFF0000, 0x000003FF, 0x00000000, 0x00000000,
     945                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     946                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     947                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     948                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     949                 :            : };
     950                 :            : 
     951                 :            : static const u32 ice_ptypes_ipv4_frag[] = {
     952                 :            :         0x00400000, 0x00000000, 0x00000000, 0x00000000,
     953                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     954                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     955                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     956                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     957                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     958                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     959                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     960                 :            : };
     961                 :            : 
     962                 :            : static const u32 ice_ptypes_ipv6_frag[] = {
     963                 :            :         0x00000000, 0x00000000, 0x01000000, 0x00000000,
     964                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     965                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     966                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     967                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     968                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     969                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     970                 :            :         0x00000000, 0x00000000, 0x00000000, 0x00000000,
     971                 :            : };
     972                 :            : 
     973                 :            : /* Manage parameters and info. used during the creation of a flow profile */
     974                 :            : struct ice_flow_prof_params {
     975                 :            :         enum ice_block blk;
     976                 :            :         u16 entry_length; /* # of bytes formatted entry will require */
     977                 :            :         u8 es_cnt;
     978                 :            :         struct ice_flow_prof *prof;
     979                 :            : 
     980                 :            :         /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
     981                 :            :          * This will give us the direction flags.
     982                 :            :          */
     983                 :            :         struct ice_fv_word es[ICE_MAX_FV_WORDS];
     984                 :            :         /* attributes can be used to add attributes to a particular PTYPE */
     985                 :            :         const struct ice_ptype_attributes *attr;
     986                 :            :         u16 attr_cnt;
     987                 :            : 
     988                 :            :         u16 mask[ICE_MAX_FV_WORDS];
     989                 :            :         ice_declare_bitmap(ptypes, ICE_FLOW_PTYPE_MAX);
     990                 :            : };
     991                 :            : 
     992                 :            : #define ICE_FLOW_RSS_HDRS_INNER_MASK \
     993                 :            :         (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
     994                 :            :         ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
     995                 :            :         ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
     996                 :            :         ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
     997                 :            :         ICE_FLOW_SEG_HDR_NAT_T_ESP | ICE_FLOW_SEG_HDR_GTPU_NON_IP | \
     998                 :            :         ICE_FLOW_SEG_HDR_VXLAN | ICE_FLOW_SEG_HDR_GRE | \
     999                 :            :         ICE_FLOW_SEG_HDR_ECPRI_TP0 | ICE_FLOW_SEG_HDR_UDP_ECPRI_TP0 | \
    1000                 :            :         ICE_FLOW_SEG_HDR_L2TPV2 | ICE_FLOW_SEG_HDR_PPP)
    1001                 :            : 
    1002                 :            : #define ICE_FLOW_SEG_HDRS_L2_MASK       \
    1003                 :            :         (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
    1004                 :            : #define ICE_FLOW_SEG_HDRS_L3_MASK       \
    1005                 :            :         (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
    1006                 :            : #define ICE_FLOW_SEG_HDRS_L4_MASK       \
    1007                 :            :         (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
    1008                 :            :          ICE_FLOW_SEG_HDR_SCTP)
    1009                 :            : /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
    1010                 :            : #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER      \
    1011                 :            :         (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
    1012                 :            : 
    1013                 :            : /**
    1014                 :            :  * ice_flow_val_hdrs - validates packet segments for valid protocol headers
    1015                 :            :  * @segs: array of one or more packet segments that describe the flow
    1016                 :            :  * @segs_cnt: number of packet segments provided
    1017                 :            :  */
    1018                 :          0 : static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
    1019                 :            : {
    1020                 :            :         u8 i;
    1021                 :            : 
    1022         [ #  # ]:          0 :         for (i = 0; i < segs_cnt; i++) {
    1023                 :            :                 /* Multiple L3 headers */
    1024   [ #  #  #  # ]:          0 :                 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
    1025         [ #  # ]:          0 :                     !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
    1026                 :            :                         return ICE_ERR_PARAM;
    1027                 :            : 
    1028                 :            :                 /* Multiple L4 headers */
    1029   [ #  #  #  # ]:          0 :                 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
    1030         [ #  # ]:          0 :                     !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
    1031                 :            :                         return ICE_ERR_PARAM;
    1032                 :            :         }
    1033                 :            : 
    1034                 :            :         return 0;
    1035                 :            : }
    1036                 :            : 
    1037                 :            : /* Sizes of fixed known protocol headers without header options */
    1038                 :            : #define ICE_FLOW_PROT_HDR_SZ_MAC        14
    1039                 :            : #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN   (ICE_FLOW_PROT_HDR_SZ_MAC + 2)
    1040                 :            : #define ICE_FLOW_PROT_HDR_SZ_IPV4       20
    1041                 :            : #define ICE_FLOW_PROT_HDR_SZ_IPV6       40
    1042                 :            : #define ICE_FLOW_PROT_HDR_SZ_ARP        28
    1043                 :            : #define ICE_FLOW_PROT_HDR_SZ_ICMP       8
    1044                 :            : #define ICE_FLOW_PROT_HDR_SZ_TCP        20
    1045                 :            : #define ICE_FLOW_PROT_HDR_SZ_UDP        8
    1046                 :            : #define ICE_FLOW_PROT_HDR_SZ_SCTP       12
    1047                 :            : 
    1048                 :            : /**
    1049                 :            :  * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
    1050                 :            :  * @params: information about the flow to be processed
    1051                 :            :  * @seg: index of packet segment whose header size is to be determined
    1052                 :            :  */
    1053                 :          0 : static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
    1054                 :            : {
    1055                 :            :         u16 sz;
    1056                 :            : 
    1057                 :            :         /* L2 headers */
    1058         [ #  # ]:          0 :         sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
    1059                 :            :                 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
    1060                 :            : 
    1061                 :            :         /* L3 headers */
    1062         [ #  # ]:          0 :         if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
    1063                 :          0 :                 sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
    1064         [ #  # ]:          0 :         else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
    1065                 :          0 :                 sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
    1066         [ #  # ]:          0 :         else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
    1067                 :          0 :                 sz += ICE_FLOW_PROT_HDR_SZ_ARP;
    1068         [ #  # ]:          0 :         else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
    1069                 :            :                 /* An L3 header is required if L4 is specified */
    1070                 :            :                 return 0;
    1071                 :            : 
    1072                 :            :         /* L4 headers */
    1073         [ #  # ]:          0 :         if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
    1074                 :          0 :                 sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
    1075         [ #  # ]:          0 :         else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
    1076                 :          0 :                 sz += ICE_FLOW_PROT_HDR_SZ_TCP;
    1077         [ #  # ]:          0 :         else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
    1078                 :          0 :                 sz += ICE_FLOW_PROT_HDR_SZ_UDP;
    1079         [ #  # ]:          0 :         else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
    1080                 :          0 :                 sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
    1081                 :            : 
    1082                 :            :         return sz;
    1083                 :            : }
    1084                 :            : 
    1085                 :            : /**
    1086                 :            :  * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
    1087                 :            :  * @params: information about the flow to be processed
    1088                 :            :  *
    1089                 :            :  * This function identifies the packet types associated with the protocol
    1090                 :            :  * headers being present in packet segments of the specified flow profile.
    1091                 :            :  */
    1092                 :            : static int
    1093                 :          0 : ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
    1094                 :            : {
    1095                 :            :         struct ice_flow_prof *prof;
    1096                 :            :         u8 i;
    1097                 :            : 
    1098                 :          0 :         ice_memset(params->ptypes, 0xff, sizeof(params->ptypes),
    1099                 :            :                    ICE_NONDMA_MEM);
    1100                 :            : 
    1101                 :          0 :         prof = params->prof;
    1102                 :            : 
    1103         [ #  # ]:          0 :         for (i = 0; i < params->prof->segs_cnt; i++) {
    1104                 :            :                 const ice_bitmap_t *src;
    1105                 :            :                 u32 hdrs;
    1106                 :            : 
    1107                 :          0 :                 hdrs = prof->segs[i].hdrs;
    1108                 :            : 
    1109         [ #  # ]:          0 :                 if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
    1110         [ #  # ]:          0 :                         src = !i ? (const ice_bitmap_t *)ice_ptypes_mac_ofos :
    1111                 :            :                                 (const ice_bitmap_t *)ice_ptypes_mac_il;
    1112                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1113                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1114                 :            :                 }
    1115                 :            : 
    1116   [ #  #  #  # ]:          0 :                 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
    1117                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_macvlan_il;
    1118                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1119                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1120                 :            :                 }
    1121                 :            : 
    1122   [ #  #  #  # ]:          0 :                 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
    1123                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1124                 :            :                                        (const ice_bitmap_t *)ice_ptypes_arp_of,
    1125                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1126                 :            :                 }
    1127                 :            : 
    1128         [ #  # ]:          0 :                 if (hdrs & ICE_FLOW_SEG_HDR_ECPRI_TP0) {
    1129                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_ecpri_tp0;
    1130                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1131                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1132                 :            :                 }
    1133                 :            : 
    1134   [ #  #  #  # ]:          0 :                 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
    1135                 :            :                     (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
    1136         [ #  # ]:          0 :                         src = i ? (const ice_bitmap_t *)ice_ptypes_ipv4_il :
    1137                 :            :                                 (const ice_bitmap_t *)ice_ptypes_ipv4_ofos_all;
    1138                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1139                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1140   [ #  #  #  # ]:          0 :                 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
    1141                 :            :                            (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
    1142         [ #  # ]:          0 :                         src = i ? (const ice_bitmap_t *)ice_ptypes_ipv6_il :
    1143                 :            :                                 (const ice_bitmap_t *)ice_ptypes_ipv6_ofos_all;
    1144                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1145                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1146         [ #  # ]:          0 :                 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
    1147                 :            :                                 (hdrs & ICE_FLOW_SEG_HDR_IPV_FRAG)) {
    1148                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_ipv4_frag;
    1149                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1150                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1151         [ #  # ]:          0 :                 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
    1152                 :            :                                 (hdrs & ICE_FLOW_SEG_HDR_IPV_FRAG)) {
    1153                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_ipv6_frag;
    1154                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1155                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1156         [ #  # ]:          0 :                 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
    1157                 :            :                            !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
    1158         [ #  # ]:          0 :                         src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv4_ofos_no_l4 :
    1159                 :            :                                 (const ice_bitmap_t *)ice_ptypes_ipv4_il_no_l4;
    1160                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1161                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1162         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
    1163         [ #  # ]:          0 :                         src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv4_ofos :
    1164                 :            :                                 (const ice_bitmap_t *)ice_ptypes_ipv4_il;
    1165                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1166                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1167         [ #  # ]:          0 :                 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
    1168                 :            :                            !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
    1169         [ #  # ]:          0 :                         src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv6_ofos_no_l4 :
    1170                 :            :                                 (const ice_bitmap_t *)ice_ptypes_ipv6_il_no_l4;
    1171                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1172                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1173         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
    1174         [ #  # ]:          0 :                         src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv6_ofos :
    1175                 :            :                                 (const ice_bitmap_t *)ice_ptypes_ipv6_il;
    1176                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1177                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1178                 :            :                 }
    1179                 :            : 
    1180         [ #  # ]:          0 :                 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
    1181                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_mac_non_ip_ofos;
    1182                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1183                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1184         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
    1185                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_pppoe;
    1186                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1187                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1188                 :            :                 } else {
    1189                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_pppoe;
    1190                 :          0 :                         ice_andnot_bitmap(params->ptypes, params->ptypes, src,
    1191                 :            :                                           ICE_FLOW_PTYPE_MAX);
    1192                 :            :                 }
    1193                 :            : 
    1194         [ #  # ]:          0 :                 if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
    1195                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_udp_il;
    1196                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1197                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1198         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
    1199                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1200                 :            :                                        (const ice_bitmap_t *)ice_ptypes_tcp_il,
    1201                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1202         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
    1203                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_sctp_il;
    1204                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1205                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1206                 :            :                 }
    1207                 :            : 
    1208         [ #  # ]:          0 :                 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
    1209         [ #  # ]:          0 :                         src = !i ? (const ice_bitmap_t *)ice_ptypes_icmp_of :
    1210                 :            :                                 (const ice_bitmap_t *)ice_ptypes_icmp_il;
    1211                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1212                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1213         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
    1214                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_gre_of;
    1215                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes, src,
    1216                 :            :                                        ICE_FLOW_PTYPE_MAX);
    1217         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
    1218                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_gtpc;
    1219                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1220                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1221         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
    1222                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_gtpc_tid;
    1223                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1224                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1225         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_NON_IP) {
    1226                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_gtpu_no_ip;
    1227                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1228                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1229         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
    1230                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_gtpu;
    1231                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1232                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1233                 :            : 
    1234                 :            :                         /* Attributes for GTP packet with downlink */
    1235                 :          0 :                         params->attr = ice_attr_gtpu_down;
    1236                 :          0 :                         params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
    1237         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
    1238                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_gtpu;
    1239                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1240                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1241                 :            : 
    1242                 :            :                         /* Attributes for GTP packet with uplink */
    1243                 :          0 :                         params->attr = ice_attr_gtpu_up;
    1244                 :          0 :                         params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
    1245         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
    1246                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_gtpu;
    1247                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1248                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1249                 :            : 
    1250                 :            :                         /* Attributes for GTP packet with Extension Header */
    1251                 :          0 :                         params->attr = ice_attr_gtpu_eh;
    1252                 :          0 :                         params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
    1253         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
    1254                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_gtpu;
    1255                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1256                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1257                 :            : 
    1258                 :            :                         /* Attributes for GTP packet without Extension Header */
    1259                 :          0 :                         params->attr = ice_attr_gtpu_session;
    1260                 :          0 :                         params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
    1261         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV2) {
    1262                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_l2tpv2;
    1263                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1264                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1265         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
    1266                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_l2tpv3;
    1267                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1268                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1269         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
    1270                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_esp;
    1271                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1272                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1273         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
    1274                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_ah;
    1275                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1276                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1277         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
    1278                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_nat_t_esp;
    1279                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1280                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1281         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_VXLAN) {
    1282                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_vxlan_vni;
    1283                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1284                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1285         [ #  # ]:          0 :                 } else if (hdrs & ICE_FLOW_SEG_HDR_UDP_ECPRI_TP0) {
    1286                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_udp_ecpri_tp0;
    1287                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1288                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1289                 :            :                 }
    1290                 :            : 
    1291         [ #  # ]:          0 :                 if (hdrs & ICE_FLOW_SEG_HDR_PPP) {
    1292                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_ppp;
    1293                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1294                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1295                 :            :                 }
    1296                 :            : 
    1297         [ #  # ]:          0 :                 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
    1298         [ #  # ]:          0 :                         if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
    1299                 :            :                                 src = (const ice_bitmap_t *)ice_ptypes_pfcp_node;
    1300                 :            :                         else
    1301                 :            :                                 src = (const ice_bitmap_t *)ice_ptypes_pfcp_session;
    1302                 :            : 
    1303                 :          0 :                         ice_and_bitmap(params->ptypes, params->ptypes,
    1304                 :            :                                        src, ICE_FLOW_PTYPE_MAX);
    1305                 :            :                 } else {
    1306                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_pfcp_node;
    1307                 :          0 :                         ice_andnot_bitmap(params->ptypes, params->ptypes,
    1308                 :            :                                           src, ICE_FLOW_PTYPE_MAX);
    1309                 :            : 
    1310                 :            :                         src = (const ice_bitmap_t *)ice_ptypes_pfcp_session;
    1311                 :          0 :                         ice_andnot_bitmap(params->ptypes, params->ptypes,
    1312                 :            :                                           src, ICE_FLOW_PTYPE_MAX);
    1313                 :            :                 }
    1314                 :            :         }
    1315                 :            : 
    1316                 :          0 :         return 0;
    1317                 :            : }
    1318                 :            : 
    1319                 :            : /**
    1320                 :            :  * ice_flow_xtract_pkt_flags - Create an extr sequence entry for packet flags
    1321                 :            :  * @hw: pointer to the HW struct
    1322                 :            :  * @params: information about the flow to be processed
    1323                 :            :  * @flags: The value of pkt_flags[x:x] in Rx/Tx MDID metadata.
    1324                 :            :  *
    1325                 :            :  * This function will allocate an extraction sequence entries for a DWORD size
    1326                 :            :  * chunk of the packet flags.
    1327                 :            :  */
    1328                 :            : static int
    1329                 :            : ice_flow_xtract_pkt_flags(struct ice_hw *hw,
    1330                 :            :                           struct ice_flow_prof_params *params,
    1331                 :            :                           enum ice_flex_mdid_pkt_flags flags)
    1332                 :            : {
    1333                 :          0 :         u8 fv_words = (u8)hw->blk[params->blk].es.fvw;
    1334                 :            :         u8 idx;
    1335                 :            : 
    1336                 :            :         /* Make sure the number of extraction sequence entries required does not
    1337                 :            :          * exceed the block's capacity.
    1338                 :            :          */
    1339         [ #  # ]:          0 :         if (params->es_cnt >= fv_words)
    1340                 :            :                 return ICE_ERR_MAX_LIMIT;
    1341                 :            : 
    1342                 :            :         /* some blocks require a reversed field vector layout */
    1343         [ #  # ]:          0 :         if (hw->blk[params->blk].es.reverse)
    1344                 :          0 :                 idx = fv_words - params->es_cnt - 1;
    1345                 :            :         else
    1346                 :            :                 idx = params->es_cnt;
    1347                 :            : 
    1348                 :          0 :         params->es[idx].prot_id = ICE_PROT_META_ID;
    1349                 :          0 :         params->es[idx].off = (u16)flags;
    1350                 :          0 :         params->es_cnt++;
    1351                 :            : 
    1352                 :            :         return 0;
    1353                 :            : }
    1354                 :            : 
    1355                 :            : /**
    1356                 :            :  * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
    1357                 :            :  * @hw: pointer to the HW struct
    1358                 :            :  * @params: information about the flow to be processed
    1359                 :            :  * @seg: packet segment index of the field to be extracted
    1360                 :            :  * @fld: ID of field to be extracted
    1361                 :            :  * @match: bitfield of all fields
    1362                 :            :  *
    1363                 :            :  * This function determines the protocol ID, offset, and size of the given
    1364                 :            :  * field. It then allocates one or more extraction sequence entries for the
    1365                 :            :  * given field, and fill the entries with protocol ID and offset information.
    1366                 :            :  */
    1367                 :            : static int
    1368                 :          0 : ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
    1369                 :            :                     u8 seg, enum ice_flow_field fld, ice_bitmap_t *match)
    1370                 :            : {
    1371                 :            :         enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
    1372                 :          0 :         u8 fv_words = (u8)hw->blk[params->blk].es.fvw;
    1373                 :            :         enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
    1374                 :            :         struct ice_flow_fld_info *flds;
    1375                 :            :         u16 cnt, ese_bits, i;
    1376                 :            :         u16 sib_mask = 0;
    1377                 :            :         u16 mask;
    1378                 :            :         u16 off;
    1379                 :            :         bool exist;
    1380                 :            : 
    1381                 :          0 :         flds = params->prof->segs[seg].fields;
    1382                 :            : 
    1383   [ #  #  #  #  :          0 :         switch (fld) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1384                 :          0 :         case ICE_FLOW_FIELD_IDX_ETH_DA:
    1385                 :            :         case ICE_FLOW_FIELD_IDX_ETH_SA:
    1386                 :            :         case ICE_FLOW_FIELD_IDX_S_VLAN:
    1387                 :            :         case ICE_FLOW_FIELD_IDX_C_VLAN:
    1388         [ #  # ]:          0 :                 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
    1389                 :            :                 break;
    1390                 :          0 :         case ICE_FLOW_FIELD_IDX_ETH_TYPE:
    1391         [ #  # ]:          0 :                 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
    1392                 :            :                 break;
    1393                 :          0 :         case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
    1394         [ #  # ]:          0 :                 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
    1395                 :            :                 break;
    1396                 :          0 :         case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
    1397         [ #  # ]:          0 :                 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
    1398                 :            :                 break;
    1399                 :          0 :         case ICE_FLOW_FIELD_IDX_IPV4_TTL:
    1400                 :            :         case ICE_FLOW_FIELD_IDX_IPV4_PROT:
    1401         [ #  # ]:          0 :                 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
    1402         [ #  # ]:          0 :                 if (params->prof->segs[0].hdrs & ICE_FLOW_SEG_HDR_GRE &&
    1403   [ #  #  #  # ]:          0 :                     params->prof->segs[1].hdrs & ICE_FLOW_SEG_HDR_GTPU &&
    1404                 :            :                     seg == 1)
    1405                 :            :                         prot_id = ICE_PROT_IPV4_IL_IL;
    1406                 :            :                 /* TTL and PROT share the same extraction seq. entry.
    1407                 :            :                  * Each is considered a sibling to the other in terms of sharing
    1408                 :            :                  * the same extraction sequence entry.
    1409                 :            :                  */
    1410         [ #  # ]:          0 :                 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
    1411                 :            :                         sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
    1412                 :            :                 else
    1413                 :            :                         sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
    1414                 :            : 
    1415                 :            :                 /* If the sibling field is also included, that field's
    1416                 :            :                  * mask needs to be included.
    1417                 :            :                  */
    1418         [ #  # ]:          0 :                 if (ice_is_bit_set(match, sib))
    1419                 :          0 :                         sib_mask = ice_flds_info[sib].mask;
    1420                 :            :                 break;
    1421                 :          0 :         case ICE_FLOW_FIELD_IDX_IPV6_TTL:
    1422                 :            :         case ICE_FLOW_FIELD_IDX_IPV6_PROT:
    1423                 :            :                 prot_id = ICE_PROT_IPV6_NEXT_PROTO;
    1424                 :          0 :                 exist = ice_check_ddp_support_proto_id(hw, prot_id);
    1425         [ #  # ]:          0 :                 if (!exist)
    1426                 :            :                         prot_id = seg == 0 ?
    1427         [ #  # ]:          0 :                                   ICE_PROT_IPV6_OF_OR_S :
    1428                 :            :                                   ICE_PROT_IPV6_IL;
    1429                 :            :                 else
    1430                 :            :                         prot_id = seg == 0 ?
    1431         [ #  # ]:          0 :                                   ICE_PROT_IPV6_NEXT_PROTO :
    1432                 :            :                                   ICE_PROT_IPV6_IL;
    1433         [ #  # ]:          0 :                 if (params->prof->segs[0].hdrs & ICE_FLOW_SEG_HDR_GRE &&
    1434   [ #  #  #  # ]:          0 :                     params->prof->segs[1].hdrs & ICE_FLOW_SEG_HDR_GTPU &&
    1435                 :            :                     seg == 1)
    1436                 :            :                         prot_id = ICE_PROT_IPV6_IL_IL;
    1437                 :            :                 /* TTL and PROT share the same extraction seq. entry.
    1438                 :            :                  * Each is considered a sibling to the other in terms of sharing
    1439                 :            :                  * the same extraction sequence entry.
    1440                 :            :                  */
    1441         [ #  # ]:          0 :                 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
    1442                 :            :                         sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
    1443                 :            :                 else
    1444                 :            :                         sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
    1445                 :            : 
    1446                 :            :                 /* If the sibling field is also included, that field's
    1447                 :            :                  * mask needs to be included.
    1448                 :            :                  */
    1449         [ #  # ]:          0 :                 if (ice_is_bit_set(match, sib))
    1450                 :          0 :                         sib_mask = ice_flds_info[sib].mask;
    1451                 :            :                 break;
    1452                 :          0 :         case ICE_FLOW_FIELD_IDX_IPV4_SA:
    1453                 :            :         case ICE_FLOW_FIELD_IDX_IPV4_DA:
    1454                 :            :         case ICE_FLOW_FIELD_IDX_IPV4_CHKSUM:
    1455         [ #  # ]:          0 :                 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
    1456         [ #  # ]:          0 :                 if (params->prof->segs[0].hdrs & ICE_FLOW_SEG_HDR_GRE &&
    1457   [ #  #  #  # ]:          0 :                     params->prof->segs[1].hdrs & ICE_FLOW_SEG_HDR_GTPU &&
    1458                 :            :                     seg == 1)
    1459                 :            :                         prot_id = ICE_PROT_IPV4_IL_IL;
    1460                 :            :                 break;
    1461                 :            :         case ICE_FLOW_FIELD_IDX_IPV4_ID:
    1462                 :            :                 prot_id = ICE_PROT_IPV4_OF_OR_S;
    1463                 :            :                 break;
    1464                 :          0 :         case ICE_FLOW_FIELD_IDX_IPV6_SA:
    1465                 :            :         case ICE_FLOW_FIELD_IDX_IPV6_DA:
    1466                 :            :         case ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA:
    1467                 :            :         case ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA:
    1468                 :            :         case ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA:
    1469                 :            :         case ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA:
    1470                 :            :         case ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA:
    1471                 :            :         case ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA:
    1472         [ #  # ]:          0 :                 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
    1473         [ #  # ]:          0 :                 if (params->prof->segs[0].hdrs & ICE_FLOW_SEG_HDR_GRE &&
    1474   [ #  #  #  # ]:          0 :                     params->prof->segs[1].hdrs & ICE_FLOW_SEG_HDR_GTPU &&
    1475                 :            :                     seg == 1)
    1476                 :            :                         prot_id = ICE_PROT_IPV6_IL_IL;
    1477                 :            :                 break;
    1478                 :          0 :         case ICE_FLOW_FIELD_IDX_IPV6_ID:
    1479                 :            :                 prot_id = ICE_PROT_IPV6_FRAG;
    1480                 :          0 :                 break;
    1481                 :          0 :         case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
    1482                 :            :         case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
    1483                 :            :         case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
    1484                 :            :         case ICE_FLOW_FIELD_IDX_TCP_CHKSUM:
    1485                 :            :                 prot_id = ICE_PROT_TCP_IL;
    1486                 :          0 :                 break;
    1487                 :          0 :         case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
    1488                 :            :         case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
    1489                 :            :         case ICE_FLOW_FIELD_IDX_UDP_CHKSUM:
    1490                 :            :                 prot_id = ICE_PROT_UDP_IL_OR_S;
    1491                 :          0 :                 break;
    1492                 :          0 :         case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
    1493                 :            :         case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
    1494                 :            :         case ICE_FLOW_FIELD_IDX_SCTP_CHKSUM:
    1495                 :            :                 prot_id = ICE_PROT_SCTP_IL;
    1496                 :          0 :                 break;
    1497                 :          0 :         case ICE_FLOW_FIELD_IDX_VXLAN_VNI:
    1498                 :            :         case ICE_FLOW_FIELD_IDX_GTPC_TEID:
    1499                 :            :         case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
    1500                 :            :         case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
    1501                 :            :         case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
    1502                 :            :         case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
    1503                 :            :         case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
    1504                 :            :         case ICE_FLOW_FIELD_IDX_GTPU_UP_QFI:
    1505                 :            :         case ICE_FLOW_FIELD_IDX_GTPU_DWN_QFI:
    1506                 :            :         case ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID:
    1507                 :            :         case ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID:
    1508                 :            :                 /* GTP is accessed through UDP OF protocol */
    1509                 :            :                 prot_id = ICE_PROT_UDP_OF;
    1510                 :          0 :                 break;
    1511                 :          0 :         case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
    1512                 :            :                 prot_id = ICE_PROT_PPPOE;
    1513                 :          0 :                 break;
    1514                 :          0 :         case ICE_FLOW_FIELD_IDX_PFCP_SEID:
    1515                 :            :                 prot_id = ICE_PROT_UDP_IL_OR_S;
    1516                 :          0 :                 break;
    1517                 :          0 :         case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
    1518                 :            :                 prot_id = ICE_PROT_L2TPV3;
    1519                 :          0 :                 break;
    1520                 :          0 :         case ICE_FLOW_FIELD_IDX_ESP_SPI:
    1521                 :            :                 prot_id = ICE_PROT_ESP_F;
    1522                 :          0 :                 break;
    1523                 :          0 :         case ICE_FLOW_FIELD_IDX_AH_SPI:
    1524                 :            :                 prot_id = ICE_PROT_ESP_2;
    1525                 :          0 :                 break;
    1526                 :          0 :         case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
    1527                 :            :                 prot_id = ICE_PROT_UDP_IL_OR_S;
    1528                 :          0 :                 break;
    1529                 :          0 :         case ICE_FLOW_FIELD_IDX_ECPRI_TP0_PC_ID:
    1530                 :            :                 prot_id = ICE_PROT_ECPRI;
    1531                 :          0 :                 break;
    1532                 :          0 :         case ICE_FLOW_FIELD_IDX_UDP_ECPRI_TP0_PC_ID:
    1533                 :            :                 prot_id = ICE_PROT_UDP_IL_OR_S;
    1534                 :          0 :                 break;
    1535                 :          0 :         case ICE_FLOW_FIELD_IDX_ARP_SIP:
    1536                 :            :         case ICE_FLOW_FIELD_IDX_ARP_DIP:
    1537                 :            :         case ICE_FLOW_FIELD_IDX_ARP_SHA:
    1538                 :            :         case ICE_FLOW_FIELD_IDX_ARP_DHA:
    1539                 :            :         case ICE_FLOW_FIELD_IDX_ARP_OP:
    1540                 :            :                 prot_id = ICE_PROT_ARP_OF;
    1541                 :          0 :                 break;
    1542                 :          0 :         case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
    1543                 :            :         case ICE_FLOW_FIELD_IDX_ICMP_CODE:
    1544                 :            :                 /* ICMP type and code share the same extraction seq. entry */
    1545                 :          0 :                 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
    1546         [ #  # ]:          0 :                         ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
    1547                 :            :                 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
    1548         [ #  # ]:          0 :                         ICE_FLOW_FIELD_IDX_ICMP_CODE :
    1549                 :            :                         ICE_FLOW_FIELD_IDX_ICMP_TYPE;
    1550                 :            :                 break;
    1551                 :          0 :         case ICE_FLOW_FIELD_IDX_GRE_KEYID:
    1552                 :            :                 prot_id = ICE_PROT_GRE_OF;
    1553                 :          0 :                 break;
    1554                 :            :         default:
    1555                 :            :                 return ICE_ERR_NOT_IMPL;
    1556                 :            :         }
    1557                 :            : 
    1558                 :            :         /* Each extraction sequence entry is a word in size, and extracts a
    1559                 :            :          * word-aligned offset from a protocol header.
    1560                 :            :          */
    1561                 :            :         ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
    1562                 :            : 
    1563                 :          0 :         flds[fld].xtrct.prot_id = (u8)prot_id;
    1564                 :          0 :         flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
    1565                 :            :                 ICE_FLOW_FV_EXTRACT_SZ;
    1566                 :          0 :         flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
    1567                 :          0 :         flds[fld].xtrct.idx = params->es_cnt;
    1568                 :          0 :         flds[fld].xtrct.mask = ice_flds_info[fld].mask;
    1569         [ #  # ]:          0 :         if (prot_id == ICE_PROT_IPV6_NEXT_PROTO) {
    1570                 :          0 :                 flds[fld].xtrct.off = 0;
    1571                 :          0 :                 flds[fld].xtrct.disp = 0;
    1572                 :            :         }
    1573                 :            : 
    1574                 :            :         /* Adjust the next field-entry index after accommodating the number of
    1575                 :            :          * entries this field consumes
    1576                 :            :          */
    1577                 :          0 :         cnt = DIVIDE_AND_ROUND_UP(flds[fld].xtrct.disp +
    1578                 :            :                                   ice_flds_info[fld].size, ese_bits);
    1579                 :            : 
    1580                 :            :         /* Fill in the extraction sequence entries needed for this field */
    1581                 :          0 :         off = flds[fld].xtrct.off;
    1582                 :            :         mask = flds[fld].xtrct.mask;
    1583         [ #  # ]:          0 :         for (i = 0; i < cnt; i++) {
    1584                 :            :                 /* Only consume an extraction sequence entry if there is no
    1585                 :            :                  * sibling field associated with this field or the sibling entry
    1586                 :            :                  * already extracts the word shared with this field.
    1587                 :            :                  */
    1588         [ #  # ]:          0 :                 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
    1589         [ #  # ]:          0 :                     flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
    1590         [ #  # ]:          0 :                     flds[sib].xtrct.off != off) {
    1591                 :            :                         u8 idx;
    1592                 :            : 
    1593                 :            :                         /* Make sure the number of extraction sequence required
    1594                 :            :                          * does not exceed the block's capability
    1595                 :            :                          */
    1596         [ #  # ]:          0 :                         if (params->es_cnt >= fv_words)
    1597                 :            :                                 return ICE_ERR_MAX_LIMIT;
    1598                 :            : 
    1599                 :            :                         /* some blocks require a reversed field vector layout */
    1600         [ #  # ]:          0 :                         if (hw->blk[params->blk].es.reverse)
    1601                 :          0 :                                 idx = fv_words - params->es_cnt - 1;
    1602                 :            :                         else
    1603                 :            :                                 idx = params->es_cnt;
    1604                 :            : 
    1605                 :          0 :                         params->es[idx].prot_id = (u8)prot_id;
    1606                 :          0 :                         params->es[idx].off = off;
    1607                 :          0 :                         params->mask[idx] = mask | sib_mask;
    1608                 :          0 :                         params->es_cnt++;
    1609                 :            :                 }
    1610                 :            : 
    1611                 :          0 :                 off += ICE_FLOW_FV_EXTRACT_SZ;
    1612                 :            :         }
    1613                 :            : 
    1614                 :            :         return 0;
    1615                 :            : }
    1616                 :            : 
    1617                 :            : /**
    1618                 :            :  * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
    1619                 :            :  * @hw: pointer to the HW struct
    1620                 :            :  * @params: information about the flow to be processed
    1621                 :            :  * @seg: index of packet segment whose raw fields are to be extracted
    1622                 :            :  */
    1623                 :            : static int
    1624                 :          0 : ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
    1625                 :            :                      u8 seg)
    1626                 :            : {
    1627                 :            :         u16 fv_words;
    1628                 :            :         u16 hdrs_sz;
    1629                 :            :         u8 i;
    1630                 :            : 
    1631         [ #  # ]:          0 :         if (!params->prof->segs[seg].raws_cnt)
    1632                 :            :                 return 0;
    1633                 :            : 
    1634         [ #  # ]:          0 :         if (params->prof->segs[seg].raws_cnt >
    1635                 :            :             ARRAY_SIZE(params->prof->segs[seg].raws))
    1636                 :            :                 return ICE_ERR_MAX_LIMIT;
    1637                 :            : 
    1638                 :            :         /* Offsets within the segment headers are not supported */
    1639                 :          0 :         hdrs_sz = ice_flow_calc_seg_sz(params, seg);
    1640         [ #  # ]:          0 :         if (!hdrs_sz)
    1641                 :            :                 return ICE_ERR_PARAM;
    1642                 :            : 
    1643                 :          0 :         fv_words = hw->blk[params->blk].es.fvw;
    1644                 :            : 
    1645         [ #  # ]:          0 :         for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
    1646                 :            :                 struct ice_flow_seg_fld_raw *raw;
    1647                 :            :                 u16 off, cnt, j;
    1648                 :            : 
    1649                 :          0 :                 raw = &params->prof->segs[seg].raws[i];
    1650                 :            : 
    1651                 :            :                 /* Storing extraction information */
    1652                 :          0 :                 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
    1653                 :          0 :                 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
    1654                 :            :                         ICE_FLOW_FV_EXTRACT_SZ;
    1655                 :          0 :                 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
    1656                 :            :                         BITS_PER_BYTE;
    1657                 :          0 :                 raw->info.xtrct.idx = params->es_cnt;
    1658                 :            : 
    1659                 :            :                 /* Determine the number of field vector entries this raw field
    1660                 :            :                  * consumes.
    1661                 :            :                  */
    1662                 :          0 :                 cnt = DIVIDE_AND_ROUND_UP(raw->info.xtrct.disp +
    1663                 :            :                                           (raw->info.src.last * BITS_PER_BYTE),
    1664                 :            :                                           (ICE_FLOW_FV_EXTRACT_SZ *
    1665                 :            :                                            BITS_PER_BYTE));
    1666                 :            :                 off = raw->info.xtrct.off;
    1667         [ #  # ]:          0 :                 for (j = 0; j < cnt; j++) {
    1668                 :            :                         u16 idx;
    1669                 :            : 
    1670                 :            :                         /* Make sure the number of extraction sequence required
    1671                 :            :                          * does not exceed the block's capability
    1672                 :            :                          */
    1673   [ #  #  #  # ]:          0 :                         if (params->es_cnt >= hw->blk[params->blk].es.count ||
    1674                 :            :                             params->es_cnt >= ICE_MAX_FV_WORDS)
    1675                 :            :                                 return ICE_ERR_MAX_LIMIT;
    1676                 :            : 
    1677                 :            :                         /* some blocks require a reversed field vector layout */
    1678         [ #  # ]:          0 :                         if (hw->blk[params->blk].es.reverse)
    1679                 :          0 :                                 idx = fv_words - params->es_cnt - 1;
    1680                 :            :                         else
    1681                 :            :                                 idx = params->es_cnt;
    1682                 :            : 
    1683                 :          0 :                         params->es[idx].prot_id = raw->info.xtrct.prot_id;
    1684                 :          0 :                         params->es[idx].off = off;
    1685                 :          0 :                         params->es_cnt++;
    1686                 :          0 :                         off += ICE_FLOW_FV_EXTRACT_SZ;
    1687                 :            :                 }
    1688                 :            :         }
    1689                 :            : 
    1690                 :            :         return 0;
    1691                 :            : }
    1692                 :            : 
    1693                 :            : /**
    1694                 :            :  * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
    1695                 :            :  * @hw: pointer to the HW struct
    1696                 :            :  * @params: information about the flow to be processed
    1697                 :            :  *
    1698                 :            :  * This function iterates through all matched fields in the given segments, and
    1699                 :            :  * creates an extraction sequence for the fields.
    1700                 :            :  */
    1701                 :            : static int
    1702                 :          0 : ice_flow_create_xtrct_seq(struct ice_hw *hw,
    1703                 :            :                           struct ice_flow_prof_params *params)
    1704                 :            : {
    1705                 :            :         int status = 0;
    1706                 :            :         u8 i;
    1707                 :            : 
    1708                 :            :         /* For ACL, we also need to extract the direction bit (Rx,Tx) data from
    1709                 :            :          * packet flags
    1710                 :            :          */
    1711         [ #  # ]:          0 :         if (params->blk == ICE_BLK_ACL) {
    1712                 :            :                 status = ice_flow_xtract_pkt_flags(hw, params,
    1713                 :            :                                                    ICE_RX_MDID_PKT_FLAGS_15_0);
    1714                 :            :                 if (status)
    1715                 :            :                         return status;
    1716                 :            :         }
    1717                 :            : 
    1718         [ #  # ]:          0 :         for (i = 0; i < params->prof->segs_cnt; i++) {
    1719                 :            :                 ice_declare_bitmap(match, ICE_FLOW_FIELD_IDX_MAX);
    1720                 :            :                 enum ice_flow_field j;
    1721                 :            : 
    1722                 :          0 :                 ice_cp_bitmap(match, params->prof->segs[i].match,
    1723                 :            :                               ICE_FLOW_FIELD_IDX_MAX);
    1724         [ #  # ]:          0 :                 ice_for_each_set_bit(j, match, ICE_FLOW_FIELD_IDX_MAX) {
    1725                 :          0 :                         status = ice_flow_xtract_fld(hw, params, i, j, match);
    1726         [ #  # ]:          0 :                         if (status)
    1727                 :          0 :                                 return status;
    1728                 :          0 :                         ice_clear_bit(j, match);
    1729                 :            :                 }
    1730                 :            : 
    1731                 :            :                 /* Process raw matching bytes */
    1732                 :          0 :                 status = ice_flow_xtract_raws(hw, params, i);
    1733         [ #  # ]:          0 :                 if (status)
    1734                 :          0 :                         return status;
    1735                 :            :         }
    1736                 :            : 
    1737                 :            :         return status;
    1738                 :            : }
    1739                 :            : 
    1740                 :            : /**
    1741                 :            :  * ice_flow_sel_acl_scen - returns the specific scenario
    1742                 :            :  * @hw: pointer to the hardware structure
    1743                 :            :  * @params: information about the flow to be processed
    1744                 :            :  *
    1745                 :            :  * This function will return the specific scenario based on the
    1746                 :            :  * params passed to it
    1747                 :            :  */
    1748                 :            : static int
    1749                 :          0 : ice_flow_sel_acl_scen(struct ice_hw *hw, struct ice_flow_prof_params *params)
    1750                 :            : {
    1751                 :            :         /* Find the best-fit scenario for the provided match width */
    1752                 :            :         struct ice_acl_scen *cand_scen = NULL, *scen;
    1753                 :            : 
    1754         [ #  # ]:          0 :         if (!hw->acl_tbl)
    1755                 :            :                 return ICE_ERR_DOES_NOT_EXIST;
    1756                 :            : 
    1757                 :            :         /* Loop through each scenario and match against the scenario width
    1758                 :            :          * to select the specific scenario
    1759                 :            :          */
    1760   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY(scen, &hw->acl_tbl->scens, ice_acl_scen, list_entry)
                   #  # ]
    1761   [ #  #  #  # ]:          0 :                 if (scen->eff_width >= params->entry_length &&
    1762         [ #  # ]:          0 :                     (!cand_scen || cand_scen->eff_width > scen->eff_width))
    1763                 :            :                         cand_scen = scen;
    1764         [ #  # ]:          0 :         if (!cand_scen)
    1765                 :            :                 return ICE_ERR_DOES_NOT_EXIST;
    1766                 :            : 
    1767                 :          0 :         params->prof->cfg.scen = cand_scen;
    1768                 :            : 
    1769                 :          0 :         return 0;
    1770                 :            : }
    1771                 :            : 
    1772                 :            : /**
    1773                 :            :  * ice_flow_acl_def_entry_frmt - Determine the layout of flow entries
    1774                 :            :  * @params: information about the flow to be processed
    1775                 :            :  */
    1776                 :            : static int
    1777                 :          0 : ice_flow_acl_def_entry_frmt(struct ice_flow_prof_params *params)
    1778                 :            : {
    1779                 :            :         u16 index, i, range_idx = 0;
    1780                 :            : 
    1781                 :            :         index = ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
    1782                 :            : 
    1783         [ #  # ]:          0 :         for (i = 0; i < params->prof->segs_cnt; i++) {
    1784                 :          0 :                 struct ice_flow_seg_info *seg = &params->prof->segs[i];
    1785                 :            :                 u16 j;
    1786                 :            : 
    1787         [ #  # ]:          0 :                 ice_for_each_set_bit(j, seg->match,
    1788                 :            :                                      (u16)ICE_FLOW_FIELD_IDX_MAX) {
    1789                 :          0 :                         struct ice_flow_fld_info *fld = &seg->fields[j];
    1790                 :            : 
    1791                 :          0 :                         fld->entry.mask = ICE_FLOW_FLD_OFF_INVAL;
    1792                 :            : 
    1793         [ #  # ]:          0 :                         if (fld->type == ICE_FLOW_FLD_TYPE_RANGE) {
    1794                 :          0 :                                 fld->entry.last = ICE_FLOW_FLD_OFF_INVAL;
    1795                 :            : 
    1796                 :            :                                 /* Range checking only supported for single
    1797                 :            :                                  * words
    1798                 :            :                                  */
    1799         [ #  # ]:          0 :                                 if (DIVIDE_AND_ROUND_UP(ice_flds_info[j].size +
    1800                 :            :                                                         fld->xtrct.disp,
    1801                 :            :                                                         BITS_PER_BYTE * 2) > 1)
    1802                 :            :                                         return ICE_ERR_PARAM;
    1803                 :            : 
    1804                 :            :                                 /* Ranges must define low and high values */
    1805         [ #  # ]:          0 :                                 if (fld->src.val == ICE_FLOW_FLD_OFF_INVAL ||
    1806         [ #  # ]:          0 :                                     fld->src.last == ICE_FLOW_FLD_OFF_INVAL)
    1807                 :            :                                         return ICE_ERR_PARAM;
    1808                 :            : 
    1809                 :          0 :                                 fld->entry.val = range_idx++;
    1810                 :            :                         } else {
    1811                 :            :                                 /* Store adjusted byte-length of field for later
    1812                 :            :                                  * use, taking into account potential
    1813                 :            :                                  * non-byte-aligned displacement
    1814                 :            :                                  */
    1815                 :          0 :                                 fld->entry.last = DIVIDE_AND_ROUND_UP
    1816                 :            :                                         (ice_flds_info[j].size +
    1817                 :            :                                          (fld->xtrct.disp % BITS_PER_BYTE),
    1818                 :            :                                          BITS_PER_BYTE);
    1819                 :          0 :                                 fld->entry.val = index;
    1820                 :          0 :                                 index += fld->entry.last;
    1821                 :            :                         }
    1822                 :            :                 }
    1823                 :            : 
    1824         [ #  # ]:          0 :                 for (j = 0; j < seg->raws_cnt; j++) {
    1825                 :          0 :                         struct ice_flow_seg_fld_raw *raw = &seg->raws[j];
    1826                 :            : 
    1827                 :          0 :                         raw->info.entry.mask = ICE_FLOW_FLD_OFF_INVAL;
    1828                 :          0 :                         raw->info.entry.val = index;
    1829                 :          0 :                         raw->info.entry.last = raw->info.src.last;
    1830                 :          0 :                         index += raw->info.entry.last;
    1831                 :            :                 }
    1832                 :            :         }
    1833                 :            : 
    1834                 :            :         /* Currently only support using the byte selection base, which only
    1835                 :            :          * allows for an effective entry size of 30 bytes. Reject anything
    1836                 :            :          * larger.
    1837                 :            :          */
    1838         [ #  # ]:          0 :         if (index > ICE_AQC_ACL_PROF_BYTE_SEL_ELEMS)
    1839                 :            :                 return ICE_ERR_PARAM;
    1840                 :            : 
    1841                 :            :         /* Only 8 range checkers per profile, reject anything trying to use
    1842                 :            :          * more
    1843                 :            :          */
    1844         [ #  # ]:          0 :         if (range_idx > ICE_AQC_ACL_PROF_RANGES_NUM_CFG)
    1845                 :            :                 return ICE_ERR_PARAM;
    1846                 :            : 
    1847                 :            :         /* Store # bytes required for entry for later use */
    1848                 :          0 :         params->entry_length = index - ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
    1849                 :            : 
    1850                 :          0 :         return 0;
    1851                 :            : }
    1852                 :            : 
    1853                 :            : /**
    1854                 :            :  * ice_flow_proc_segs - process all packet segments associated with a profile
    1855                 :            :  * @hw: pointer to the HW struct
    1856                 :            :  * @params: information about the flow to be processed
    1857                 :            :  */
    1858                 :            : static int
    1859                 :          0 : ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
    1860                 :            : {
    1861                 :            :         int status;
    1862                 :            : 
    1863                 :          0 :         status = ice_flow_proc_seg_hdrs(params);
    1864         [ #  # ]:          0 :         if (status)
    1865                 :            :                 return status;
    1866                 :            : 
    1867                 :          0 :         status = ice_flow_create_xtrct_seq(hw, params);
    1868         [ #  # ]:          0 :         if (status)
    1869                 :            :                 return status;
    1870                 :            : 
    1871      [ #  #  # ]:          0 :         switch (params->blk) {
    1872                 :            :         case ICE_BLK_FD:
    1873                 :            :         case ICE_BLK_RSS:
    1874                 :            :                 status = 0;
    1875                 :            :                 break;
    1876                 :          0 :         case ICE_BLK_ACL:
    1877                 :          0 :                 status = ice_flow_acl_def_entry_frmt(params);
    1878         [ #  # ]:          0 :                 if (status)
    1879                 :            :                         return status;
    1880                 :          0 :                 status = ice_flow_sel_acl_scen(hw, params);
    1881         [ #  # ]:          0 :                 if (status)
    1882                 :          0 :                         return status;
    1883                 :            :                 break;
    1884                 :            :         default:
    1885                 :            :                 return ICE_ERR_NOT_IMPL;
    1886                 :            :         }
    1887                 :            : 
    1888                 :            :         return status;
    1889                 :            : }
    1890                 :            : 
    1891                 :            : #define ICE_FLOW_FIND_PROF_CHK_FLDS     0x00000001
    1892                 :            : #define ICE_FLOW_FIND_PROF_CHK_VSI      0x00000002
    1893                 :            : #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR  0x00000004
    1894                 :            : 
    1895                 :            : /**
    1896                 :            :  * ice_flow_find_prof_conds - Find a profile matching headers and conditions
    1897                 :            :  * @hw: pointer to the HW struct
    1898                 :            :  * @blk: classification stage
    1899                 :            :  * @dir: flow direction
    1900                 :            :  * @segs: array of one or more packet segments that describe the flow
    1901                 :            :  * @segs_cnt: number of packet segments provided
    1902                 :            :  * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
    1903                 :            :  * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
    1904                 :            :  */
    1905                 :            : static struct ice_flow_prof *
    1906                 :          0 : ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
    1907                 :            :                          enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
    1908                 :            :                          u8 segs_cnt, u16 vsi_handle, u32 conds)
    1909                 :            : {
    1910                 :            :         struct ice_flow_prof *p, *prof = NULL;
    1911                 :            : 
    1912                 :          0 :         ice_acquire_lock(&hw->fl_profs_locks[blk]);
    1913   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry)
                   #  # ]
    1914   [ #  #  #  #  :          0 :                 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
                   #  # ]
    1915         [ #  # ]:          0 :                     segs_cnt && segs_cnt == p->segs_cnt) {
    1916                 :            :                         u8 i;
    1917                 :            : 
    1918                 :            :                         /* Check for profile-VSI association if specified */
    1919   [ #  #  #  # ]:          0 :                         if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
    1920         [ #  # ]:          0 :                             ice_is_vsi_valid(hw, vsi_handle) &&
    1921         [ #  # ]:          0 :                             !ice_is_bit_set(p->vsis, vsi_handle))
    1922                 :          0 :                                 continue;
    1923                 :            : 
    1924                 :            :                         /* Protocol headers must be checked. Matched fields are
    1925                 :            :                          * checked if specified.
    1926                 :            :                          */
    1927         [ #  # ]:          0 :                         for (i = 0; i < segs_cnt; i++)
    1928         [ #  # ]:          0 :                                 if (segs[i].hdrs != p->segs[i].hdrs ||
    1929         [ #  # ]:          0 :                                     ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
    1930                 :          0 :                                      (ice_cmp_bitmap(segs[i].match,
    1931                 :          0 :                                                      p->segs[i].match,
    1932                 :            :                                                      ICE_FLOW_FIELD_IDX_MAX) ==
    1933                 :            :                                        false)))
    1934                 :            :                                         break;
    1935                 :            : 
    1936                 :            :                         /* A match is found if all segments are matched */
    1937         [ #  # ]:          0 :                         if (i == segs_cnt) {
    1938                 :            :                                 prof = p;
    1939                 :            :                                 break;
    1940                 :            :                         }
    1941                 :            :                 }
    1942                 :            :         ice_release_lock(&hw->fl_profs_locks[blk]);
    1943                 :            : 
    1944                 :          0 :         return prof;
    1945                 :            : }
    1946                 :            : 
    1947                 :            : /**
    1948                 :            :  * ice_flow_find_prof - Look up a profile matching headers and matched fields
    1949                 :            :  * @hw: pointer to the HW struct
    1950                 :            :  * @blk: classification stage
    1951                 :            :  * @dir: flow direction
    1952                 :            :  * @segs: array of one or more packet segments that describe the flow
    1953                 :            :  * @segs_cnt: number of packet segments provided
    1954                 :            :  */
    1955                 :            : u64
    1956                 :          0 : ice_flow_find_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
    1957                 :            :                    struct ice_flow_seg_info *segs, u8 segs_cnt)
    1958                 :            : {
    1959                 :            :         struct ice_flow_prof *p;
    1960                 :            : 
    1961                 :          0 :         p = ice_flow_find_prof_conds(hw, blk, dir, segs, segs_cnt,
    1962                 :            :                                      ICE_MAX_VSI, ICE_FLOW_FIND_PROF_CHK_FLDS);
    1963                 :            : 
    1964         [ #  # ]:          0 :         return p ? p->id : ICE_FLOW_PROF_ID_INVAL;
    1965                 :            : }
    1966                 :            : 
    1967                 :            : /**
    1968                 :            :  * ice_flow_find_prof_id - Look up a profile with given profile ID
    1969                 :            :  * @hw: pointer to the HW struct
    1970                 :            :  * @blk: classification stage
    1971                 :            :  * @prof_id: unique ID to identify this flow profile
    1972                 :            :  */
    1973                 :            : static struct ice_flow_prof *
    1974                 :            : ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
    1975                 :            : {
    1976                 :            :         struct ice_flow_prof *p;
    1977                 :            : 
    1978   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry)
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1979   [ #  #  #  #  :          0 :                 if (p->id == prof_id)
                   #  # ]
    1980                 :            :                         return p;
    1981                 :            : 
    1982                 :            :         return NULL;
    1983                 :            : }
    1984                 :            : 
    1985                 :            : /**
    1986                 :            :  * ice_dealloc_flow_entry - Deallocate flow entry memory
    1987                 :            :  * @hw: pointer to the HW struct
    1988                 :            :  * @entry: flow entry to be removed
    1989                 :            :  */
    1990                 :            : static void
    1991                 :          0 : ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
    1992                 :            : {
    1993         [ #  # ]:          0 :         if (!entry)
    1994                 :            :                 return;
    1995                 :            : 
    1996         [ #  # ]:          0 :         if (entry->entry)
    1997                 :          0 :                 ice_free(hw, entry->entry);
    1998                 :            : 
    1999         [ #  # ]:          0 :         if (entry->range_buf) {
    2000                 :          0 :                 ice_free(hw, entry->range_buf);
    2001                 :          0 :                 entry->range_buf = NULL;
    2002                 :            :         }
    2003                 :            : 
    2004         [ #  # ]:          0 :         if (entry->acts) {
    2005                 :          0 :                 ice_free(hw, entry->acts);
    2006                 :          0 :                 entry->acts = NULL;
    2007                 :          0 :                 entry->acts_cnt = 0;
    2008                 :            :         }
    2009                 :            : 
    2010                 :          0 :         ice_free(hw, entry);
    2011                 :            : }
    2012                 :            : 
    2013                 :            : /**
    2014                 :            :  * ice_flow_get_hw_prof - return the HW profile for a specific profile ID handle
    2015                 :            :  * @hw: pointer to the HW struct
    2016                 :            :  * @blk: classification stage
    2017                 :            :  * @prof_id: the profile ID handle
    2018                 :            :  * @hw_prof_id: pointer to variable to receive the HW profile ID
    2019                 :            :  */
    2020                 :            : int
    2021                 :          0 : ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
    2022                 :            :                      u8 *hw_prof_id)
    2023                 :            : {
    2024                 :            :         struct ice_prof_map *map;
    2025                 :            :         int status = ICE_ERR_DOES_NOT_EXIST;
    2026                 :            : 
    2027                 :          0 :         ice_acquire_lock(&hw->blk[blk].es.prof_map_lock);
    2028                 :          0 :         map = ice_search_prof_id(hw, blk, prof_id);
    2029         [ #  # ]:          0 :         if (map) {
    2030                 :          0 :                 *hw_prof_id = map->prof_id;
    2031                 :            :                 status = 0;
    2032                 :            :         }
    2033                 :            :         ice_release_lock(&hw->blk[blk].es.prof_map_lock);
    2034                 :          0 :         return status;
    2035                 :            : }
    2036                 :            : 
    2037                 :            : #define ICE_ACL_INVALID_SCEN    0x3f
    2038                 :            : 
    2039                 :            : /**
    2040                 :            :  * ice_flow_acl_is_prof_in_use - Verify if the profile is associated to any PF
    2041                 :            :  * @hw: pointer to the hardware structure
    2042                 :            :  * @prof: pointer to flow profile
    2043                 :            :  * @buf: destination buffer function writes partial extraction sequence to
    2044                 :            :  *
    2045                 :            :  * returns 0 if no PF is associated to the given profile
    2046                 :            :  * returns ICE_ERR_IN_USE if at least one PF is associated to the given profile
    2047                 :            :  * returns other error code for real error
    2048                 :            :  */
    2049                 :            : static int
    2050                 :          0 : ice_flow_acl_is_prof_in_use(struct ice_hw *hw, struct ice_flow_prof *prof,
    2051                 :            :                             struct ice_aqc_acl_prof_generic_frmt *buf)
    2052                 :            : {
    2053                 :          0 :         u8 prof_id = 0;
    2054                 :            :         int status;
    2055                 :            : 
    2056                 :          0 :         status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id, &prof_id);
    2057         [ #  # ]:          0 :         if (status)
    2058                 :            :                 return status;
    2059                 :            : 
    2060                 :          0 :         status = ice_query_acl_prof(hw, prof_id, buf, NULL);
    2061         [ #  # ]:          0 :         if (status)
    2062                 :            :                 return status;
    2063                 :            : 
    2064                 :            :         /* If all PF's associated scenarios are all 0 or all
    2065                 :            :          * ICE_ACL_INVALID_SCEN (63) for the given profile then the latter has
    2066                 :            :          * not been configured yet.
    2067                 :            :          */
    2068   [ #  #  #  # ]:          0 :         if (buf->pf_scenario_num[0] == 0 && buf->pf_scenario_num[1] == 0 &&
    2069   [ #  #  #  # ]:          0 :             buf->pf_scenario_num[2] == 0 && buf->pf_scenario_num[3] == 0 &&
    2070   [ #  #  #  # ]:          0 :             buf->pf_scenario_num[4] == 0 && buf->pf_scenario_num[5] == 0 &&
    2071   [ #  #  #  # ]:          0 :             buf->pf_scenario_num[6] == 0 && buf->pf_scenario_num[7] == 0)
    2072                 :            :                 return 0;
    2073                 :            : 
    2074         [ #  # ]:          0 :         if (buf->pf_scenario_num[0] == ICE_ACL_INVALID_SCEN &&
    2075         [ #  # ]:          0 :             buf->pf_scenario_num[1] == ICE_ACL_INVALID_SCEN &&
    2076         [ #  # ]:          0 :             buf->pf_scenario_num[2] == ICE_ACL_INVALID_SCEN &&
    2077         [ #  # ]:          0 :             buf->pf_scenario_num[3] == ICE_ACL_INVALID_SCEN &&
    2078         [ #  # ]:          0 :             buf->pf_scenario_num[4] == ICE_ACL_INVALID_SCEN &&
    2079         [ #  # ]:          0 :             buf->pf_scenario_num[5] == ICE_ACL_INVALID_SCEN &&
    2080         [ #  # ]:          0 :             buf->pf_scenario_num[6] == ICE_ACL_INVALID_SCEN &&
    2081         [ #  # ]:          0 :             buf->pf_scenario_num[7] == ICE_ACL_INVALID_SCEN)
    2082                 :          0 :                 return 0;
    2083                 :            : 
    2084                 :            :         return ICE_ERR_IN_USE;
    2085                 :            : }
    2086                 :            : 
    2087                 :            : /**
    2088                 :            :  * ice_flow_acl_free_act_cntr - Free the ACL rule's actions
    2089                 :            :  * @hw: pointer to the hardware structure
    2090                 :            :  * @acts: array of actions to be performed on a match
    2091                 :            :  * @acts_cnt: number of actions
    2092                 :            :  */
    2093                 :            : static int
    2094                 :          0 : ice_flow_acl_free_act_cntr(struct ice_hw *hw, struct ice_flow_action *acts,
    2095                 :            :                            u8 acts_cnt)
    2096                 :            : {
    2097                 :            :         int i;
    2098                 :            : 
    2099         [ #  # ]:          0 :         for (i = 0; i < acts_cnt; i++) {
    2100         [ #  # ]:          0 :                 if (acts[i].type == ICE_FLOW_ACT_CNTR_PKT ||
    2101         [ #  # ]:          0 :                     acts[i].type == ICE_FLOW_ACT_CNTR_BYTES ||
    2102                 :            :                     acts[i].type == ICE_FLOW_ACT_CNTR_PKT_BYTES) {
    2103                 :          0 :                         struct ice_acl_cntrs cntrs = { 0 };
    2104                 :            :                         int status;
    2105                 :            : 
    2106                 :            :                         /* amount is unused in the dealloc path but the common
    2107                 :            :                          * parameter check routine wants a value set, as zero
    2108                 :            :                          * is invalid for the check. Just set it.
    2109                 :            :                          */
    2110                 :          0 :                         cntrs.amount = 1;
    2111                 :            :                         cntrs.bank = 0; /* Only bank0 for the moment */
    2112                 :          0 :                         cntrs.first_cntr =
    2113                 :          0 :                                         LE16_TO_CPU(acts[i].data.acl_act.value);
    2114                 :          0 :                         cntrs.last_cntr =
    2115                 :            :                                         LE16_TO_CPU(acts[i].data.acl_act.value);
    2116                 :            : 
    2117         [ #  # ]:          0 :                         if (acts[i].type == ICE_FLOW_ACT_CNTR_PKT_BYTES)
    2118                 :          0 :                                 cntrs.type = ICE_AQC_ACL_CNT_TYPE_DUAL;
    2119                 :            :                         else
    2120                 :            :                                 cntrs.type = ICE_AQC_ACL_CNT_TYPE_SINGLE;
    2121                 :            : 
    2122                 :          0 :                         status = ice_aq_dealloc_acl_cntrs(hw, &cntrs, NULL);
    2123         [ #  # ]:          0 :                         if (status)
    2124                 :          0 :                                 return status;
    2125                 :            :                 }
    2126                 :            :         }
    2127                 :            :         return 0;
    2128                 :            : }
    2129                 :            : 
    2130                 :            : /**
    2131                 :            :  * ice_flow_acl_disassoc_scen - Disassociate the scenario from the profile
    2132                 :            :  * @hw: pointer to the hardware structure
    2133                 :            :  * @prof: pointer to flow profile
    2134                 :            :  *
    2135                 :            :  * Disassociate the scenario from the profile for the PF of the VSI.
    2136                 :            :  */
    2137                 :            : static int
    2138                 :          0 : ice_flow_acl_disassoc_scen(struct ice_hw *hw, struct ice_flow_prof *prof)
    2139                 :            : {
    2140                 :            :         struct ice_aqc_acl_prof_generic_frmt buf;
    2141                 :            :         int status = 0;
    2142                 :          0 :         u8 prof_id = 0;
    2143                 :            : 
    2144                 :            :         ice_memset(&buf, 0, sizeof(buf), ICE_NONDMA_MEM);
    2145                 :            : 
    2146                 :          0 :         status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id, &prof_id);
    2147         [ #  # ]:          0 :         if (status)
    2148                 :            :                 return status;
    2149                 :            : 
    2150                 :          0 :         status = ice_query_acl_prof(hw, prof_id, &buf, NULL);
    2151         [ #  # ]:          0 :         if (status)
    2152                 :            :                 return status;
    2153                 :            : 
    2154                 :            :         /* Clear scenario for this PF */
    2155                 :          0 :         buf.pf_scenario_num[hw->pf_id] = ICE_ACL_INVALID_SCEN;
    2156                 :          0 :         status = ice_prgm_acl_prof_xtrct(hw, prof_id, &buf, NULL);
    2157                 :            : 
    2158                 :          0 :         return status;
    2159                 :            : }
    2160                 :            : 
    2161                 :            : /**
    2162                 :            :  * ice_flow_rem_entry_sync - Remove a flow entry
    2163                 :            :  * @hw: pointer to the HW struct
    2164                 :            :  * @blk: classification stage
    2165                 :            :  * @entry: flow entry to be removed
    2166                 :            :  */
    2167                 :            : static int
    2168                 :          0 : ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block blk,
    2169                 :            :                         struct ice_flow_entry *entry)
    2170                 :            : {
    2171         [ #  # ]:          0 :         if (!entry)
    2172                 :            :                 return ICE_ERR_BAD_PTR;
    2173                 :            : 
    2174         [ #  # ]:          0 :         if (blk == ICE_BLK_ACL) {
    2175                 :            :                 int status;
    2176                 :            : 
    2177         [ #  # ]:          0 :                 if (!entry->prof)
    2178                 :            :                         return ICE_ERR_BAD_PTR;
    2179                 :            : 
    2180                 :          0 :                 status = ice_acl_rem_entry(hw, entry->prof->cfg.scen,
    2181                 :          0 :                                            entry->scen_entry_idx);
    2182         [ #  # ]:          0 :                 if (status)
    2183                 :            :                         return status;
    2184                 :            : 
    2185                 :            :                 /* Checks if we need to release an ACL counter. */
    2186   [ #  #  #  # ]:          0 :                 if (entry->acts_cnt && entry->acts)
    2187                 :          0 :                         ice_flow_acl_free_act_cntr(hw, entry->acts,
    2188                 :            :                                                    entry->acts_cnt);
    2189                 :            :         }
    2190                 :            : 
    2191         [ #  # ]:          0 :         LIST_DEL(&entry->l_entry);
    2192                 :            : 
    2193                 :          0 :         ice_dealloc_flow_entry(hw, entry);
    2194                 :            : 
    2195                 :          0 :         return 0;
    2196                 :            : }
    2197                 :            : 
    2198                 :            : /**
    2199                 :            :  * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
    2200                 :            :  * @hw: pointer to the HW struct
    2201                 :            :  * @blk: classification stage
    2202                 :            :  * @dir: flow direction
    2203                 :            :  * @prof_id: unique ID to identify this flow profile
    2204                 :            :  * @segs: array of one or more packet segments that describe the flow
    2205                 :            :  * @segs_cnt: number of packet segments provided
    2206                 :            :  * @acts: array of default actions
    2207                 :            :  * @acts_cnt: number of default actions
    2208                 :            :  * @prof: stores the returned flow profile added
    2209                 :            :  *
    2210                 :            :  * Assumption: the caller has acquired the lock to the profile list
    2211                 :            :  */
    2212                 :            : static int
    2213                 :          0 : ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
    2214                 :            :                        enum ice_flow_dir dir, u64 prof_id,
    2215                 :            :                        struct ice_flow_seg_info *segs, u8 segs_cnt,
    2216                 :            :                        struct ice_flow_action *acts, u8 acts_cnt,
    2217                 :            :                        struct ice_flow_prof **prof)
    2218                 :            : {
    2219                 :            :         struct ice_flow_prof_params *params;
    2220                 :            :         int status;
    2221                 :            :         u8 i;
    2222                 :            : 
    2223   [ #  #  #  # ]:          0 :         if (!prof || (acts_cnt && !acts))
    2224                 :            :                 return ICE_ERR_BAD_PTR;
    2225                 :            : 
    2226                 :          0 :         params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
    2227         [ #  # ]:          0 :         if (!params)
    2228                 :            :                 return ICE_ERR_NO_MEMORY;
    2229                 :            : 
    2230                 :          0 :         params->prof = (struct ice_flow_prof *)
    2231                 :          0 :                 ice_malloc(hw, sizeof(*params->prof));
    2232         [ #  # ]:          0 :         if (!params->prof) {
    2233                 :            :                 status = ICE_ERR_NO_MEMORY;
    2234                 :          0 :                 goto free_params;
    2235                 :            :         }
    2236                 :            : 
    2237                 :            :         /* initialize extraction sequence to all invalid (0xff) */
    2238         [ #  # ]:          0 :         for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
    2239                 :          0 :                 params->es[i].prot_id = ICE_PROT_INVALID;
    2240                 :          0 :                 params->es[i].off = ICE_FV_OFFSET_INVAL;
    2241                 :            :         }
    2242                 :            : 
    2243                 :          0 :         params->blk = blk;
    2244                 :          0 :         params->prof->id = prof_id;
    2245                 :          0 :         params->prof->dir = dir;
    2246                 :          0 :         params->prof->segs_cnt = segs_cnt;
    2247                 :            : 
    2248                 :            :         /* Make a copy of the segments that need to be persistent in the flow
    2249                 :            :          * profile instance
    2250                 :            :          */
    2251         [ #  # ]:          0 :         for (i = 0; i < segs_cnt; i++)
    2252         [ #  # ]:          0 :                 ice_memcpy(&params->prof->segs[i], &segs[i], sizeof(*segs),
    2253                 :            :                            ICE_NONDMA_TO_NONDMA);
    2254                 :            : 
    2255                 :            :         /* Make a copy of the actions that need to be persistent in the flow
    2256                 :            :          * profile instance.
    2257                 :            :          */
    2258         [ #  # ]:          0 :         if (acts_cnt) {
    2259                 :          0 :                 params->prof->acts = (struct ice_flow_action *)
    2260                 :          0 :                         ice_memdup(hw, acts, acts_cnt * sizeof(*acts),
    2261                 :            :                                    ICE_NONDMA_TO_NONDMA);
    2262                 :            : 
    2263         [ #  # ]:          0 :                 if (!params->prof->acts) {
    2264                 :            :                         status = ICE_ERR_NO_MEMORY;
    2265                 :          0 :                         goto out;
    2266                 :            :                 }
    2267                 :            :         }
    2268                 :            : 
    2269                 :          0 :         status = ice_flow_proc_segs(hw, params);
    2270         [ #  # ]:          0 :         if (status) {
    2271         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
    2272                 :          0 :                 goto out;
    2273                 :            :         }
    2274                 :            : 
    2275                 :            :         /* Add a HW profile for this flow profile */
    2276                 :          0 :         status = ice_add_prof(hw, blk, prof_id, params->ptypes,
    2277                 :          0 :                               params->attr, params->attr_cnt, params->es,
    2278                 :          0 :                               params->mask, true);
    2279         [ #  # ]:          0 :         if (status) {
    2280         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
    2281                 :          0 :                 goto out;
    2282                 :            :         }
    2283                 :            : 
    2284                 :          0 :         INIT_LIST_HEAD(&params->prof->entries);
    2285                 :            :         ice_init_lock(&params->prof->entries_lock);
    2286                 :          0 :         *prof = params->prof;
    2287                 :            : 
    2288                 :          0 : out:
    2289         [ #  # ]:          0 :         if (status) {
    2290         [ #  # ]:          0 :                 if (params->prof->acts)
    2291                 :          0 :                         ice_free(hw, params->prof->acts);
    2292                 :          0 :                 ice_free(hw, params->prof);
    2293                 :            :         }
    2294                 :          0 : free_params:
    2295                 :          0 :         ice_free(hw, params);
    2296                 :            : 
    2297                 :          0 :         return status;
    2298                 :            : }
    2299                 :            : 
    2300                 :            : /**
    2301                 :            :  * ice_flow_rem_prof_sync - remove a flow profile
    2302                 :            :  * @hw: pointer to the hardware structure
    2303                 :            :  * @blk: classification stage
    2304                 :            :  * @prof: pointer to flow profile to remove
    2305                 :            :  *
    2306                 :            :  * Assumption: the caller has acquired the lock to the profile list
    2307                 :            :  */
    2308                 :            : static int
    2309                 :          0 : ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
    2310                 :            :                        struct ice_flow_prof *prof)
    2311                 :            : {
    2312                 :            :         int status;
    2313                 :            : 
    2314                 :            :         /* Remove all remaining flow entries before removing the flow profile */
    2315         [ #  # ]:          0 :         if (!LIST_EMPTY(&prof->entries)) {
    2316                 :            :                 struct ice_flow_entry *e, *t;
    2317                 :            : 
    2318                 :          0 :                 ice_acquire_lock(&prof->entries_lock);
    2319                 :            : 
    2320   [ #  #  #  #  :          0 :                 LIST_FOR_EACH_ENTRY_SAFE(e, t, &prof->entries, ice_flow_entry,
          #  #  #  #  #  
                      # ]
    2321                 :            :                                          l_entry) {
    2322                 :          0 :                         status = ice_flow_rem_entry_sync(hw, blk, e);
    2323         [ #  # ]:          0 :                         if (status)
    2324                 :            :                                 break;
    2325                 :            :                 }
    2326                 :            : 
    2327                 :            :                 ice_release_lock(&prof->entries_lock);
    2328                 :            :         }
    2329                 :            : 
    2330         [ #  # ]:          0 :         if (blk == ICE_BLK_ACL) {
    2331                 :            :                 struct ice_aqc_acl_profile_ranges query_rng_buf;
    2332                 :            :                 struct ice_aqc_acl_prof_generic_frmt buf;
    2333                 :          0 :                 u8 prof_id = 0;
    2334                 :            : 
    2335                 :            :                 /* Disassociate the scenario from the profile for the PF */
    2336                 :          0 :                 status = ice_flow_acl_disassoc_scen(hw, prof);
    2337         [ #  # ]:          0 :                 if (status)
    2338                 :          0 :                         return status;
    2339                 :            : 
    2340                 :            :                 /* Clear the range-checker if the profile ID is no longer
    2341                 :            :                  * used by any PF
    2342                 :            :                  */
    2343                 :          0 :                 status = ice_flow_acl_is_prof_in_use(hw, prof, &buf);
    2344         [ #  # ]:          0 :                 if (status && status != ICE_ERR_IN_USE) {
    2345                 :            :                         return status;
    2346         [ #  # ]:          0 :                 } else if (!status) {
    2347                 :            :                         /* Clear the range-checker value for profile ID */
    2348                 :            :                         ice_memset(&query_rng_buf, 0,
    2349                 :            :                                    sizeof(struct ice_aqc_acl_profile_ranges),
    2350                 :            :                                    ICE_NONDMA_MEM);
    2351                 :            : 
    2352                 :          0 :                         status = ice_flow_get_hw_prof(hw, blk, prof->id,
    2353                 :            :                                                       &prof_id);
    2354         [ #  # ]:          0 :                         if (status)
    2355                 :            :                                 return status;
    2356                 :            : 
    2357                 :          0 :                         status = ice_prog_acl_prof_ranges(hw, prof_id,
    2358                 :            :                                                           &query_rng_buf, NULL);
    2359         [ #  # ]:          0 :                         if (status)
    2360                 :            :                                 return status;
    2361                 :            :                 }
    2362                 :            :         }
    2363                 :            : 
    2364                 :            :         /* Remove all hardware profiles associated with this flow profile */
    2365                 :          0 :         status = ice_rem_prof(hw, blk, prof->id);
    2366         [ #  # ]:          0 :         if (!status) {
    2367         [ #  # ]:          0 :                 LIST_DEL(&prof->l_entry);
    2368                 :            :                 ice_destroy_lock(&prof->entries_lock);
    2369         [ #  # ]:          0 :                 if (prof->acts)
    2370                 :          0 :                         ice_free(hw, prof->acts);
    2371                 :          0 :                 ice_free(hw, prof);
    2372                 :            :         }
    2373                 :            : 
    2374                 :            :         return status;
    2375                 :            : }
    2376                 :            : 
    2377                 :            : /**
    2378                 :            :  * ice_flow_acl_set_xtrct_seq_fld - Populate xtrct seq for single field
    2379                 :            :  * @buf: Destination buffer function writes partial xtrct sequence to
    2380                 :            :  * @info: Info about field
    2381                 :            :  */
    2382                 :            : static void
    2383                 :            : ice_flow_acl_set_xtrct_seq_fld(struct ice_aqc_acl_prof_generic_frmt *buf,
    2384                 :            :                                struct ice_flow_fld_info *info)
    2385                 :            : {
    2386                 :            :         u16 dst, i;
    2387                 :            :         u8 src;
    2388                 :            : 
    2389                 :          0 :         src = info->xtrct.idx * ICE_FLOW_FV_EXTRACT_SZ +
    2390                 :          0 :                 info->xtrct.disp / BITS_PER_BYTE;
    2391                 :          0 :         dst = info->entry.val;
    2392   [ #  #  #  # ]:          0 :         for (i = 0; i < info->entry.last; i++)
    2393                 :            :                 /* HW stores field vector words in LE, convert words back to BE
    2394                 :            :                  * so constructed entries will end up in network order
    2395                 :            :                  */
    2396                 :          0 :                 buf->byte_selection[dst++] = src++ ^ 1;
    2397                 :            : }
    2398                 :            : 
    2399                 :            : /**
    2400                 :            :  * ice_flow_acl_set_xtrct_seq - Program ACL extraction sequence
    2401                 :            :  * @hw: pointer to the hardware structure
    2402                 :            :  * @prof: pointer to flow profile
    2403                 :            :  */
    2404                 :            : static int
    2405                 :          0 : ice_flow_acl_set_xtrct_seq(struct ice_hw *hw, struct ice_flow_prof *prof)
    2406                 :            : {
    2407                 :            :         struct ice_aqc_acl_prof_generic_frmt buf;
    2408                 :            :         struct ice_flow_fld_info *info;
    2409                 :          0 :         u8 prof_id = 0;
    2410                 :            :         int status;
    2411                 :            :         u16 i;
    2412                 :            : 
    2413                 :            :         ice_memset(&buf, 0, sizeof(buf), ICE_NONDMA_MEM);
    2414                 :            : 
    2415                 :          0 :         status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id, &prof_id);
    2416         [ #  # ]:          0 :         if (status)
    2417                 :            :                 return status;
    2418                 :            : 
    2419                 :          0 :         status = ice_flow_acl_is_prof_in_use(hw, prof, &buf);
    2420         [ #  # ]:          0 :         if (status && status != ICE_ERR_IN_USE)
    2421                 :            :                 return status;
    2422                 :            : 
    2423         [ #  # ]:          0 :         if (!status) {
    2424                 :            :                 /* Program the profile dependent configuration. This is done
    2425                 :            :                  * only once regardless of the number of PFs using that profile
    2426                 :            :                  */
    2427                 :            :                 ice_memset(&buf, 0, sizeof(buf), ICE_NONDMA_MEM);
    2428                 :            : 
    2429         [ #  # ]:          0 :                 for (i = 0; i < prof->segs_cnt; i++) {
    2430                 :          0 :                         struct ice_flow_seg_info *seg = &prof->segs[i];
    2431                 :            :                         u16 j;
    2432                 :            : 
    2433         [ #  # ]:          0 :                         ice_for_each_set_bit(j, seg->match,
    2434                 :            :                                              ICE_FLOW_FIELD_IDX_MAX) {
    2435                 :          0 :                                 info = &seg->fields[j];
    2436                 :            : 
    2437         [ #  # ]:          0 :                                 if (info->type == ICE_FLOW_FLD_TYPE_RANGE)
    2438                 :          0 :                                         buf.word_selection[info->entry.val] =
    2439                 :          0 :                                                 info->xtrct.idx;
    2440                 :            :                                 else
    2441                 :            :                                         ice_flow_acl_set_xtrct_seq_fld(&buf,
    2442                 :            :                                                                        info);
    2443                 :            :                         }
    2444                 :            : 
    2445         [ #  # ]:          0 :                         for (j = 0; j < seg->raws_cnt; j++) {
    2446                 :          0 :                                 info = &seg->raws[j].info;
    2447                 :            :                                 ice_flow_acl_set_xtrct_seq_fld(&buf, info);
    2448                 :            :                         }
    2449                 :            :                 }
    2450                 :            : 
    2451                 :            :                 ice_memset(&buf.pf_scenario_num[0], ICE_ACL_INVALID_SCEN,
    2452                 :            :                            ICE_AQC_ACL_PROF_PF_SCEN_NUM_ELEMS,
    2453                 :            :                            ICE_NONDMA_MEM);
    2454                 :            :         }
    2455                 :            : 
    2456                 :            :         /* Update the current PF */
    2457                 :          0 :         buf.pf_scenario_num[hw->pf_id] = (u8)prof->cfg.scen->id;
    2458                 :          0 :         status = ice_prgm_acl_prof_xtrct(hw, prof_id, &buf, NULL);
    2459                 :            : 
    2460                 :          0 :         return status;
    2461                 :            : }
    2462                 :            : 
    2463                 :            : /**
    2464                 :            :  * ice_flow_assoc_vsig_vsi - associate a VSI with VSIG
    2465                 :            :  * @hw: pointer to the hardware structure
    2466                 :            :  * @blk: classification stage
    2467                 :            :  * @vsi_handle: software VSI handle
    2468                 :            :  * @vsig: target VSI group
    2469                 :            :  *
    2470                 :            :  * Assumption: the caller has already verified that the VSI to
    2471                 :            :  * be added has the same characteristics as the VSIG and will
    2472                 :            :  * thereby have access to all resources added to that VSIG.
    2473                 :            :  */
    2474                 :            : int
    2475                 :          0 : ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
    2476                 :            :                         u16 vsig)
    2477                 :            : {
    2478                 :            :         int status;
    2479                 :            : 
    2480   [ #  #  #  # ]:          0 :         if (!ice_is_vsi_valid(hw, vsi_handle) || blk >= ICE_BLK_COUNT)
    2481                 :            :                 return ICE_ERR_PARAM;
    2482                 :            : 
    2483                 :          0 :         ice_acquire_lock(&hw->fl_profs_locks[blk]);
    2484                 :          0 :         status = ice_add_vsi_flow(hw, blk, ice_get_hw_vsi_num(hw, vsi_handle),
    2485                 :            :                                   vsig);
    2486                 :            :         ice_release_lock(&hw->fl_profs_locks[blk]);
    2487                 :            : 
    2488                 :          0 :         return status;
    2489                 :            : }
    2490                 :            : 
    2491                 :            : /**
    2492                 :            :  * ice_flow_assoc_prof - associate a VSI with a flow profile
    2493                 :            :  * @hw: pointer to the hardware structure
    2494                 :            :  * @blk: classification stage
    2495                 :            :  * @prof: pointer to flow profile
    2496                 :            :  * @vsi_handle: software VSI handle
    2497                 :            :  *
    2498                 :            :  * Assumption: the caller has acquired the lock to the profile list
    2499                 :            :  * and the software VSI handle has been validated
    2500                 :            :  */
    2501                 :            : int
    2502                 :          0 : ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
    2503                 :            :                     struct ice_flow_prof *prof, u16 vsi_handle)
    2504                 :            : {
    2505                 :            :         int status = 0;
    2506                 :            : 
    2507         [ #  # ]:          0 :         if (!ice_is_bit_set(prof->vsis, vsi_handle)) {
    2508         [ #  # ]:          0 :                 if (blk == ICE_BLK_ACL) {
    2509                 :          0 :                         status = ice_flow_acl_set_xtrct_seq(hw, prof);
    2510         [ #  # ]:          0 :                         if (status)
    2511                 :            :                                 return status;
    2512                 :            :                 }
    2513                 :          0 :                 status = ice_add_prof_id_flow(hw, blk,
    2514                 :          0 :                                               ice_get_hw_vsi_num(hw,
    2515                 :            :                                                                  vsi_handle),
    2516                 :            :                                               prof->id);
    2517         [ #  # ]:          0 :                 if (!status)
    2518                 :            :                         ice_set_bit(vsi_handle, prof->vsis);
    2519                 :            :                 else
    2520         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
    2521                 :            :                                   status);
    2522                 :            :         }
    2523                 :            : 
    2524                 :            :         return status;
    2525                 :            : }
    2526                 :            : 
    2527                 :            : /**
    2528                 :            :  * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
    2529                 :            :  * @hw: pointer to the hardware structure
    2530                 :            :  * @blk: classification stage
    2531                 :            :  * @prof: pointer to flow profile
    2532                 :            :  * @vsi_handle: software VSI handle
    2533                 :            :  *
    2534                 :            :  * Assumption: the caller has acquired the lock to the profile list
    2535                 :            :  * and the software VSI handle has been validated
    2536                 :            :  */
    2537                 :            : static int
    2538                 :          0 : ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
    2539                 :            :                        struct ice_flow_prof *prof, u16 vsi_handle)
    2540                 :            : {
    2541                 :            :         int status = 0;
    2542                 :            : 
    2543         [ #  # ]:          0 :         if (ice_is_bit_set(prof->vsis, vsi_handle)) {
    2544                 :          0 :                 status = ice_rem_prof_id_flow(hw, blk,
    2545                 :          0 :                                               ice_get_hw_vsi_num(hw,
    2546                 :            :                                                                  vsi_handle),
    2547                 :            :                                               prof->id);
    2548         [ #  # ]:          0 :                 if (!status)
    2549                 :            :                         ice_clear_bit(vsi_handle, prof->vsis);
    2550                 :            :                 else
    2551         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
    2552                 :            :                                   status);
    2553                 :            :         }
    2554                 :            : 
    2555                 :          0 :         return status;
    2556                 :            : }
    2557                 :            : 
    2558                 :            : #define FLAG_GTP_EH_PDU_LINK    BIT_ULL(13)
    2559                 :            : #define FLAG_GTP_EH_PDU         BIT_ULL(14)
    2560                 :            : 
    2561                 :            : #define FLAG_GTPU_MSK   \
    2562                 :            :         (FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
    2563                 :            : #define FLAG_GTPU_UP    \
    2564                 :            :         (FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
    2565                 :            : #define FLAG_GTPU_DW    \
    2566                 :            :         (FLAG_GTP_EH_PDU)
    2567                 :            : /**
    2568                 :            :  * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
    2569                 :            :  * @hw: pointer to the HW struct
    2570                 :            :  * @dest_vsi_handle: dest VSI handle
    2571                 :            :  * @fdir_vsi_handle: fdir programming VSI handle
    2572                 :            :  * @prof: stores parsed profile info from raw flow
    2573                 :            :  * @blk: classification stage
    2574                 :            :  */
    2575                 :            : int
    2576                 :          0 : ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
    2577                 :            :                      u16 fdir_vsi_handle, struct ice_parser_profile *prof,
    2578                 :            :                      enum ice_block blk)
    2579                 :            : {
    2580                 :          0 :         int id = ice_find_first_bit(prof->ptypes, ICE_FLOW_PTYPE_MAX);
    2581                 :            :         struct ice_flow_prof_params *params;
    2582                 :          0 :         u8 fv_words = hw->blk[blk].es.fvw;
    2583                 :            :         int status;
    2584                 :            :         int i, idx;
    2585                 :            : 
    2586                 :          0 :         params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
    2587         [ #  # ]:          0 :         if (!params)
    2588                 :            :                 return ICE_ERR_NO_MEMORY;
    2589                 :            : 
    2590         [ #  # ]:          0 :         for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
    2591                 :          0 :                 params->es[i].prot_id = ICE_PROT_INVALID;
    2592                 :          0 :                 params->es[i].off = ICE_FV_OFFSET_INVAL;
    2593                 :            :         }
    2594                 :            : 
    2595         [ #  # ]:          0 :         for (i = 0; i < prof->fv_num; i++) {
    2596         [ #  # ]:          0 :                 if (hw->blk[blk].es.reverse)
    2597                 :          0 :                         idx = fv_words - i - 1;
    2598                 :            :                 else
    2599                 :            :                         idx = i;
    2600                 :          0 :                 params->es[idx].prot_id = prof->fv[i].proto_id;
    2601                 :          0 :                 params->es[idx].off = prof->fv[i].offset;
    2602         [ #  # ]:          0 :                 params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
    2603                 :            :         }
    2604                 :            : 
    2605      [ #  #  # ]:          0 :         switch (prof->flags) {
    2606                 :          0 :         case FLAG_GTPU_DW:
    2607                 :          0 :                 params->attr = ice_attr_gtpu_down;
    2608                 :          0 :                 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
    2609                 :          0 :                 break;
    2610                 :          0 :         case FLAG_GTPU_UP:
    2611                 :          0 :                 params->attr = ice_attr_gtpu_up;
    2612                 :          0 :                 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
    2613                 :          0 :                 break;
    2614                 :          0 :         default:
    2615         [ #  # ]:          0 :                 if (prof->flags_msk & FLAG_GTPU_MSK) {
    2616                 :          0 :                         params->attr = ice_attr_gtpu_session;
    2617                 :          0 :                         params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
    2618                 :            :                 }
    2619                 :            :                 break;
    2620                 :            :         }
    2621                 :            : 
    2622                 :          0 :         status = ice_add_prof(hw, blk, id, prof->ptypes,
    2623                 :          0 :                               params->attr, params->attr_cnt,
    2624                 :          0 :                               params->es, params->mask, false);
    2625         [ #  # ]:          0 :         if (status)
    2626                 :          0 :                 goto free_params;
    2627                 :            : 
    2628                 :          0 :         status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
    2629                 :            :                                         fdir_vsi_handle, id);
    2630         [ #  # ]:          0 :         if (status)
    2631                 :          0 :                 goto free_params;
    2632                 :            : 
    2633                 :            :         return 0;
    2634                 :            : 
    2635                 :          0 : free_params:
    2636                 :          0 :         ice_free(hw, params);
    2637                 :            : 
    2638                 :          0 :         return status;
    2639                 :            : }
    2640                 :            : 
    2641                 :            : /**
    2642                 :            :  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
    2643                 :            :  * @hw: pointer to the HW struct
    2644                 :            :  * @blk: classification stage
    2645                 :            :  * @dir: flow direction
    2646                 :            :  * @prof_id: unique ID to identify this flow profile
    2647                 :            :  * @segs: array of one or more packet segments that describe the flow
    2648                 :            :  * @segs_cnt: number of packet segments provided
    2649                 :            :  * @acts: array of default actions
    2650                 :            :  * @acts_cnt: number of default actions
    2651                 :            :  * @prof: stores the returned flow profile added
    2652                 :            :  */
    2653                 :            : int
    2654                 :          0 : ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
    2655                 :            :                   u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
    2656                 :            :                   struct ice_flow_action *acts, u8 acts_cnt,
    2657                 :            :                   struct ice_flow_prof **prof)
    2658                 :            : {
    2659                 :            :         int status;
    2660                 :            : 
    2661         [ #  # ]:          0 :         if (segs_cnt > ICE_FLOW_SEG_MAX)
    2662                 :            :                 return ICE_ERR_MAX_LIMIT;
    2663                 :            : 
    2664         [ #  # ]:          0 :         if (!segs_cnt)
    2665                 :            :                 return ICE_ERR_PARAM;
    2666                 :            : 
    2667         [ #  # ]:          0 :         if (!segs)
    2668                 :            :                 return ICE_ERR_BAD_PTR;
    2669                 :            : 
    2670                 :          0 :         status = ice_flow_val_hdrs(segs, segs_cnt);
    2671         [ #  # ]:          0 :         if (status)
    2672                 :            :                 return status;
    2673                 :            : 
    2674                 :          0 :         ice_acquire_lock(&hw->fl_profs_locks[blk]);
    2675                 :            : 
    2676                 :          0 :         status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
    2677                 :            :                                         acts, acts_cnt, prof);
    2678         [ #  # ]:          0 :         if (!status)
    2679         [ #  # ]:          0 :                 LIST_ADD(&(*prof)->l_entry, &hw->fl_profs[blk]);
    2680                 :            : 
    2681                 :            :         ice_release_lock(&hw->fl_profs_locks[blk]);
    2682                 :            : 
    2683                 :          0 :         return status;
    2684                 :            : }
    2685                 :            : 
    2686                 :            : /**
    2687                 :            :  * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
    2688                 :            :  * @hw: pointer to the HW struct
    2689                 :            :  * @blk: the block for which the flow profile is to be removed
    2690                 :            :  * @prof_id: unique ID of the flow profile to be removed
    2691                 :            :  */
    2692                 :            : int
    2693                 :          0 : ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
    2694                 :            : {
    2695                 :            :         struct ice_flow_prof *prof;
    2696                 :            :         int status;
    2697                 :            : 
    2698                 :          0 :         ice_acquire_lock(&hw->fl_profs_locks[blk]);
    2699                 :            : 
    2700                 :            :         prof = ice_flow_find_prof_id(hw, blk, prof_id);
    2701         [ #  # ]:          0 :         if (!prof) {
    2702                 :            :                 status = ICE_ERR_DOES_NOT_EXIST;
    2703                 :          0 :                 goto out;
    2704                 :            :         }
    2705                 :            : 
    2706                 :            :         /* prof becomes invalid after the call */
    2707                 :          0 :         status = ice_flow_rem_prof_sync(hw, blk, prof);
    2708                 :            : 
    2709                 :          0 : out:
    2710                 :            :         ice_release_lock(&hw->fl_profs_locks[blk]);
    2711                 :            : 
    2712                 :          0 :         return status;
    2713                 :            : }
    2714                 :            : 
    2715                 :            : /**
    2716                 :            :  * ice_flow_find_entry - look for a flow entry using its unique ID
    2717                 :            :  * @hw: pointer to the HW struct
    2718                 :            :  * @blk: classification stage
    2719                 :            :  * @entry_id: unique ID to identify this flow entry
    2720                 :            :  *
    2721                 :            :  * This function looks for the flow entry with the specified unique ID in all
    2722                 :            :  * flow profiles of the specified classification stage. If the entry is found,
    2723                 :            :  * and it returns the handle to the flow entry. Otherwise, it returns
    2724                 :            :  * ICE_FLOW_ENTRY_ID_INVAL.
    2725                 :            :  */
    2726                 :          0 : u64 ice_flow_find_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_id)
    2727                 :            : {
    2728                 :            :         struct ice_flow_entry *found = NULL;
    2729                 :            :         struct ice_flow_prof *p;
    2730                 :            : 
    2731                 :          0 :         ice_acquire_lock(&hw->fl_profs_locks[blk]);
    2732                 :            : 
    2733   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry) {
                   #  # ]
    2734                 :            :                 struct ice_flow_entry *e;
    2735                 :            : 
    2736                 :          0 :                 ice_acquire_lock(&p->entries_lock);
    2737   [ #  #  #  #  :          0 :                 LIST_FOR_EACH_ENTRY(e, &p->entries, ice_flow_entry, l_entry)
                   #  # ]
    2738         [ #  # ]:          0 :                         if (e->id == entry_id) {
    2739                 :            :                                 found = e;
    2740                 :            :                                 break;
    2741                 :            :                         }
    2742                 :            :                 ice_release_lock(&p->entries_lock);
    2743                 :            : 
    2744         [ #  # ]:          0 :                 if (found)
    2745                 :            :                         break;
    2746                 :            :         }
    2747                 :            : 
    2748                 :            :         ice_release_lock(&hw->fl_profs_locks[blk]);
    2749                 :            : 
    2750         [ #  # ]:          0 :         return found ? ICE_FLOW_ENTRY_HNDL(found) : ICE_FLOW_ENTRY_HANDLE_INVAL;
    2751                 :            : }
    2752                 :            : 
    2753                 :            : /**
    2754                 :            :  * ice_flow_acl_check_actions - Checks the ACL rule's actions
    2755                 :            :  * @hw: pointer to the hardware structure
    2756                 :            :  * @acts: array of actions to be performed on a match
    2757                 :            :  * @acts_cnt: number of actions
    2758                 :            :  * @cnt_alloc: indicates if an ACL counter has been allocated.
    2759                 :            :  */
    2760                 :            : static int
    2761                 :          0 : ice_flow_acl_check_actions(struct ice_hw *hw, struct ice_flow_action *acts,
    2762                 :            :                            u8 acts_cnt, bool *cnt_alloc)
    2763                 :            : {
    2764                 :            :         ice_declare_bitmap(dup_check, ICE_AQC_TBL_MAX_ACTION_PAIRS * 2);
    2765                 :            :         int i;
    2766                 :            : 
    2767                 :            :         ice_zero_bitmap(dup_check, ICE_AQC_TBL_MAX_ACTION_PAIRS * 2);
    2768                 :          0 :         *cnt_alloc = false;
    2769                 :            : 
    2770         [ #  # ]:          0 :         if (acts_cnt > ICE_FLOW_ACL_MAX_NUM_ACT)
    2771                 :            :                 return ICE_ERR_OUT_OF_RANGE;
    2772                 :            : 
    2773         [ #  # ]:          0 :         for (i = 0; i < acts_cnt; i++) {
    2774         [ #  # ]:          0 :                 if (acts[i].type != ICE_FLOW_ACT_NOP &&
    2775         [ #  # ]:          0 :                     acts[i].type != ICE_FLOW_ACT_DROP &&
    2776         [ #  # ]:          0 :                     acts[i].type != ICE_FLOW_ACT_CNTR_PKT &&
    2777                 :            :                     acts[i].type != ICE_FLOW_ACT_FWD_QUEUE)
    2778                 :            :                         return ICE_ERR_CFG;
    2779                 :            : 
    2780                 :            :                 /* If the caller want to add two actions of the same type, then
    2781                 :            :                  * it is considered invalid configuration.
    2782                 :            :                  */
    2783         [ #  # ]:          0 :                 if (ice_test_and_set_bit((u16)acts[i].type, dup_check))
    2784                 :            :                         return ICE_ERR_PARAM;
    2785                 :            :         }
    2786                 :            : 
    2787                 :            :         /* Checks if ACL counters are needed. */
    2788         [ #  # ]:          0 :         for (i = 0; i < acts_cnt; i++) {
    2789         [ #  # ]:          0 :                 if (acts[i].type == ICE_FLOW_ACT_CNTR_PKT ||
    2790         [ #  # ]:          0 :                     acts[i].type == ICE_FLOW_ACT_CNTR_BYTES ||
    2791                 :            :                     acts[i].type == ICE_FLOW_ACT_CNTR_PKT_BYTES) {
    2792                 :          0 :                         struct ice_acl_cntrs cntrs = { 0 };
    2793                 :            :                         int status;
    2794                 :            : 
    2795                 :          0 :                         cntrs.amount = 1;
    2796                 :            :                         cntrs.bank = 0; /* Only bank0 for the moment */
    2797                 :            : 
    2798         [ #  # ]:          0 :                         if (acts[i].type == ICE_FLOW_ACT_CNTR_PKT_BYTES)
    2799                 :          0 :                                 cntrs.type = ICE_AQC_ACL_CNT_TYPE_DUAL;
    2800                 :            :                         else
    2801                 :            :                                 cntrs.type = ICE_AQC_ACL_CNT_TYPE_SINGLE;
    2802                 :            : 
    2803                 :          0 :                         status = ice_aq_alloc_acl_cntrs(hw, &cntrs, NULL);
    2804         [ #  # ]:          0 :                         if (status)
    2805                 :          0 :                                 return status;
    2806                 :            :                         /* Counter index within the bank */
    2807                 :          0 :                         acts[i].data.acl_act.value =
    2808                 :          0 :                                                 CPU_TO_LE16(cntrs.first_cntr);
    2809                 :          0 :                         *cnt_alloc = true;
    2810                 :            :                 }
    2811                 :            :         }
    2812                 :            : 
    2813                 :            :         return 0;
    2814                 :            : }
    2815                 :            : 
    2816                 :            : /**
    2817                 :            :  * ice_flow_acl_frmt_entry_range - Format an ACL range checker for a given field
    2818                 :            :  * @fld: number of the given field
    2819                 :            :  * @info: info about field
    2820                 :            :  * @range_buf: range checker configuration buffer
    2821                 :            :  * @data: pointer to a data buffer containing flow entry's match values/masks
    2822                 :            :  * @range: Input/output param indicating which range checkers are being used
    2823                 :            :  */
    2824                 :            : static void
    2825                 :          0 : ice_flow_acl_frmt_entry_range(u16 fld, struct ice_flow_fld_info *info,
    2826                 :            :                               struct ice_aqc_acl_profile_ranges *range_buf,
    2827                 :            :                               u8 *data, u8 *range)
    2828                 :            : {
    2829                 :            :         u16 new_mask;
    2830                 :            : 
    2831                 :            :         /* If not specified, default mask is all bits in field */
    2832                 :          0 :         new_mask = (info->src.mask == ICE_FLOW_FLD_OFF_INVAL ?
    2833         [ #  # ]:          0 :                     BIT(ice_flds_info[fld].size) - 1 :
    2834                 :          0 :                     (*(u16 *)(data + info->src.mask))) << info->xtrct.disp;
    2835                 :            : 
    2836                 :            :         /* If the mask is 0, then we don't need to worry about this input
    2837                 :            :          * range checker value.
    2838                 :            :          */
    2839         [ #  # ]:          0 :         if (new_mask) {
    2840                 :          0 :                 u16 new_high =
    2841                 :          0 :                         (*(u16 *)(data + info->src.last)) << info->xtrct.disp;
    2842                 :          0 :                 u16 new_low =
    2843                 :          0 :                         (*(u16 *)(data + info->src.val)) << info->xtrct.disp;
    2844                 :          0 :                 u8 range_idx = (u8)info->entry.val;
    2845                 :            : 
    2846                 :          0 :                 range_buf->checker_cfg[range_idx].low_boundary =
    2847         [ #  # ]:          0 :                         CPU_TO_BE16(new_low);
    2848                 :          0 :                 range_buf->checker_cfg[range_idx].high_boundary =
    2849         [ #  # ]:          0 :                         CPU_TO_BE16(new_high);
    2850         [ #  # ]:          0 :                 range_buf->checker_cfg[range_idx].mask = CPU_TO_BE16(new_mask);
    2851                 :            : 
    2852                 :            :                 /* Indicate which range checker is being used */
    2853                 :          0 :                 *range |= BIT(range_idx);
    2854                 :            :         }
    2855                 :          0 : }
    2856                 :            : 
    2857                 :            : /**
    2858                 :            :  * ice_flow_acl_frmt_entry_fld - Partially format ACL entry for a given field
    2859                 :            :  * @fld: number of the given field
    2860                 :            :  * @info: info about the field
    2861                 :            :  * @buf: buffer containing the entry
    2862                 :            :  * @dontcare: buffer containing don't care mask for entry
    2863                 :            :  * @data: pointer to a data buffer containing flow entry's match values/masks
    2864                 :            :  */
    2865                 :            : static void
    2866                 :          0 : ice_flow_acl_frmt_entry_fld(u16 fld, struct ice_flow_fld_info *info, u8 *buf,
    2867                 :            :                             u8 *dontcare, u8 *data)
    2868                 :            : {
    2869                 :            :         u16 dst, src, mask, k, end_disp, tmp_s = 0, tmp_m = 0;
    2870                 :            :         bool use_mask = false;
    2871                 :            :         u8 disp;
    2872                 :            : 
    2873                 :          0 :         src = info->src.val;
    2874                 :          0 :         mask = info->src.mask;
    2875                 :          0 :         dst = info->entry.val - ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
    2876                 :          0 :         disp = info->xtrct.disp % BITS_PER_BYTE;
    2877                 :            : 
    2878         [ #  # ]:          0 :         if (mask != ICE_FLOW_FLD_OFF_INVAL)
    2879                 :            :                 use_mask = true;
    2880                 :            : 
    2881         [ #  # ]:          0 :         for (k = 0; k < info->entry.last; k++, dst++) {
    2882                 :            :                 /* Add overflow bits from previous byte */
    2883                 :          0 :                 buf[dst] = (tmp_s & 0xff00) >> 8;
    2884                 :            : 
    2885                 :            :                 /* If mask is not valid, tmp_m is always zero, so just setting
    2886                 :            :                  * dontcare to 0 (no masked bits). If mask is valid, pulls in
    2887                 :            :                  * overflow bits of mask from prev byte
    2888                 :            :                  */
    2889                 :          0 :                 dontcare[dst] = (tmp_m & 0xff00) >> 8;
    2890                 :            : 
    2891                 :            :                 /* If there is displacement, last byte will only contain
    2892                 :            :                  * displaced data, but there is no more data to read from user
    2893                 :            :                  * buffer, so skip so as not to potentially read beyond end of
    2894                 :            :                  * user buffer
    2895                 :            :                  */
    2896   [ #  #  #  # ]:          0 :                 if (!disp || k < info->entry.last - 1) {
    2897                 :            :                         /* Store shifted data to use in next byte */
    2898                 :          0 :                         tmp_s = data[src++] << disp;
    2899                 :            : 
    2900                 :            :                         /* Add current (shifted) byte */
    2901                 :          0 :                         buf[dst] |= tmp_s & 0xff;
    2902                 :            : 
    2903                 :            :                         /* Handle mask if valid */
    2904         [ #  # ]:          0 :                         if (use_mask) {
    2905                 :          0 :                                 tmp_m = (~data[mask++] & 0xff) << disp;
    2906                 :          0 :                                 dontcare[dst] |= tmp_m & 0xff;
    2907                 :            :                         }
    2908                 :            :                 }
    2909                 :            :         }
    2910                 :            : 
    2911                 :            :         /* Fill in don't care bits at beginning of field */
    2912         [ #  # ]:          0 :         if (disp) {
    2913                 :          0 :                 dst = info->entry.val - ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
    2914         [ #  # ]:          0 :                 for (k = 0; k < disp; k++)
    2915                 :          0 :                         dontcare[dst] |= BIT(k);
    2916                 :            :         }
    2917                 :            : 
    2918                 :          0 :         end_disp = (disp + ice_flds_info[fld].size) % BITS_PER_BYTE;
    2919                 :            : 
    2920                 :            :         /* Fill in don't care bits at end of field */
    2921         [ #  # ]:          0 :         if (end_disp) {
    2922                 :          0 :                 dst = info->entry.val - ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX +
    2923                 :          0 :                       info->entry.last - 1;
    2924         [ #  # ]:          0 :                 for (k = end_disp; k < BITS_PER_BYTE; k++)
    2925                 :          0 :                         dontcare[dst] |= BIT(k);
    2926                 :            :         }
    2927                 :          0 : }
    2928                 :            : 
    2929                 :            : /**
    2930                 :            :  * ice_flow_acl_frmt_entry - Format ACL entry
    2931                 :            :  * @hw: pointer to the hardware structure
    2932                 :            :  * @prof: pointer to flow profile
    2933                 :            :  * @e: pointer to the flow entry
    2934                 :            :  * @data: pointer to a data buffer containing flow entry's match values/masks
    2935                 :            :  * @acts: array of actions to be performed on a match
    2936                 :            :  * @acts_cnt: number of actions
    2937                 :            :  *
    2938                 :            :  * Formats the key (and key_inverse) to be matched from the data passed in,
    2939                 :            :  * along with data from the flow profile. This key/key_inverse pair makes up
    2940                 :            :  * the 'entry' for an ACL flow entry.
    2941                 :            :  */
    2942                 :            : static int
    2943                 :          0 : ice_flow_acl_frmt_entry(struct ice_hw *hw, struct ice_flow_prof *prof,
    2944                 :            :                         struct ice_flow_entry *e, u8 *data,
    2945                 :            :                         struct ice_flow_action *acts, u8 acts_cnt)
    2946                 :            : {
    2947                 :          0 :         u8 *buf = NULL, *dontcare = NULL, *key = NULL, range = 0, dir_flag_msk;
    2948                 :            :         struct ice_aqc_acl_profile_ranges *range_buf = NULL;
    2949                 :            :         bool cnt_alloc;
    2950                 :          0 :         u8 prof_id = 0;
    2951                 :            :         u16 i, buf_sz;
    2952                 :            :         int status;
    2953                 :            : 
    2954                 :          0 :         status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id, &prof_id);
    2955         [ #  # ]:          0 :         if (status)
    2956                 :            :                 return status;
    2957                 :            : 
    2958                 :            :         /* Format the result action */
    2959                 :            : 
    2960                 :          0 :         status = ice_flow_acl_check_actions(hw, acts, acts_cnt, &cnt_alloc);
    2961         [ #  # ]:          0 :         if (status)
    2962                 :            :                 return status;
    2963                 :            : 
    2964                 :            :         status = ICE_ERR_NO_MEMORY;
    2965                 :            : 
    2966                 :          0 :         e->acts = (struct ice_flow_action *)
    2967                 :          0 :                 ice_memdup(hw, acts, acts_cnt * sizeof(*acts),
    2968                 :            :                            ICE_NONDMA_TO_NONDMA);
    2969         [ #  # ]:          0 :         if (!e->acts)
    2970                 :          0 :                 goto out;
    2971                 :            : 
    2972                 :          0 :         e->acts_cnt = acts_cnt;
    2973                 :            : 
    2974                 :            :         /* Format the matching data */
    2975                 :          0 :         buf_sz = prof->cfg.scen->width;
    2976                 :          0 :         buf = (u8 *)ice_malloc(hw, buf_sz);
    2977         [ #  # ]:          0 :         if (!buf)
    2978                 :          0 :                 goto out;
    2979                 :            : 
    2980                 :          0 :         dontcare = (u8 *)ice_malloc(hw, buf_sz);
    2981         [ #  # ]:          0 :         if (!dontcare)
    2982                 :          0 :                 goto out;
    2983                 :            : 
    2984                 :            :         /* 'key' buffer will store both key and key_inverse, so must be twice
    2985                 :            :          * size of buf
    2986                 :            :          */
    2987                 :          0 :         key = (u8 *)ice_malloc(hw, buf_sz * 2);
    2988         [ #  # ]:          0 :         if (!key)
    2989                 :          0 :                 goto out;
    2990                 :            : 
    2991                 :            :         range_buf = (struct ice_aqc_acl_profile_ranges *)
    2992                 :          0 :                 ice_malloc(hw, sizeof(struct ice_aqc_acl_profile_ranges));
    2993         [ #  # ]:          0 :         if (!range_buf)
    2994                 :          0 :                 goto out;
    2995                 :            : 
    2996                 :            :         /* Set don't care mask to all 1's to start, will zero out used bytes */
    2997                 :            :         ice_memset(dontcare, 0xff, buf_sz, ICE_NONDMA_MEM);
    2998                 :            : 
    2999         [ #  # ]:          0 :         for (i = 0; i < prof->segs_cnt; i++) {
    3000                 :          0 :                 struct ice_flow_seg_info *seg = &prof->segs[i];
    3001                 :            :                 u16 j;
    3002                 :            : 
    3003         [ #  # ]:          0 :                 ice_for_each_set_bit(j, seg->match,
    3004                 :            :                                      (u16)ICE_FLOW_FIELD_IDX_MAX) {
    3005                 :          0 :                         struct ice_flow_fld_info *info = &seg->fields[j];
    3006                 :            : 
    3007         [ #  # ]:          0 :                         if (info->type == ICE_FLOW_FLD_TYPE_RANGE)
    3008                 :          0 :                                 ice_flow_acl_frmt_entry_range(j, info,
    3009                 :            :                                                               range_buf, data,
    3010                 :            :                                                               &range);
    3011                 :            :                         else
    3012                 :          0 :                                 ice_flow_acl_frmt_entry_fld(j, info, buf,
    3013                 :            :                                                             dontcare, data);
    3014                 :            :                 }
    3015                 :            : 
    3016         [ #  # ]:          0 :                 for (j = 0; j < seg->raws_cnt; j++) {
    3017                 :          0 :                         struct ice_flow_fld_info *info = &seg->raws[j].info;
    3018                 :            :                         u16 dst, src, mask, k;
    3019                 :            :                         bool use_mask = false;
    3020                 :            : 
    3021                 :          0 :                         src = info->src.val;
    3022                 :          0 :                         dst = info->entry.val -
    3023                 :            :                                         ICE_AQC_ACL_PROF_BYTE_SEL_START_IDX;
    3024                 :          0 :                         mask = info->src.mask;
    3025                 :            : 
    3026         [ #  # ]:          0 :                         if (mask != ICE_FLOW_FLD_OFF_INVAL)
    3027                 :            :                                 use_mask = true;
    3028                 :            : 
    3029         [ #  # ]:          0 :                         for (k = 0; k < info->entry.last; k++, dst++) {
    3030                 :          0 :                                 buf[dst] = data[src++];
    3031         [ #  # ]:          0 :                                 if (use_mask)
    3032                 :          0 :                                         dontcare[dst] = ~data[mask++];
    3033                 :            :                                 else
    3034                 :          0 :                                         dontcare[dst] = 0;
    3035                 :            :                         }
    3036                 :            :                 }
    3037                 :            :         }
    3038                 :            : 
    3039                 :          0 :         buf[prof->cfg.scen->pid_idx] = (u8)prof_id;
    3040                 :          0 :         dontcare[prof->cfg.scen->pid_idx] = 0;
    3041                 :            : 
    3042                 :            :         /* Format the buffer for direction flags */
    3043                 :            :         dir_flag_msk = BIT(ICE_FLG_PKT_DIR);
    3044                 :            : 
    3045         [ #  # ]:          0 :         if (prof->dir == ICE_FLOW_RX)
    3046                 :          0 :                 buf[prof->cfg.scen->pkt_dir_idx] = dir_flag_msk;
    3047                 :            : 
    3048         [ #  # ]:          0 :         if (range) {
    3049                 :          0 :                 buf[prof->cfg.scen->rng_chk_idx] = range;
    3050                 :            :                 /* Mark any unused range checkers as don't care */
    3051                 :          0 :                 dontcare[prof->cfg.scen->rng_chk_idx] = ~range;
    3052                 :          0 :                 e->range_buf = range_buf;
    3053                 :            :         } else {
    3054                 :          0 :                 ice_free(hw, range_buf);
    3055                 :            :         }
    3056                 :            : 
    3057                 :          0 :         status = ice_set_key(key, buf_sz * 2, buf, NULL, dontcare, NULL, 0,
    3058                 :            :                              buf_sz);
    3059         [ #  # ]:          0 :         if (status)
    3060                 :          0 :                 goto out;
    3061                 :            : 
    3062                 :          0 :         e->entry = key;
    3063                 :          0 :         e->entry_sz = buf_sz * 2;
    3064                 :            : 
    3065                 :          0 : out:
    3066         [ #  # ]:          0 :         if (buf)
    3067                 :          0 :                 ice_free(hw, buf);
    3068                 :            : 
    3069         [ #  # ]:          0 :         if (dontcare)
    3070                 :          0 :                 ice_free(hw, dontcare);
    3071                 :            : 
    3072         [ #  # ]:          0 :         if (status && key)
    3073                 :          0 :                 ice_free(hw, key);
    3074                 :            : 
    3075         [ #  # ]:          0 :         if (status && range_buf) {
    3076                 :          0 :                 ice_free(hw, range_buf);
    3077                 :          0 :                 e->range_buf = NULL;
    3078                 :            :         }
    3079                 :            : 
    3080   [ #  #  #  # ]:          0 :         if (status && e->acts) {
    3081                 :          0 :                 ice_free(hw, e->acts);
    3082                 :          0 :                 e->acts = NULL;
    3083                 :          0 :                 e->acts_cnt = 0;
    3084                 :            :         }
    3085                 :            : 
    3086   [ #  #  #  # ]:          0 :         if (status && cnt_alloc)
    3087                 :          0 :                 ice_flow_acl_free_act_cntr(hw, acts, acts_cnt);
    3088                 :            : 
    3089                 :            :         return status;
    3090                 :            : }
    3091                 :            : 
    3092                 :            : /**
    3093                 :            :  * ice_flow_acl_find_scen_entry_cond - Find an ACL scenario entry that matches
    3094                 :            :  *                                     the compared data.
    3095                 :            :  * @prof: pointer to flow profile
    3096                 :            :  * @e: pointer to the comparing flow entry
    3097                 :            :  * @do_chg_action: decide if we want to change the ACL action
    3098                 :            :  * @do_add_entry: decide if we want to add the new ACL entry
    3099                 :            :  * @do_rem_entry: decide if we want to remove the current ACL entry
    3100                 :            :  *
    3101                 :            :  * Find an ACL scenario entry that matches the compared data. In the same time,
    3102                 :            :  * this function also figure out:
    3103                 :            :  * a/ If we want to change the ACL action
    3104                 :            :  * b/ If we want to add the new ACL entry
    3105                 :            :  * c/ If we want to remove the current ACL entry
    3106                 :            :  */
    3107                 :            : static struct ice_flow_entry *
    3108                 :          0 : ice_flow_acl_find_scen_entry_cond(struct ice_flow_prof *prof,
    3109                 :            :                                   struct ice_flow_entry *e, bool *do_chg_action,
    3110                 :            :                                   bool *do_add_entry, bool *do_rem_entry)
    3111                 :            : {
    3112                 :            :         struct ice_flow_entry *p, *return_entry = NULL;
    3113                 :            :         u8 i, j;
    3114                 :            : 
    3115                 :            :         /* Check if:
    3116                 :            :          * a/ There exists an entry with same matching data, but different
    3117                 :            :          *    priority, then we remove this existing ACL entry. Then, we
    3118                 :            :          *    will add the new entry to the ACL scenario.
    3119                 :            :          * b/ There exists an entry with same matching data, priority, and
    3120                 :            :          *    result action, then we do nothing
    3121                 :            :          * c/ There exists an entry with same matching data, priority, but
    3122                 :            :          *    different, action, then do only change the action's entry.
    3123                 :            :          * d/ Else, we add this new entry to the ACL scenario.
    3124                 :            :          */
    3125                 :          0 :         *do_chg_action = false;
    3126                 :          0 :         *do_add_entry = true;
    3127                 :          0 :         *do_rem_entry = false;
    3128   [ #  #  #  # ]:          0 :         LIST_FOR_EACH_ENTRY(p, &prof->entries, ice_flow_entry, l_entry) {
    3129   [ #  #  #  # ]:          0 :                 if (memcmp(p->entry, e->entry, p->entry_sz))
    3130                 :            :                         continue;
    3131                 :            : 
    3132                 :            :                 /* From this point, we have the same matching_data. */
    3133                 :          0 :                 *do_add_entry = false;
    3134                 :            :                 return_entry = p;
    3135                 :            : 
    3136         [ #  # ]:          0 :                 if (p->priority != e->priority) {
    3137                 :            :                         /* matching data && !priority */
    3138                 :          0 :                         *do_add_entry = true;
    3139                 :          0 :                         *do_rem_entry = true;
    3140                 :          0 :                         break;
    3141                 :            :                 }
    3142                 :            : 
    3143                 :            :                 /* From this point, we will have matching_data && priority */
    3144         [ #  # ]:          0 :                 if (p->acts_cnt != e->acts_cnt)
    3145                 :          0 :                         *do_chg_action = true;
    3146         [ #  # ]:          0 :                 for (i = 0; i < p->acts_cnt; i++) {
    3147                 :            :                         bool found_not_match = false;
    3148                 :            : 
    3149         [ #  # ]:          0 :                         for (j = 0; j < e->acts_cnt; j++)
    3150         [ #  # ]:          0 :                                 if (memcmp(&p->acts[i], &e->acts[j],
    3151                 :            :                                            sizeof(struct ice_flow_action))) {
    3152                 :            :                                         found_not_match = true;
    3153                 :            :                                         break;
    3154                 :            :                                 }
    3155                 :            : 
    3156         [ #  # ]:          0 :                         if (found_not_match) {
    3157                 :          0 :                                 *do_chg_action = true;
    3158                 :          0 :                                 break;
    3159                 :            :                         }
    3160                 :            :                 }
    3161                 :            : 
    3162                 :            :                 /* (do_chg_action = true) means :
    3163                 :            :                  *    matching_data && priority && !result_action
    3164                 :            :                  * (do_chg_action = false) means :
    3165                 :            :                  *    matching_data && priority && result_action
    3166                 :            :                  */
    3167                 :            :                 break;
    3168                 :            :         }
    3169                 :            : 
    3170                 :          0 :         return return_entry;
    3171                 :            : }
    3172                 :            : 
    3173                 :            : /**
    3174                 :            :  * ice_flow_acl_convert_to_acl_prio - Convert to ACL priority
    3175                 :            :  * @p: flow priority
    3176                 :            :  */
    3177                 :            : static enum ice_acl_entry_prio
    3178                 :            : ice_flow_acl_convert_to_acl_prio(enum ice_flow_priority p)
    3179                 :            : {
    3180                 :            :         enum ice_acl_entry_prio acl_prio;
    3181                 :            : 
    3182                 :            :         switch (p) {
    3183                 :            :         case ICE_FLOW_PRIO_LOW:
    3184                 :            :                 acl_prio = ICE_ACL_PRIO_LOW;
    3185                 :            :                 break;
    3186                 :            :         case ICE_FLOW_PRIO_NORMAL:
    3187                 :            :                 acl_prio = ICE_ACL_PRIO_NORMAL;
    3188                 :            :                 break;
    3189                 :            :         case ICE_FLOW_PRIO_HIGH:
    3190                 :            :                 acl_prio = ICE_ACL_PRIO_HIGH;
    3191                 :            :                 break;
    3192                 :            :         default:
    3193                 :            :                 acl_prio = ICE_ACL_PRIO_NORMAL;
    3194                 :            :                 break;
    3195                 :            :         }
    3196                 :            : 
    3197                 :            :         return acl_prio;
    3198                 :            : }
    3199                 :            : 
    3200                 :            : /**
    3201                 :            :  * ice_flow_acl_union_rng_chk - Perform union operation between two
    3202                 :            :  *                              range-range checker buffers
    3203                 :            :  * @dst_buf: pointer to destination range checker buffer
    3204                 :            :  * @src_buf: pointer to source range checker buffer
    3205                 :            :  *
    3206                 :            :  * For this function, we do the union between dst_buf and src_buf
    3207                 :            :  * range checker buffer, and we will save the result back to dst_buf
    3208                 :            :  */
    3209                 :            : static int
    3210                 :          0 : ice_flow_acl_union_rng_chk(struct ice_aqc_acl_profile_ranges *dst_buf,
    3211                 :            :                            struct ice_aqc_acl_profile_ranges *src_buf)
    3212                 :            : {
    3213                 :            :         u8 i, j;
    3214                 :            : 
    3215         [ #  # ]:          0 :         if (!dst_buf || !src_buf)
    3216                 :            :                 return ICE_ERR_BAD_PTR;
    3217                 :            : 
    3218         [ #  # ]:          0 :         for (i = 0; i < ICE_AQC_ACL_PROF_RANGES_NUM_CFG; i++) {
    3219                 :            :                 struct ice_acl_rng_data *cfg_data = NULL, *in_data;
    3220                 :            :                 bool will_populate = false;
    3221                 :            : 
    3222                 :          0 :                 in_data = &src_buf->checker_cfg[i];
    3223                 :            : 
    3224         [ #  # ]:          0 :                 if (!in_data->mask)
    3225                 :            :                         break;
    3226                 :            : 
    3227         [ #  # ]:          0 :                 for (j = 0; j < ICE_AQC_ACL_PROF_RANGES_NUM_CFG; j++) {
    3228                 :          0 :                         cfg_data = &dst_buf->checker_cfg[j];
    3229                 :            : 
    3230         [ #  # ]:          0 :                         if (!cfg_data->mask ||
    3231         [ #  # ]:          0 :                             !memcmp(cfg_data, in_data,
    3232                 :            :                                     sizeof(struct ice_acl_rng_data))) {
    3233                 :            :                                 will_populate = true;
    3234                 :            :                                 break;
    3235                 :            :                         }
    3236                 :            :                 }
    3237                 :            : 
    3238         [ #  # ]:          0 :                 if (will_populate) {
    3239                 :            :                         ice_memcpy(cfg_data, in_data,
    3240                 :            :                                    sizeof(struct ice_acl_rng_data),
    3241                 :            :                                    ICE_NONDMA_TO_NONDMA);
    3242                 :            :                 } else {
    3243                 :            :                         /* No available slot left to program range checker */
    3244                 :            :                         return ICE_ERR_MAX_LIMIT;
    3245                 :            :                 }
    3246                 :            :         }
    3247                 :            : 
    3248                 :            :         return 0;
    3249                 :            : }
    3250                 :            : 
    3251                 :            : /**
    3252                 :            :  * ice_flow_acl_add_scen_entry_sync - Add entry to ACL scenario sync
    3253                 :            :  * @hw: pointer to the hardware structure
    3254                 :            :  * @prof: pointer to flow profile
    3255                 :            :  * @entry: double pointer to the flow entry
    3256                 :            :  *
    3257                 :            :  * For this function, we will look at the current added entries in the
    3258                 :            :  * corresponding ACL scenario. Then, we will perform matching logic to
    3259                 :            :  * see if we want to add/modify/do nothing with this new entry.
    3260                 :            :  */
    3261                 :            : static int
    3262                 :          0 : ice_flow_acl_add_scen_entry_sync(struct ice_hw *hw, struct ice_flow_prof *prof,
    3263                 :            :                                  struct ice_flow_entry **entry)
    3264                 :            : {
    3265                 :            :         bool do_add_entry, do_rem_entry, do_chg_action, do_chg_rng_chk;
    3266                 :            :         struct ice_aqc_acl_profile_ranges query_rng_buf, cfg_rng_buf;
    3267                 :            :         struct ice_acl_act_entry *acts = NULL;
    3268                 :            :         struct ice_flow_entry *exist;
    3269                 :            :         struct ice_flow_entry *e;
    3270                 :            :         int status = 0;
    3271                 :            :         u8 i;
    3272                 :            : 
    3273   [ #  #  #  #  :          0 :         if (!entry || !(*entry) || !prof)
                   #  # ]
    3274                 :            :                 return ICE_ERR_BAD_PTR;
    3275                 :            : 
    3276                 :            :         e = *entry;
    3277                 :            : 
    3278                 :            :         do_chg_rng_chk = false;
    3279         [ #  # ]:          0 :         if (e->range_buf) {
    3280                 :          0 :                 u8 prof_id = 0;
    3281                 :            : 
    3282                 :          0 :                 status = ice_flow_get_hw_prof(hw, ICE_BLK_ACL, prof->id,
    3283                 :            :                                               &prof_id);
    3284         [ #  # ]:          0 :                 if (status)
    3285                 :          0 :                         return status;
    3286                 :            : 
    3287                 :            :                 /* Query the current range-checker value in FW */
    3288                 :          0 :                 status = ice_query_acl_prof_ranges(hw, prof_id, &query_rng_buf,
    3289                 :            :                                                    NULL);
    3290         [ #  # ]:          0 :                 if (status)
    3291                 :            :                         return status;
    3292                 :            :                 ice_memcpy(&cfg_rng_buf, &query_rng_buf,
    3293                 :            :                            sizeof(struct ice_aqc_acl_profile_ranges),
    3294                 :            :                            ICE_NONDMA_TO_NONDMA);
    3295                 :            : 
    3296                 :            :                 /* Generate the new range-checker value */
    3297                 :          0 :                 status = ice_flow_acl_union_rng_chk(&cfg_rng_buf, e->range_buf);
    3298         [ #  # ]:          0 :                 if (status)
    3299                 :            :                         return status;
    3300                 :            : 
    3301                 :            :                 /* Reconfigure the range check if the buffer is changed. */
    3302                 :            :                 do_chg_rng_chk = false;
    3303         [ #  # ]:          0 :                 if (memcmp(&query_rng_buf, &cfg_rng_buf,
    3304                 :            :                            sizeof(struct ice_aqc_acl_profile_ranges))) {
    3305                 :          0 :                         status = ice_prog_acl_prof_ranges(hw, prof_id,
    3306                 :            :                                                           &cfg_rng_buf, NULL);
    3307         [ #  # ]:          0 :                         if (status)
    3308                 :            :                                 return status;
    3309                 :            : 
    3310                 :            :                         do_chg_rng_chk = true;
    3311                 :            :                 }
    3312                 :            :         }
    3313                 :            : 
    3314                 :            :         /* Figure out if we want to (change the ACL action) and/or
    3315                 :            :          * (Add the new ACL entry) and/or (Remove the current ACL entry)
    3316                 :            :          */
    3317                 :          0 :         exist = ice_flow_acl_find_scen_entry_cond(prof, e, &do_chg_action,
    3318                 :            :                                                   &do_add_entry, &do_rem_entry);
    3319         [ #  # ]:          0 :         if (do_rem_entry) {
    3320                 :          0 :                 status = ice_flow_rem_entry_sync(hw, ICE_BLK_ACL, exist);
    3321         [ #  # ]:          0 :                 if (status)
    3322                 :            :                         return status;
    3323                 :            :         }
    3324                 :            : 
    3325                 :            :         /* Prepare the result action buffer */
    3326                 :            :         acts = (struct ice_acl_act_entry *)
    3327                 :          0 :                 ice_calloc(hw, e->entry_sz, sizeof(struct ice_acl_act_entry));
    3328         [ #  # ]:          0 :         if (!acts)
    3329                 :            :                 return ICE_ERR_NO_MEMORY;
    3330                 :            : 
    3331         [ #  # ]:          0 :         for (i = 0; i < e->acts_cnt; i++)
    3332         [ #  # ]:          0 :                 ice_memcpy(&acts[i], &e->acts[i].data.acl_act,
    3333                 :            :                            sizeof(struct ice_acl_act_entry),
    3334                 :            :                            ICE_NONDMA_TO_NONDMA);
    3335                 :            : 
    3336         [ #  # ]:          0 :         if (do_add_entry) {
    3337                 :            :                 enum ice_acl_entry_prio prio;
    3338                 :            :                 u8 *keys, *inverts;
    3339                 :            :                 u16 entry_idx;
    3340                 :            : 
    3341                 :          0 :                 keys = (u8 *)e->entry;
    3342                 :          0 :                 inverts = keys + (e->entry_sz / 2);
    3343         [ #  # ]:          0 :                 prio = ice_flow_acl_convert_to_acl_prio(e->priority);
    3344                 :            : 
    3345                 :          0 :                 status = ice_acl_add_entry(hw, prof->cfg.scen, prio, keys,
    3346                 :            :                                            inverts, acts, e->acts_cnt,
    3347                 :            :                                            &entry_idx);
    3348         [ #  # ]:          0 :                 if (status)
    3349                 :          0 :                         goto out;
    3350                 :            : 
    3351                 :          0 :                 e->scen_entry_idx = entry_idx;
    3352         [ #  # ]:          0 :                 LIST_ADD(&e->l_entry, &prof->entries);
    3353                 :            :         } else {
    3354         [ #  # ]:          0 :                 if (do_chg_action) {
    3355                 :            :                         /* For the action memory info, update the SW's copy of
    3356                 :            :                          * exist entry with e's action memory info
    3357                 :            :                          */
    3358                 :          0 :                         ice_free(hw, exist->acts);
    3359                 :          0 :                         exist->acts_cnt = e->acts_cnt;
    3360                 :          0 :                         exist->acts = (struct ice_flow_action *)
    3361                 :          0 :                                 ice_calloc(hw, exist->acts_cnt,
    3362                 :            :                                            sizeof(struct ice_flow_action));
    3363         [ #  # ]:          0 :                         if (!exist->acts) {
    3364                 :            :                                 status = ICE_ERR_NO_MEMORY;
    3365                 :          0 :                                 goto out;
    3366                 :            :                         }
    3367                 :            : 
    3368         [ #  # ]:          0 :                         ice_memcpy(exist->acts, e->acts,
    3369                 :            :                                    sizeof(struct ice_flow_action) * e->acts_cnt,
    3370                 :            :                                    ICE_NONDMA_TO_NONDMA);
    3371                 :            : 
    3372                 :          0 :                         status = ice_acl_prog_act(hw, prof->cfg.scen, acts,
    3373                 :          0 :                                                   e->acts_cnt,
    3374                 :          0 :                                                   exist->scen_entry_idx);
    3375         [ #  # ]:          0 :                         if (status)
    3376                 :          0 :                                 goto out;
    3377                 :            :                 }
    3378                 :            : 
    3379         [ #  # ]:          0 :                 if (do_chg_rng_chk) {
    3380                 :            :                         /* In this case, we want to update the range checker
    3381                 :            :                          * information of the exist entry
    3382                 :            :                          */
    3383                 :          0 :                         status = ice_flow_acl_union_rng_chk(exist->range_buf,
    3384                 :            :                                                             e->range_buf);
    3385         [ #  # ]:          0 :                         if (status)
    3386                 :          0 :                                 goto out;
    3387                 :            :                 }
    3388                 :            : 
    3389                 :            :                 /* As we don't add the new entry to our SW DB, deallocate its
    3390                 :            :                  * memories, and return the exist entry to the caller
    3391                 :            :                  */
    3392                 :          0 :                 ice_dealloc_flow_entry(hw, e);
    3393                 :          0 :                 *(entry) = exist;
    3394                 :            :         }
    3395                 :          0 : out:
    3396                 :          0 :         ice_free(hw, acts);
    3397                 :            : 
    3398                 :          0 :         return status;
    3399                 :            : }
    3400                 :            : 
    3401                 :            : /**
    3402                 :            :  * ice_flow_acl_add_scen_entry - Add entry to ACL scenario
    3403                 :            :  * @hw: pointer to the hardware structure
    3404                 :            :  * @prof: pointer to flow profile
    3405                 :            :  * @e: double pointer to the flow entry
    3406                 :            :  */
    3407                 :            : static int
    3408                 :          0 : ice_flow_acl_add_scen_entry(struct ice_hw *hw, struct ice_flow_prof *prof,
    3409                 :            :                             struct ice_flow_entry **e)
    3410                 :            : {
    3411                 :            :         int status;
    3412                 :            : 
    3413                 :          0 :         ice_acquire_lock(&prof->entries_lock);
    3414                 :          0 :         status = ice_flow_acl_add_scen_entry_sync(hw, prof, e);
    3415                 :            :         ice_release_lock(&prof->entries_lock);
    3416                 :            : 
    3417                 :          0 :         return status;
    3418                 :            : }
    3419                 :            : 
    3420                 :            : /**
    3421                 :            :  * ice_flow_add_entry - Add a flow entry
    3422                 :            :  * @hw: pointer to the HW struct
    3423                 :            :  * @blk: classification stage
    3424                 :            :  * @prof_id: ID of the profile to add a new flow entry to
    3425                 :            :  * @entry_id: unique ID to identify this flow entry
    3426                 :            :  * @vsi_handle: software VSI handle for the flow entry
    3427                 :            :  * @prio: priority of the flow entry
    3428                 :            :  * @data: pointer to a data buffer containing flow entry's match values/masks
    3429                 :            :  * @acts: arrays of actions to be performed on a match
    3430                 :            :  * @acts_cnt: number of actions
    3431                 :            :  * @entry_h: pointer to buffer that receives the new flow entry's handle
    3432                 :            :  */
    3433                 :            : int
    3434                 :          0 : ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
    3435                 :            :                    u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
    3436                 :            :                    void *data, struct ice_flow_action *acts, u8 acts_cnt,
    3437                 :            :                    u64 *entry_h)
    3438                 :            : {
    3439                 :          0 :         struct ice_flow_entry *e = NULL;
    3440                 :            :         struct ice_flow_prof *prof;
    3441                 :            :         int status = 0;
    3442                 :            : 
    3443                 :            :         /* ACL entries must indicate an action */
    3444   [ #  #  #  # ]:          0 :         if (blk == ICE_BLK_ACL && (!acts || !acts_cnt))
    3445                 :            :                 return ICE_ERR_PARAM;
    3446                 :            : 
    3447                 :            :         /* No flow entry data is expected for RSS */
    3448   [ #  #  #  # ]:          0 :         if (!entry_h || (!data && blk != ICE_BLK_RSS))
    3449                 :            :                 return ICE_ERR_BAD_PTR;
    3450                 :            : 
    3451         [ #  # ]:          0 :         if (!ice_is_vsi_valid(hw, vsi_handle))
    3452                 :            :                 return ICE_ERR_PARAM;
    3453                 :            : 
    3454                 :          0 :         ice_acquire_lock(&hw->fl_profs_locks[blk]);
    3455                 :            : 
    3456                 :            :         prof = ice_flow_find_prof_id(hw, blk, prof_id);
    3457         [ #  # ]:          0 :         if (!prof) {
    3458                 :            :                 status = ICE_ERR_DOES_NOT_EXIST;
    3459                 :            :         } else {
    3460                 :            :                 /* Allocate memory for the entry being added and associate
    3461                 :            :                  * the VSI to the found flow profile
    3462                 :            :                  */
    3463                 :          0 :                 e = (struct ice_flow_entry *)ice_malloc(hw, sizeof(*e));
    3464         [ #  # ]:          0 :                 if (!e)
    3465                 :            :                         status = ICE_ERR_NO_MEMORY;
    3466                 :            :                 else
    3467                 :          0 :                         status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
    3468                 :            :         }
    3469                 :            : 
    3470                 :            :         ice_release_lock(&hw->fl_profs_locks[blk]);
    3471         [ #  # ]:          0 :         if (status)
    3472                 :          0 :                 goto out;
    3473                 :            : 
    3474                 :          0 :         e->id = entry_id;
    3475                 :          0 :         e->vsi_handle = vsi_handle;
    3476                 :          0 :         e->prof = prof;
    3477                 :          0 :         e->priority = prio;
    3478                 :            : 
    3479      [ #  #  # ]:          0 :         switch (blk) {
    3480                 :            :         case ICE_BLK_FD:
    3481                 :            :         case ICE_BLK_RSS:
    3482                 :            :                 break;
    3483                 :          0 :         case ICE_BLK_ACL:
    3484                 :            :                 /* ACL will handle the entry management */
    3485                 :          0 :                 status = ice_flow_acl_frmt_entry(hw, prof, e, (u8 *)data, acts,
    3486                 :            :                                                  acts_cnt);
    3487         [ #  # ]:          0 :                 if (status)
    3488                 :          0 :                         goto out;
    3489                 :            : 
    3490                 :          0 :                 status = ice_flow_acl_add_scen_entry(hw, prof, &e);
    3491         [ #  # ]:          0 :                 if (status)
    3492                 :          0 :                         goto out;
    3493                 :            : 
    3494                 :            :                 break;
    3495                 :          0 :         default:
    3496                 :            :                 status = ICE_ERR_NOT_IMPL;
    3497                 :          0 :                 goto out;
    3498                 :            :         }
    3499                 :            : 
    3500         [ #  # ]:          0 :         if (blk != ICE_BLK_ACL) {
    3501                 :            :                 /* ACL will handle the entry management */
    3502                 :          0 :                 ice_acquire_lock(&prof->entries_lock);
    3503         [ #  # ]:          0 :                 LIST_ADD(&e->l_entry, &prof->entries);
    3504                 :            :                 ice_release_lock(&prof->entries_lock);
    3505                 :            :         }
    3506                 :            : 
    3507                 :          0 :         *entry_h = ICE_FLOW_ENTRY_HNDL(e);
    3508                 :            : 
    3509                 :          0 : out:
    3510   [ #  #  #  # ]:          0 :         if (status && e) {
    3511         [ #  # ]:          0 :                 if (e->entry)
    3512                 :          0 :                         ice_free(hw, e->entry);
    3513                 :          0 :                 ice_free(hw, e);
    3514                 :            :         }
    3515                 :            : 
    3516                 :            :         return status;
    3517                 :            : }
    3518                 :            : 
    3519                 :            : /**
    3520                 :            :  * ice_flow_rem_entry - Remove a flow entry
    3521                 :            :  * @hw: pointer to the HW struct
    3522                 :            :  * @blk: classification stage
    3523                 :            :  * @entry_h: handle to the flow entry to be removed
    3524                 :            :  */
    3525                 :          0 : int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk,
    3526                 :            :                        u64 entry_h)
    3527                 :            : {
    3528                 :            :         struct ice_flow_entry *entry;
    3529                 :            :         struct ice_flow_prof *prof;
    3530                 :            :         int status = 0;
    3531                 :            : 
    3532         [ #  # ]:          0 :         if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
    3533                 :            :                 return ICE_ERR_PARAM;
    3534                 :            : 
    3535                 :          0 :         entry = ICE_FLOW_ENTRY_PTR((intptr_t)entry_h);
    3536                 :            : 
    3537                 :            :         /* Retain the pointer to the flow profile as the entry will be freed */
    3538                 :          0 :         prof = entry->prof;
    3539                 :            : 
    3540         [ #  # ]:          0 :         if (prof) {
    3541                 :          0 :                 ice_acquire_lock(&prof->entries_lock);
    3542                 :          0 :                 status = ice_flow_rem_entry_sync(hw, blk, entry);
    3543                 :            :                 ice_release_lock(&prof->entries_lock);
    3544                 :            :         }
    3545                 :            : 
    3546                 :            :         return status;
    3547                 :            : }
    3548                 :            : 
    3549                 :            : /**
    3550                 :            :  * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
    3551                 :            :  * @seg: packet segment the field being set belongs to
    3552                 :            :  * @fld: field to be set
    3553                 :            :  * @field_type: type of the field
    3554                 :            :  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
    3555                 :            :  *           entry's input buffer
    3556                 :            :  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
    3557                 :            :  *            input buffer
    3558                 :            :  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
    3559                 :            :  *            entry's input buffer
    3560                 :            :  *
    3561                 :            :  * This helper function stores information of a field being matched, including
    3562                 :            :  * the type of the field and the locations of the value to match, the mask, and
    3563                 :            :  * the upper-bound value in the start of the input buffer for a flow entry.
    3564                 :            :  * This function should only be used for fixed-size data structures.
    3565                 :            :  *
    3566                 :            :  * This function also opportunistically determines the protocol headers to be
    3567                 :            :  * present based on the fields being set. Some fields cannot be used alone to
    3568                 :            :  * determine the protocol headers present. Sometimes, fields for particular
    3569                 :            :  * protocol headers are not matched. In those cases, the protocol headers
    3570                 :            :  * must be explicitly set.
    3571                 :            :  */
    3572                 :            : static void
    3573                 :          0 : ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
    3574                 :            :                      enum ice_flow_fld_match_type field_type, u16 val_loc,
    3575                 :            :                      u16 mask_loc, u16 last_loc)
    3576                 :            : {
    3577         [ #  # ]:          0 :         ice_set_bit(fld, seg->match);
    3578         [ #  # ]:          0 :         if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
    3579                 :          0 :                 ice_set_bit(fld, seg->range);
    3580                 :            : 
    3581                 :          0 :         seg->fields[fld].type = field_type;
    3582                 :          0 :         seg->fields[fld].src.val = val_loc;
    3583                 :          0 :         seg->fields[fld].src.mask = mask_loc;
    3584                 :          0 :         seg->fields[fld].src.last = last_loc;
    3585                 :            : 
    3586                 :          0 :         ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
    3587                 :          0 : }
    3588                 :            : 
    3589                 :            : /**
    3590                 :            :  * ice_flow_set_fld - specifies locations of field from entry's input buffer
    3591                 :            :  * @seg: packet segment the field being set belongs to
    3592                 :            :  * @fld: field to be set
    3593                 :            :  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
    3594                 :            :  *           entry's input buffer
    3595                 :            :  * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
    3596                 :            :  *            input buffer
    3597                 :            :  * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
    3598                 :            :  *            entry's input buffer
    3599                 :            :  * @range: indicate if field being matched is to be in a range
    3600                 :            :  *
    3601                 :            :  * This function specifies the locations, in the form of byte offsets from the
    3602                 :            :  * start of the input buffer for a flow entry, from where the value to match,
    3603                 :            :  * the mask value, and upper value can be extracted. These locations are then
    3604                 :            :  * stored in the flow profile. When adding a flow entry associated with the
    3605                 :            :  * flow profile, these locations will be used to quickly extract the values and
    3606                 :            :  * create the content of a match entry. This function should only be used for
    3607                 :            :  * fixed-size data structures.
    3608                 :            :  */
    3609                 :            : void
    3610                 :          0 : ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
    3611                 :            :                  u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
    3612                 :            : {
    3613                 :          0 :         enum ice_flow_fld_match_type t = range ?
    3614                 :            :                 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
    3615                 :            : 
    3616                 :          0 :         ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
    3617                 :          0 : }
    3618                 :            : 
    3619                 :            : /**
    3620                 :            :  * ice_flow_set_fld_prefix - sets locations of prefix field from entry's buf
    3621                 :            :  * @seg: packet segment the field being set belongs to
    3622                 :            :  * @fld: field to be set
    3623                 :            :  * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
    3624                 :            :  *           entry's input buffer
    3625                 :            :  * @pref_loc: location of prefix value from entry's input buffer
    3626                 :            :  * @pref_sz: size of the location holding the prefix value
    3627                 :            :  *
    3628                 :            :  * This function specifies the locations, in the form of byte offsets from the
    3629                 :            :  * start of the input buffer for a flow entry, from where the value to match
    3630                 :            :  * and the IPv4 prefix value can be extracted. These locations are then stored
    3631                 :            :  * in the flow profile. When adding flow entries to the associated flow profile,
    3632                 :            :  * these locations can be used to quickly extract the values to create the
    3633                 :            :  * content of a match entry. This function should only be used for fixed-size
    3634                 :            :  * data structures.
    3635                 :            :  */
    3636                 :            : void
    3637                 :          0 : ice_flow_set_fld_prefix(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
    3638                 :            :                         u16 val_loc, u16 pref_loc, u8 pref_sz)
    3639                 :            : {
    3640                 :            :         /* For this type of field, the "mask" location is for the prefix value's
    3641                 :            :          * location and the "last" location is for the size of the location of
    3642                 :            :          * the prefix value.
    3643                 :            :          */
    3644                 :            :         ice_flow_set_fld_ext(seg, fld, ICE_FLOW_FLD_TYPE_PREFIX, val_loc,
    3645                 :            :                              pref_loc, (u16)pref_sz);
    3646                 :          0 : }
    3647                 :            : 
    3648                 :            : /**
    3649                 :            :  * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
    3650                 :            :  * @seg: packet segment the field being set belongs to
    3651                 :            :  * @off: offset of the raw field from the beginning of the segment in bytes
    3652                 :            :  * @len: length of the raw pattern to be matched
    3653                 :            :  * @val_loc: location of the value to match from entry's input buffer
    3654                 :            :  * @mask_loc: location of mask value from entry's input buffer
    3655                 :            :  *
    3656                 :            :  * This function specifies the offset of the raw field to be match from the
    3657                 :            :  * beginning of the specified packet segment, and the locations, in the form of
    3658                 :            :  * byte offsets from the start of the input buffer for a flow entry, from where
    3659                 :            :  * the value to match and the mask value to be extracted. These locations are
    3660                 :            :  * then stored in the flow profile. When adding flow entries to the associated
    3661                 :            :  * flow profile, these locations can be used to quickly extract the values to
    3662                 :            :  * create the content of a match entry. This function should only be used for
    3663                 :            :  * fixed-size data structures.
    3664                 :            :  */
    3665                 :            : void
    3666                 :          0 : ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
    3667                 :            :                      u16 val_loc, u16 mask_loc)
    3668                 :            : {
    3669         [ #  # ]:          0 :         if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
    3670                 :          0 :                 seg->raws[seg->raws_cnt].off = off;
    3671                 :          0 :                 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
    3672                 :          0 :                 seg->raws[seg->raws_cnt].info.src.val = val_loc;
    3673                 :          0 :                 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
    3674                 :            :                 /* The "last" field is used to store the length of the field */
    3675                 :          0 :                 seg->raws[seg->raws_cnt].info.src.last = len;
    3676                 :            :         }
    3677                 :            : 
    3678                 :            :         /* Overflows of "raws" will be handled as an error condition later in
    3679                 :            :          * the flow when this information is processed.
    3680                 :            :          */
    3681                 :          0 :         seg->raws_cnt++;
    3682                 :          0 : }
    3683                 :            : 
    3684                 :            : /**
    3685                 :            :  * ice_flow_rem_vsi_prof - remove vsi from flow profile
    3686                 :            :  * @hw: pointer to the hardware structure
    3687                 :            :  * @blk: classification stage
    3688                 :            :  * @vsi_handle: software VSI handle
    3689                 :            :  * @prof_id: unique ID to identify this flow profile
    3690                 :            :  *
    3691                 :            :  * This function removes the flow entries associated to the input
    3692                 :            :  * vsi handle and disassociates the vsi from the flow profile.
    3693                 :            :  */
    3694                 :          0 : int ice_flow_rem_vsi_prof(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
    3695                 :            :                           u64 prof_id)
    3696                 :            : {
    3697                 :            :         struct ice_flow_prof *prof = NULL;
    3698                 :            :         int status = 0;
    3699                 :            : 
    3700   [ #  #  #  # ]:          0 :         if (blk >= ICE_BLK_COUNT || !ice_is_vsi_valid(hw, vsi_handle))
    3701                 :          0 :                 return ICE_ERR_PARAM;
    3702                 :            : 
    3703                 :            :         /* find flow profile pointer with input package block and profile id */
    3704                 :            :         prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
    3705         [ #  # ]:          0 :         if (!prof) {
    3706         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_PKG,
    3707                 :            :                           "Cannot find flow profile id=%" PRIu64 "\n", prof_id);
    3708                 :          0 :                 return ICE_ERR_DOES_NOT_EXIST;
    3709                 :            :         }
    3710                 :            : 
    3711                 :            :         /* Remove all remaining flow entries before removing the flow profile */
    3712         [ #  # ]:          0 :         if (!LIST_EMPTY(&prof->entries)) {
    3713                 :            :                 struct ice_flow_entry *e, *t;
    3714                 :            : 
    3715                 :          0 :                 ice_acquire_lock(&prof->entries_lock);
    3716   [ #  #  #  #  :          0 :                 LIST_FOR_EACH_ENTRY_SAFE(e, t, &prof->entries, ice_flow_entry,
          #  #  #  #  #  
                      # ]
    3717                 :            :                                          l_entry) {
    3718         [ #  # ]:          0 :                         if (e->vsi_handle != vsi_handle)
    3719                 :          0 :                                 continue;
    3720                 :            : 
    3721                 :          0 :                         status = ice_flow_rem_entry_sync(hw, blk, e);
    3722         [ #  # ]:          0 :                         if (status)
    3723                 :            :                                 break;
    3724                 :            :                 }
    3725                 :            :                 ice_release_lock(&prof->entries_lock);
    3726                 :            :         }
    3727         [ #  # ]:          0 :         if (status)
    3728                 :            :                 return status;
    3729                 :            : 
    3730                 :            :         /* disassociate the flow profile from sw vsi handle */
    3731                 :          0 :         status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
    3732         [ #  # ]:          0 :         if (status)
    3733         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_PKG,
    3734                 :            :                           "ice_flow_disassoc_prof() failed with status=%d\n",
    3735                 :            :                           status);
    3736                 :            :         return status;
    3737                 :            : }
    3738                 :            : 
    3739                 :            : #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
    3740                 :            : (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_ETH_NON_IP | ICE_FLOW_SEG_HDR_VLAN)
    3741                 :            : 
    3742                 :            : #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
    3743                 :            :         (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
    3744                 :            : 
    3745                 :            : #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
    3746                 :            :         (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
    3747                 :            : 
    3748                 :            : #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
    3749                 :            :         (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
    3750                 :            :          ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
    3751                 :            :          ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
    3752                 :            : 
    3753                 :            : /**
    3754                 :            :  * ice_flow_set_rss_seg_info - setup packet segments for RSS
    3755                 :            :  * @segs: pointer to the flow field segment(s)
    3756                 :            :  * @seg_cnt: segment count
    3757                 :            :  * @cfg: configure parameters
    3758                 :            :  *
    3759                 :            :  * Helper function to extract fields from hash bitmap and use flow
    3760                 :            :  * header value to set flow field segment for further use in flow
    3761                 :            :  * profile entry or removal.
    3762                 :            :  */
    3763                 :            : static int
    3764                 :          0 : ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt,
    3765                 :            :                           const struct ice_rss_hash_cfg *cfg)
    3766                 :            : {
    3767                 :            :         struct ice_flow_seg_info *seg;
    3768                 :            :         u64 val;
    3769                 :            :         u16 i;
    3770                 :            : 
    3771                 :            :         /* set inner most segment */
    3772                 :          0 :         seg = &segs[seg_cnt - 1];
    3773                 :            : 
    3774         [ #  # ]:          0 :         ice_for_each_set_bit(i, (const ice_bitmap_t *)&cfg->hash_flds,
    3775                 :            :                              (u16)ICE_FLOW_FIELD_IDX_MAX)
    3776                 :          0 :                 ice_flow_set_fld(seg, (enum ice_flow_field)i,
    3777                 :            :                                  ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
    3778                 :            :                                  ICE_FLOW_FLD_OFF_INVAL, false);
    3779                 :            : 
    3780                 :          0 :         ICE_FLOW_SET_HDRS(seg, cfg->addl_hdrs);
    3781                 :            : 
    3782                 :            :         /* set outer most header */
    3783         [ #  # ]:          0 :         if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4)
    3784                 :          0 :                 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
    3785                 :            :                                                     ICE_FLOW_SEG_HDR_IPV_FRAG |
    3786                 :            :                                                     ICE_FLOW_SEG_HDR_IPV_OTHER;
    3787         [ #  # ]:          0 :         else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6)
    3788                 :          0 :                 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
    3789                 :            :                                                     ICE_FLOW_SEG_HDR_IPV_FRAG |
    3790                 :            :                                                     ICE_FLOW_SEG_HDR_IPV_OTHER;
    3791         [ #  # ]:          0 :         else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4_GRE)
    3792                 :          0 :                 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
    3793                 :            :                                                     ICE_FLOW_SEG_HDR_GRE |
    3794                 :            :                                                     ICE_FLOW_SEG_HDR_IPV_OTHER;
    3795         [ #  # ]:          0 :         else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6_GRE)
    3796                 :          0 :                 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
    3797                 :            :                                                     ICE_FLOW_SEG_HDR_GRE |
    3798                 :            :                                                     ICE_FLOW_SEG_HDR_IPV_OTHER;
    3799                 :            : 
    3800                 :          0 :         if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
    3801         [ #  # ]:          0 :             ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER &
    3802                 :            :             ~ICE_FLOW_SEG_HDR_IPV_FRAG)
    3803                 :            :                 return ICE_ERR_PARAM;
    3804                 :            : 
    3805                 :          0 :         val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
    3806   [ #  #  #  # ]:          0 :         if (val && !ice_is_pow2(val))
    3807                 :            :                 return ICE_ERR_CFG;
    3808                 :            : 
    3809                 :          0 :         val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
    3810   [ #  #  #  # ]:          0 :         if (val && !ice_is_pow2(val))
    3811                 :          0 :                 return ICE_ERR_CFG;
    3812                 :            : 
    3813                 :            :         return 0;
    3814                 :            : }
    3815                 :            : 
    3816                 :            : /**
    3817                 :            :  * ice_rem_vsi_rss_list - remove VSI from RSS list
    3818                 :            :  * @hw: pointer to the hardware structure
    3819                 :            :  * @vsi_handle: software VSI handle
    3820                 :            :  *
    3821                 :            :  * Remove the VSI from all RSS configurations in the list.
    3822                 :            :  */
    3823                 :          0 : void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
    3824                 :            : {
    3825                 :            :         struct ice_rss_cfg *r, *tmp;
    3826                 :            : 
    3827         [ #  # ]:          0 :         if (LIST_EMPTY(&hw->rss_list_head))
    3828                 :            :                 return;
    3829                 :            : 
    3830                 :          0 :         ice_acquire_lock(&hw->rss_locks);
    3831   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head,
          #  #  #  #  #  
                      # ]
    3832                 :            :                                  ice_rss_cfg, l_entry)
    3833         [ #  # ]:          0 :                 if (ice_test_and_clear_bit(vsi_handle, r->vsis))
    3834         [ #  # ]:          0 :                         if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) {
    3835         [ #  # ]:          0 :                                 LIST_DEL(&r->l_entry);
    3836                 :          0 :                                 ice_free(hw, r);
    3837                 :            :                         }
    3838                 :            :         ice_release_lock(&hw->rss_locks);
    3839                 :            : }
    3840                 :            : 
    3841                 :            : /**
    3842                 :            :  * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
    3843                 :            :  * @hw: pointer to the hardware structure
    3844                 :            :  * @vsi_handle: software VSI handle
    3845                 :            :  *
    3846                 :            :  * This function will iterate through all flow profiles and disassociate
    3847                 :            :  * the VSI from that profile. If the flow profile has no VSIs it will
    3848                 :            :  * be removed.
    3849                 :            :  */
    3850                 :          0 : int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
    3851                 :            : {
    3852                 :            :         const enum ice_block blk = ICE_BLK_RSS;
    3853                 :            :         struct ice_flow_prof *p, *t;
    3854                 :            :         int status = 0;
    3855                 :            :         u16 vsig;
    3856                 :            : 
    3857         [ #  # ]:          0 :         if (!ice_is_vsi_valid(hw, vsi_handle))
    3858                 :            :                 return ICE_ERR_PARAM;
    3859                 :            : 
    3860         [ #  # ]:          0 :         if (LIST_EMPTY(&hw->fl_profs[blk]))
    3861                 :            :                 return 0;
    3862                 :            : 
    3863                 :          0 :         ice_acquire_lock(&hw->rss_locks);
    3864   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY_SAFE(p, t, &hw->fl_profs[blk], ice_flow_prof,
          #  #  #  #  #  
                      # ]
    3865                 :            :                                  l_entry) {
    3866                 :            :                 int ret;
    3867                 :            : 
    3868                 :            :                 /* check if vsig is already removed */
    3869                 :          0 :                 ret = ice_vsig_find_vsi(hw, blk,
    3870                 :          0 :                                         ice_get_hw_vsi_num(hw, vsi_handle),
    3871                 :            :                                         &vsig);
    3872   [ #  #  #  # ]:          0 :                 if (!ret && !vsig)
    3873                 :            :                         break;
    3874                 :            : 
    3875         [ #  # ]:          0 :                 if (ice_is_bit_set(p->vsis, vsi_handle)) {
    3876                 :          0 :                         status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
    3877         [ #  # ]:          0 :                         if (status)
    3878                 :            :                                 break;
    3879                 :            : 
    3880         [ #  # ]:          0 :                         if (!ice_is_any_bit_set(p->vsis, ICE_MAX_VSI)) {
    3881                 :          0 :                                 status = ice_flow_rem_prof(hw, blk, p->id);
    3882         [ #  # ]:          0 :                                 if (status)
    3883                 :            :                                         break;
    3884                 :            :                         }
    3885                 :            :                 }
    3886                 :            :         }
    3887                 :            :         ice_release_lock(&hw->rss_locks);
    3888                 :            : 
    3889                 :          0 :         return status;
    3890                 :            : }
    3891                 :            : 
    3892                 :            : /**
    3893                 :            :  * ice_get_rss_hdr_type - get a RSS profile's header type
    3894                 :            :  * @prof: RSS flow profile
    3895                 :            :  */
    3896                 :            : static enum ice_rss_cfg_hdr_type
    3897                 :            : ice_get_rss_hdr_type(struct ice_flow_prof *prof)
    3898                 :            : {
    3899                 :            :         enum ice_rss_cfg_hdr_type hdr_type = ICE_RSS_ANY_HEADERS;
    3900                 :            : 
    3901   [ #  #  #  # ]:          0 :         if (prof->segs_cnt == ICE_FLOW_SEG_SINGLE) {
    3902                 :            :                 hdr_type = ICE_RSS_OUTER_HEADERS;
    3903   [ #  #  #  # ]:          0 :         } else if (prof->segs_cnt == ICE_FLOW_SEG_MAX) {
    3904                 :            :                 const struct ice_flow_seg_info *s;
    3905                 :            : 
    3906                 :            :                 s = &prof->segs[ICE_RSS_OUTER_HEADERS];
    3907   [ #  #  #  # ]:          0 :                 if (s->hdrs == ICE_FLOW_SEG_HDR_NONE)
    3908                 :            :                         hdr_type = ICE_RSS_INNER_HEADERS;
    3909   [ #  #  #  # ]:          0 :                 if (s->hdrs & ICE_FLOW_SEG_HDR_IPV4)
    3910                 :            :                         hdr_type = ICE_RSS_INNER_HEADERS_W_OUTER_IPV4;
    3911   [ #  #  #  # ]:          0 :                 if (s->hdrs & ICE_FLOW_SEG_HDR_IPV6)
    3912                 :            :                         hdr_type = ICE_RSS_INNER_HEADERS_W_OUTER_IPV6;
    3913                 :            :         }
    3914                 :            : 
    3915                 :            :         return hdr_type;
    3916                 :            : }
    3917                 :            : 
    3918                 :            : /**
    3919                 :            :  * ice_rem_rss_list - remove RSS configuration from list
    3920                 :            :  * @hw: pointer to the hardware structure
    3921                 :            :  * @vsi_handle: software VSI handle
    3922                 :            :  * @prof: pointer to flow profile
    3923                 :            :  *
    3924                 :            :  * Assumption: lock has already been acquired for RSS list
    3925                 :            :  */
    3926                 :            : static void
    3927                 :          0 : ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
    3928                 :            : {
    3929                 :            :         enum ice_rss_cfg_hdr_type hdr_type;
    3930                 :            :         struct ice_rss_cfg *r, *tmp;
    3931                 :            :         u64 seg_match = 0;
    3932                 :            :         u16 i;
    3933                 :            : 
    3934                 :            :         /* convert match bitmap to u64 for hash field comparison */
    3935         [ #  # ]:          0 :         ice_for_each_set_bit(i, prof->segs[prof->segs_cnt - 1].match,
    3936                 :            :                              ICE_FLOW_FIELD_IDX_MAX) {
    3937                 :          0 :                 seg_match |= 1ULL << i;
    3938                 :            :         }
    3939                 :            : 
    3940                 :            :         /* Search for RSS hash fields associated to the VSI that match the
    3941                 :            :          * hash configurations associated to the flow profile. If found
    3942                 :            :          * remove from the RSS entry list of the VSI context and delete entry.
    3943                 :            :          */
    3944                 :            :         hdr_type = ice_get_rss_hdr_type(prof);
    3945   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head,
          #  #  #  #  #  
                      # ]
    3946                 :            :                                  ice_rss_cfg, l_entry)
    3947         [ #  # ]:          0 :                 if (r->hash.hash_flds == seg_match &&
    3948         [ #  # ]:          0 :                     r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs &&
    3949         [ #  # ]:          0 :                     r->hash.hdr_type == hdr_type) {
    3950                 :          0 :                         ice_clear_bit(vsi_handle, r->vsis);
    3951         [ #  # ]:          0 :                         if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) {
    3952         [ #  # ]:          0 :                                 LIST_DEL(&r->l_entry);
    3953                 :          0 :                                 ice_free(hw, r);
    3954                 :            :                         }
    3955                 :          0 :                         return;
    3956                 :            :                 }
    3957                 :            : }
    3958                 :            : 
    3959                 :            : /**
    3960                 :            :  * ice_add_rss_list - add RSS configuration to list
    3961                 :            :  * @hw: pointer to the hardware structure
    3962                 :            :  * @vsi_handle: software VSI handle
    3963                 :            :  * @prof: pointer to flow profile
    3964                 :            :  *
    3965                 :            :  * Assumption: lock has already been acquired for RSS list
    3966                 :            :  */
    3967                 :            : static int
    3968                 :          0 : ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
    3969                 :            : {
    3970                 :            :         enum ice_rss_cfg_hdr_type hdr_type;
    3971                 :            :         struct ice_rss_cfg *r, *rss_cfg;
    3972                 :            :         u64 seg_match = 0;
    3973                 :            :         u16 i;
    3974                 :            : 
    3975         [ #  # ]:          0 :         ice_for_each_set_bit(i, prof->segs[prof->segs_cnt - 1].match,
    3976                 :            :                              ICE_FLOW_FIELD_IDX_MAX) {
    3977                 :          0 :                 seg_match |= 1ULL << i;
    3978                 :            :         }
    3979                 :            : 
    3980                 :            :         hdr_type = ice_get_rss_hdr_type(prof);
    3981   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
                   #  # ]
    3982                 :            :                             ice_rss_cfg, l_entry)
    3983         [ #  # ]:          0 :                 if (r->hash.hash_flds == seg_match &&
    3984         [ #  # ]:          0 :                     r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs &&
    3985         [ #  # ]:          0 :                     r->hash.hdr_type == hdr_type) {
    3986                 :          0 :                         ice_set_bit(vsi_handle, r->vsis);
    3987                 :          0 :                         return 0;
    3988                 :            :                 }
    3989                 :            : 
    3990                 :          0 :         rss_cfg = (struct ice_rss_cfg *)ice_malloc(hw, sizeof(*rss_cfg));
    3991         [ #  # ]:          0 :         if (!rss_cfg)
    3992                 :            :                 return ICE_ERR_NO_MEMORY;
    3993                 :            : 
    3994                 :          0 :         rss_cfg->hash.hash_flds = seg_match;
    3995                 :          0 :         rss_cfg->hash.addl_hdrs = prof->segs[prof->segs_cnt - 1].hdrs;
    3996                 :          0 :         rss_cfg->hash.hdr_type = hdr_type;
    3997                 :          0 :         rss_cfg->hash.symm = prof->cfg.symm;
    3998         [ #  # ]:          0 :         ice_set_bit(vsi_handle, rss_cfg->vsis);
    3999                 :            : 
    4000         [ #  # ]:          0 :         LIST_ADD_TAIL(&rss_cfg->l_entry, &hw->rss_list_head);
    4001                 :            : 
    4002                 :            :         return 0;
    4003                 :            : }
    4004                 :            : 
    4005                 :            : #define ICE_FLOW_PROF_HASH_S    0
    4006                 :            : #define ICE_FLOW_PROF_HASH_M    (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
    4007                 :            : #define ICE_FLOW_PROF_HDR_S     32
    4008                 :            : #define ICE_FLOW_PROF_HDR_M     (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
    4009                 :            : #define ICE_FLOW_PROF_ENCAP_S   62
    4010                 :            : #define ICE_FLOW_PROF_ENCAP_M   (0x3ULL << ICE_FLOW_PROF_ENCAP_S)
    4011                 :            : 
    4012                 :            : /* Flow profile ID format:
    4013                 :            :  * [0:31] - Packet match fields
    4014                 :            :  * [32:61] - Protocol header
    4015                 :            :  * [62:63] - Encapsulation flag:
    4016                 :            :  *           0 if non-tunneled
    4017                 :            :  *           1 if tunneled
    4018                 :            :  *           2 for tunneled with outer IPv4
    4019                 :            :  *           3 for tunneled with outer IPv6
    4020                 :            :  */
    4021                 :            : #define ICE_FLOW_GEN_PROFID(hash, hdr, encap)                                \
    4022                 :            :         ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) |                        \
    4023                 :            :                (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
    4024                 :            :                (((u64)(encap) << ICE_FLOW_PROF_ENCAP_S) &                    \
    4025                 :            :                 ICE_FLOW_PROF_ENCAP_M)))
    4026                 :            : 
    4027                 :            : static void
    4028                 :          0 : ice_rss_config_xor_word(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst)
    4029                 :            : {
    4030                 :          0 :         u32 s = ((src % 4) << 3); /* byte shift */
    4031                 :          0 :         u32 v = dst | 0x80; /* value to program */
    4032                 :          0 :         u8 i = src / 4; /* register index */
    4033                 :            :         u32 reg;
    4034                 :            : 
    4035                 :          0 :         reg = rd32(hw, GLQF_HSYMM(prof_id, i));
    4036                 :          0 :         reg = (reg & ~(0xff << s)) | (v << s);
    4037                 :          0 :         wr32(hw, GLQF_HSYMM(prof_id, i), reg);
    4038                 :          0 : }
    4039                 :            : 
    4040                 :            : static void
    4041                 :          0 : ice_rss_config_xor(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst, u8 len)
    4042                 :            : {
    4043                 :            :         int fv_last_word =
    4044                 :            :                 ICE_FLOW_SW_FIELD_VECTOR_MAX / ICE_FLOW_FV_EXTRACT_SZ - 1;
    4045                 :            :         int i;
    4046                 :            : 
    4047         [ #  # ]:          0 :         for (i = 0; i < len; i++) {
    4048                 :          0 :                 ice_rss_config_xor_word(hw, prof_id,
    4049                 :            :                                         /* Yes, field vector in GLQF_HSYMM and
    4050                 :            :                                          * GLQF_HINSET is inversed!
    4051                 :            :                                          */
    4052                 :          0 :                                         fv_last_word - (src + i),
    4053                 :          0 :                                         fv_last_word - (dst + i));
    4054                 :          0 :                 ice_rss_config_xor_word(hw, prof_id,
    4055                 :            :                                         fv_last_word - (dst + i),
    4056                 :            :                                         fv_last_word - (src + i));
    4057                 :            :         }
    4058                 :          0 : }
    4059                 :            : 
    4060                 :            : static void
    4061                 :          0 : ice_rss_update_symm(struct ice_hw *hw,
    4062                 :            :                     struct ice_flow_prof *prof)
    4063                 :            : {
    4064                 :            :         struct ice_prof_map *map;
    4065                 :            :         u8 prof_id, m;
    4066                 :            : 
    4067                 :          0 :         ice_acquire_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
    4068                 :          0 :         map = ice_search_prof_id(hw, ICE_BLK_RSS, prof->id);
    4069         [ #  # ]:          0 :         if (map)
    4070                 :          0 :                 prof_id = map->prof_id;
    4071                 :            :         ice_release_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
    4072         [ #  # ]:          0 :         if (!map)
    4073                 :            :                 return;
    4074                 :            :         /* clear to default */
    4075         [ #  # ]:          0 :         for (m = 0; m < 6; m++)
    4076                 :          0 :                 wr32(hw, GLQF_HSYMM(prof_id, m), 0);
    4077         [ #  # ]:          0 :         if (prof->cfg.symm) {
    4078                 :            :                 struct ice_flow_seg_info *seg =
    4079                 :          0 :                         &prof->segs[prof->segs_cnt - 1];
    4080                 :            : 
    4081                 :            :                 struct ice_flow_seg_xtrct *ipv4_src =
    4082                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_SA].xtrct;
    4083                 :            :                 struct ice_flow_seg_xtrct *ipv4_dst =
    4084                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_DA].xtrct;
    4085                 :            :                 struct ice_flow_seg_xtrct *ipv6_src =
    4086                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_SA].xtrct;
    4087                 :            :                 struct ice_flow_seg_xtrct *ipv6_dst =
    4088                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_DA].xtrct;
    4089                 :            : 
    4090                 :            :                 struct ice_flow_seg_xtrct *tcp_src =
    4091                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_TCP_SRC_PORT].xtrct;
    4092                 :            :                 struct ice_flow_seg_xtrct *tcp_dst =
    4093                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_TCP_DST_PORT].xtrct;
    4094                 :            : 
    4095                 :            :                 struct ice_flow_seg_xtrct *udp_src =
    4096                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_UDP_SRC_PORT].xtrct;
    4097                 :            :                 struct ice_flow_seg_xtrct *udp_dst =
    4098                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_UDP_DST_PORT].xtrct;
    4099                 :            : 
    4100                 :            :                 struct ice_flow_seg_xtrct *sctp_src =
    4101                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT].xtrct;
    4102                 :            :                 struct ice_flow_seg_xtrct *sctp_dst =
    4103                 :            :                         &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_DST_PORT].xtrct;
    4104                 :            : 
    4105                 :            :                 /* xor IPv4 */
    4106   [ #  #  #  # ]:          0 :                 if (ipv4_src->prot_id != 0 && ipv4_dst->prot_id != 0)
    4107                 :          0 :                         ice_rss_config_xor(hw, prof_id,
    4108                 :          0 :                                            ipv4_src->idx, ipv4_dst->idx, 2);
    4109                 :            : 
    4110                 :            :                 /* xor IPv6 */
    4111   [ #  #  #  # ]:          0 :                 if (ipv6_src->prot_id != 0 && ipv6_dst->prot_id != 0)
    4112                 :          0 :                         ice_rss_config_xor(hw, prof_id,
    4113                 :          0 :                                            ipv6_src->idx, ipv6_dst->idx, 8);
    4114                 :            : 
    4115                 :            :                 /* xor TCP */
    4116   [ #  #  #  # ]:          0 :                 if (tcp_src->prot_id != 0 && tcp_dst->prot_id != 0)
    4117                 :          0 :                         ice_rss_config_xor(hw, prof_id,
    4118                 :          0 :                                            tcp_src->idx, tcp_dst->idx, 1);
    4119                 :            : 
    4120                 :            :                 /* xor UDP */
    4121   [ #  #  #  # ]:          0 :                 if (udp_src->prot_id != 0 && udp_dst->prot_id != 0)
    4122                 :          0 :                         ice_rss_config_xor(hw, prof_id,
    4123                 :          0 :                                            udp_src->idx, udp_dst->idx, 1);
    4124                 :            : 
    4125                 :            :                 /* xor SCTP */
    4126   [ #  #  #  # ]:          0 :                 if (sctp_src->prot_id != 0 && sctp_dst->prot_id != 0)
    4127                 :          0 :                         ice_rss_config_xor(hw, prof_id,
    4128                 :          0 :                                            sctp_src->idx, sctp_dst->idx, 1);
    4129                 :            :         }
    4130                 :            : }
    4131                 :            : 
    4132                 :            : /**
    4133                 :            :  * ice_rss_cfg_raw_symm - configure symmetric hash parameters
    4134                 :            :  * for raw pattern
    4135                 :            :  * @hw: pointer to the hardware structure
    4136                 :            :  * @prof: pointer to parser profile
    4137                 :            :  * @prof_id: profile ID
    4138                 :            :  *
    4139                 :            :  * Calculate symmetric hash parameters based on input protocol type.
    4140                 :            :  */
    4141                 :            : static void
    4142                 :          0 : ice_rss_cfg_raw_symm(struct ice_hw *hw,
    4143                 :            :                      struct ice_parser_profile *prof, u64 prof_id)
    4144                 :            : {
    4145                 :            :         u8 src_idx, dst_idx, proto_id;
    4146                 :            :         int len, i = 0;
    4147                 :            : 
    4148         [ #  # ]:          0 :         while (i < prof->fv_num) {
    4149                 :          0 :                 proto_id = prof->fv[i].proto_id;
    4150                 :            : 
    4151   [ #  #  #  # ]:          0 :                 switch (proto_id) {
    4152                 :          0 :                 case ICE_PROT_IPV4_OF_OR_S:
    4153                 :            :                 case ICE_PROT_IPV4_IL:
    4154                 :            :                 case ICE_PROT_IPV4_IL_IL:
    4155                 :            :                         len = ICE_FLOW_FLD_SZ_IPV4_ADDR /
    4156                 :            :                               ICE_FLOW_FV_EXTRACT_SZ;
    4157         [ #  # ]:          0 :                         if (prof->fv[i].offset ==
    4158                 :          0 :                             ICE_FLOW_FIELD_IPV4_SRC_OFFSET &&
    4159         [ #  # ]:          0 :                             prof->fv[i + len].proto_id == proto_id &&
    4160         [ #  # ]:          0 :                             prof->fv[i + len].offset ==
    4161                 :            :                             ICE_FLOW_FIELD_IPV4_DST_OFFSET) {
    4162                 :          0 :                                 src_idx = i;
    4163                 :          0 :                                 dst_idx = i + len;
    4164                 :          0 :                                 i += 2 * len;
    4165                 :          0 :                                 break;
    4166                 :            :                         }
    4167                 :          0 :                         i++;
    4168                 :          0 :                         continue;
    4169                 :          0 :                 case ICE_PROT_IPV6_OF_OR_S:
    4170                 :            :                 case ICE_PROT_IPV6_IL:
    4171                 :            :                 case ICE_PROT_IPV6_IL_IL:
    4172                 :            :                         len = ICE_FLOW_FLD_SZ_IPV6_ADDR /
    4173                 :            :                               ICE_FLOW_FV_EXTRACT_SZ;
    4174         [ #  # ]:          0 :                         if (prof->fv[i].offset ==
    4175                 :          0 :                             ICE_FLOW_FIELD_IPV6_SRC_OFFSET &&
    4176         [ #  # ]:          0 :                             prof->fv[i + len].proto_id == proto_id &&
    4177         [ #  # ]:          0 :                             prof->fv[i + len].offset ==
    4178                 :            :                             ICE_FLOW_FIELD_IPV6_DST_OFFSET) {
    4179                 :          0 :                                 src_idx = i;
    4180                 :          0 :                                 dst_idx = i + len;
    4181                 :          0 :                                 i += 2 * len;
    4182                 :          0 :                                 break;
    4183                 :            :                         }
    4184                 :          0 :                         i++;
    4185                 :          0 :                         continue;
    4186                 :          0 :                 case ICE_PROT_TCP_IL:
    4187                 :            :                 case ICE_PROT_UDP_IL_OR_S:
    4188                 :            :                 case ICE_PROT_SCTP_IL:
    4189                 :            :                         len = ICE_FLOW_FLD_SZ_PORT /
    4190                 :            :                               ICE_FLOW_FV_EXTRACT_SZ;
    4191         [ #  # ]:          0 :                         if (prof->fv[i].offset ==
    4192                 :          0 :                             ICE_FLOW_FIELD_SRC_PORT_OFFSET &&
    4193         [ #  # ]:          0 :                             prof->fv[i + len].proto_id == proto_id &&
    4194         [ #  # ]:          0 :                             prof->fv[i + len].offset ==
    4195                 :            :                             ICE_FLOW_FIELD_DST_PORT_OFFSET) {
    4196                 :          0 :                                 src_idx = i;
    4197                 :          0 :                                 dst_idx = i + len;
    4198                 :          0 :                                 i += 2 * len;
    4199                 :          0 :                                 break;
    4200                 :            :                         }
    4201                 :          0 :                         i++;
    4202                 :          0 :                         continue;
    4203                 :          0 :                 default:
    4204                 :          0 :                         i++;
    4205                 :          0 :                         continue;
    4206                 :            :                 }
    4207                 :          0 :                 ice_rss_config_xor(hw, prof_id, src_idx, dst_idx, len);
    4208                 :            :         }
    4209                 :          0 : }
    4210                 :            : 
    4211                 :            : /* Max registers index per packet profile */
    4212                 :            : #define ICE_SYMM_REG_INDEX_MAX 6
    4213                 :            : 
    4214                 :            : /**
    4215                 :            :  * ice_rss_update_raw_symm - update symmetric hash configuration
    4216                 :            :  * for raw pattern
    4217                 :            :  * @hw: pointer to the hardware structure
    4218                 :            :  * @cfg: configure parameters for raw pattern
    4219                 :            :  * @id: profile tracking ID
    4220                 :            :  *
    4221                 :            :  * Update symmetric hash configuration for raw pattern if required.
    4222                 :            :  * Otherwise only clear to default.
    4223                 :            :  */
    4224                 :            : void
    4225                 :          0 : ice_rss_update_raw_symm(struct ice_hw *hw,
    4226                 :            :                         struct ice_rss_raw_cfg *cfg, u64 id)
    4227                 :            : {
    4228                 :            :         struct ice_prof_map *map;
    4229                 :            :         u8 prof_id, m;
    4230                 :            : 
    4231                 :          0 :         ice_acquire_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
    4232                 :          0 :         map = ice_search_prof_id(hw, ICE_BLK_RSS, id);
    4233         [ #  # ]:          0 :         if (map)
    4234                 :          0 :                 prof_id = map->prof_id;
    4235                 :            :         ice_release_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
    4236         [ #  # ]:          0 :         if (!map)
    4237                 :            :                 return;
    4238                 :            :         /* clear to default */
    4239         [ #  # ]:          0 :         for (m = 0; m < ICE_SYMM_REG_INDEX_MAX; m++)
    4240                 :          0 :                 wr32(hw, GLQF_HSYMM(prof_id, m), 0);
    4241         [ #  # ]:          0 :         if (cfg->symm)
    4242                 :          0 :                 ice_rss_cfg_raw_symm(hw, &cfg->prof, prof_id);
    4243                 :            : }
    4244                 :            : 
    4245                 :            : /**
    4246                 :            :  * ice_add_rss_cfg_sync - add an RSS configuration
    4247                 :            :  * @hw: pointer to the hardware structure
    4248                 :            :  * @vsi_handle: software VSI handle
    4249                 :            :  * @cfg: configure parameters
    4250                 :            :  *
    4251                 :            :  * Assumption: lock has already been acquired for RSS list
    4252                 :            :  */
    4253                 :            : static int
    4254                 :          0 : ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
    4255                 :            :                      const struct ice_rss_hash_cfg *cfg)
    4256                 :            : {
    4257                 :            :         const enum ice_block blk = ICE_BLK_RSS;
    4258                 :          0 :         struct ice_flow_prof *prof = NULL;
    4259                 :            :         struct ice_flow_seg_info *segs;
    4260                 :            :         u8 segs_cnt;
    4261                 :            :         int status;
    4262                 :            : 
    4263         [ #  # ]:          0 :         segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
    4264                 :            :                            ICE_FLOW_SEG_SINGLE :
    4265                 :            :                            ICE_FLOW_SEG_MAX;
    4266                 :            : 
    4267                 :          0 :         segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
    4268                 :            :                                                       sizeof(*segs));
    4269         [ #  # ]:          0 :         if (!segs)
    4270                 :            :                 return ICE_ERR_NO_MEMORY;
    4271                 :            : 
    4272                 :            :         /* Construct the packet segment info from the hashed fields */
    4273                 :          0 :         status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
    4274         [ #  # ]:          0 :         if (status)
    4275                 :          0 :                 goto exit;
    4276                 :            : 
    4277                 :            :         /* Search for a flow profile that has matching headers, hash fields
    4278                 :            :          * and has the input VSI associated to it. If found, no further
    4279                 :            :          * operations required and exit.
    4280                 :            :          */
    4281                 :          0 :         prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
    4282                 :            :                                         vsi_handle,
    4283                 :            :                                         ICE_FLOW_FIND_PROF_CHK_FLDS |
    4284                 :            :                                         ICE_FLOW_FIND_PROF_CHK_VSI);
    4285         [ #  # ]:          0 :         if (prof) {
    4286         [ #  # ]:          0 :                 if (prof->cfg.symm == cfg->symm)
    4287                 :          0 :                         goto exit;
    4288                 :          0 :                 prof->cfg.symm = cfg->symm;
    4289                 :          0 :                 goto update_symm;
    4290                 :            :         }
    4291                 :            : 
    4292                 :            :         /* Check if a flow profile exists with the same protocol headers and
    4293                 :            :          * associated with the input VSI. If so disassociate the VSI from
    4294                 :            :          * this profile. The VSI will be added to a new profile created with
    4295                 :            :          * the protocol header and new hash field configuration.
    4296                 :            :          */
    4297                 :          0 :         prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
    4298                 :            :                                         vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
    4299         [ #  # ]:          0 :         if (prof) {
    4300                 :          0 :                 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
    4301         [ #  # ]:          0 :                 if (!status)
    4302                 :          0 :                         ice_rem_rss_list(hw, vsi_handle, prof);
    4303                 :            :                 else
    4304                 :          0 :                         goto exit;
    4305                 :            : 
    4306                 :            :                 /* Remove profile if it has no VSIs associated */
    4307         [ #  # ]:          0 :                 if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI)) {
    4308                 :          0 :                         status = ice_flow_rem_prof(hw, blk, prof->id);
    4309         [ #  # ]:          0 :                         if (status)
    4310                 :          0 :                                 goto exit;
    4311                 :            :                 }
    4312                 :            :         }
    4313                 :            : 
    4314                 :            :         /* Search for a profile that has same match fields only. If this
    4315                 :            :          * exists then associate the VSI to this profile.
    4316                 :            :          */
    4317                 :          0 :         prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
    4318                 :            :                                         vsi_handle,
    4319                 :            :                                         ICE_FLOW_FIND_PROF_CHK_FLDS);
    4320         [ #  # ]:          0 :         if (prof) {
    4321         [ #  # ]:          0 :                 if (prof->cfg.symm == cfg->symm) {
    4322                 :          0 :                         status = ice_flow_assoc_prof(hw, blk, prof,
    4323                 :            :                                                      vsi_handle);
    4324         [ #  # ]:          0 :                         if (!status)
    4325                 :          0 :                                 status = ice_add_rss_list(hw, vsi_handle,
    4326                 :            :                                                           prof);
    4327                 :            :                 } else {
    4328                 :            :                         /* if a profile exist but with different symmetric
    4329                 :            :                          * requirement, just return error.
    4330                 :            :                          */
    4331                 :            :                         status = ICE_ERR_NOT_SUPPORTED;
    4332                 :            :                 }
    4333                 :          0 :                 goto exit;
    4334                 :            :         }
    4335                 :            : 
    4336                 :            :         /* Create a new flow profile with generated profile and packet
    4337                 :            :          * segment information.
    4338                 :            :          */
    4339                 :          0 :         status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
    4340                 :          0 :                                    ICE_FLOW_GEN_PROFID(cfg->hash_flds,
    4341                 :            :                                                        segs[segs_cnt - 1].hdrs,
    4342                 :            :                                                        cfg->hdr_type),
    4343                 :            :                                    segs, segs_cnt, NULL, 0, &prof);
    4344         [ #  # ]:          0 :         if (status)
    4345                 :          0 :                 goto exit;
    4346                 :            : 
    4347                 :          0 :         status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
    4348                 :            :         /* If association to a new flow profile failed then this profile can
    4349                 :            :          * be removed.
    4350                 :            :          */
    4351         [ #  # ]:          0 :         if (status) {
    4352                 :          0 :                 ice_flow_rem_prof(hw, blk, prof->id);
    4353                 :          0 :                 goto exit;
    4354                 :            :         }
    4355                 :            : 
    4356                 :          0 :         status = ice_add_rss_list(hw, vsi_handle, prof);
    4357                 :            : 
    4358                 :          0 :         prof->cfg.symm = cfg->symm;
    4359                 :          0 : update_symm:
    4360                 :          0 :         ice_rss_update_symm(hw, prof);
    4361                 :            : 
    4362                 :          0 : exit:
    4363                 :          0 :         ice_free(hw, segs);
    4364                 :          0 :         return status;
    4365                 :            : }
    4366                 :            : 
    4367                 :            : /**
    4368                 :            :  * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
    4369                 :            :  * @hw: pointer to the hardware structure
    4370                 :            :  * @vsi_handle: software VSI handle
    4371                 :            :  * @cfg: configure parameters
    4372                 :            :  *
    4373                 :            :  * This function will generate a flow profile based on fields associated with
    4374                 :            :  * the input fields to hash on, the flow type and use the VSI number to add
    4375                 :            :  * a flow entry to the profile.
    4376                 :            :  */
    4377                 :            : int
    4378                 :          0 : ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
    4379                 :            :                 const struct ice_rss_hash_cfg *cfg)
    4380                 :            : {
    4381                 :            :         struct ice_rss_hash_cfg local_cfg;
    4382                 :            :         int status;
    4383                 :            : 
    4384   [ #  #  #  # ]:          0 :         if (!ice_is_vsi_valid(hw, vsi_handle) || !cfg ||
    4385         [ #  # ]:          0 :             cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
    4386         [ #  # ]:          0 :             cfg->hash_flds == ICE_HASH_INVALID)
    4387                 :            :                 return ICE_ERR_PARAM;
    4388                 :            : 
    4389                 :          0 :         ice_acquire_lock(&hw->rss_locks);
    4390                 :          0 :         local_cfg = *cfg;
    4391         [ #  # ]:          0 :         if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
    4392                 :          0 :                 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
    4393                 :            :         } else {
    4394                 :          0 :                 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
    4395                 :          0 :                 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
    4396         [ #  # ]:          0 :                 if (!status) {
    4397                 :          0 :                         local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
    4398                 :          0 :                         status = ice_add_rss_cfg_sync(hw, vsi_handle,
    4399                 :            :                                                       &local_cfg);
    4400                 :            :                 }
    4401                 :            :         }
    4402                 :            :         ice_release_lock(&hw->rss_locks);
    4403                 :            : 
    4404                 :          0 :         return status;
    4405                 :            : }
    4406                 :            : 
    4407                 :            : /**
    4408                 :            :  * ice_rem_rss_cfg_sync - remove an existing RSS configuration
    4409                 :            :  * @hw: pointer to the hardware structure
    4410                 :            :  * @vsi_handle: software VSI handle
    4411                 :            :  * @cfg: configure parameters
    4412                 :            :  *
    4413                 :            :  * Assumption: lock has already been acquired for RSS list
    4414                 :            :  */
    4415                 :            : static int
    4416                 :          0 : ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
    4417                 :            :                      const struct ice_rss_hash_cfg *cfg)
    4418                 :            : {
    4419                 :            :         const enum ice_block blk = ICE_BLK_RSS;
    4420                 :            :         struct ice_flow_seg_info *segs;
    4421                 :            :         struct ice_flow_prof *prof;
    4422                 :            :         u8 segs_cnt;
    4423                 :            :         int status;
    4424                 :            : 
    4425         [ #  # ]:          0 :         segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
    4426                 :            :                            ICE_FLOW_SEG_SINGLE :
    4427                 :            :                            ICE_FLOW_SEG_MAX;
    4428                 :          0 :         segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
    4429                 :            :                                                       sizeof(*segs));
    4430         [ #  # ]:          0 :         if (!segs)
    4431                 :            :                 return ICE_ERR_NO_MEMORY;
    4432                 :            : 
    4433                 :            :         /* Construct the packet segment info from the hashed fields */
    4434                 :          0 :         status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
    4435         [ #  # ]:          0 :         if (status)
    4436                 :          0 :                 goto out;
    4437                 :            : 
    4438                 :          0 :         prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
    4439                 :            :                                         vsi_handle,
    4440                 :            :                                         ICE_FLOW_FIND_PROF_CHK_FLDS);
    4441         [ #  # ]:          0 :         if (!prof) {
    4442                 :            :                 status = ICE_ERR_DOES_NOT_EXIST;
    4443                 :          0 :                 goto out;
    4444                 :            :         }
    4445                 :            : 
    4446                 :          0 :         status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
    4447         [ #  # ]:          0 :         if (status)
    4448                 :          0 :                 goto out;
    4449                 :            : 
    4450                 :            :         /* Remove RSS configuration from VSI context before deleting
    4451                 :            :          * the flow profile.
    4452                 :            :          */
    4453                 :          0 :         ice_rem_rss_list(hw, vsi_handle, prof);
    4454                 :            : 
    4455         [ #  # ]:          0 :         if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI))
    4456                 :          0 :                 status = ice_flow_rem_prof(hw, blk, prof->id);
    4457                 :            : 
    4458                 :          0 : out:
    4459                 :          0 :         ice_free(hw, segs);
    4460                 :          0 :         return status;
    4461                 :            : }
    4462                 :            : 
    4463                 :            : /**
    4464                 :            :  * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
    4465                 :            :  * @hw: pointer to the hardware structure
    4466                 :            :  * @vsi_handle: software VSI handle
    4467                 :            :  * @cfg: configure parameters
    4468                 :            :  *
    4469                 :            :  * This function will lookup the flow profile based on the input
    4470                 :            :  * hash field bitmap, iterate through the profile entry list of
    4471                 :            :  * that profile and find entry associated with input VSI to be
    4472                 :            :  * removed. Calls are made to underlying flow apis which will in
    4473                 :            :  * turn build or update buffers for RSS XLT1 section.
    4474                 :            :  */
    4475                 :            : int
    4476                 :          0 : ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
    4477                 :            :                 const struct ice_rss_hash_cfg *cfg)
    4478                 :            : {
    4479                 :            :         struct ice_rss_hash_cfg local_cfg;
    4480                 :            :         int status;
    4481                 :            : 
    4482   [ #  #  #  # ]:          0 :         if (!ice_is_vsi_valid(hw, vsi_handle) || !cfg ||
    4483         [ #  # ]:          0 :             cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
    4484         [ #  # ]:          0 :             cfg->hash_flds == ICE_HASH_INVALID)
    4485                 :            :                 return ICE_ERR_PARAM;
    4486                 :            : 
    4487                 :          0 :         ice_acquire_lock(&hw->rss_locks);
    4488                 :          0 :         local_cfg = *cfg;
    4489         [ #  # ]:          0 :         if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
    4490                 :          0 :                 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
    4491                 :            :         } else {
    4492                 :          0 :                 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
    4493                 :          0 :                 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
    4494         [ #  # ]:          0 :                 if (!status) {
    4495                 :          0 :                         local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
    4496                 :          0 :                         status = ice_rem_rss_cfg_sync(hw, vsi_handle,
    4497                 :            :                                                       &local_cfg);
    4498                 :            :                 }
    4499                 :            :         }
    4500                 :            :         ice_release_lock(&hw->rss_locks);
    4501                 :            : 
    4502                 :          0 :         return status;
    4503                 :            : }
    4504                 :            : 
    4505                 :            : /**
    4506                 :            :  * ice_replay_rss_cfg - replay RSS configurations associated with VSI
    4507                 :            :  * @hw: pointer to the hardware structure
    4508                 :            :  * @vsi_handle: software VSI handle
    4509                 :            :  */
    4510                 :          0 : int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
    4511                 :            : {
    4512                 :            :         struct ice_rss_cfg *r;
    4513                 :            :         int status = 0;
    4514                 :            : 
    4515         [ #  # ]:          0 :         if (!ice_is_vsi_valid(hw, vsi_handle))
    4516                 :            :                 return ICE_ERR_PARAM;
    4517                 :            : 
    4518                 :          0 :         ice_acquire_lock(&hw->rss_locks);
    4519   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
                   #  # ]
    4520                 :            :                             ice_rss_cfg, l_entry) {
    4521         [ #  # ]:          0 :                 if (ice_is_bit_set(r->vsis, vsi_handle)) {
    4522                 :          0 :                         status = ice_add_rss_cfg_sync(hw, vsi_handle, &r->hash);
    4523         [ #  # ]:          0 :                         if (status)
    4524                 :            :                                 break;
    4525                 :            :                 }
    4526                 :            :         }
    4527                 :            :         ice_release_lock(&hw->rss_locks);
    4528                 :            : 
    4529                 :          0 :         return status;
    4530                 :            : }
    4531                 :            : 
    4532                 :            : /**
    4533                 :            :  * ice_get_rss_cfg - returns hashed fields for the given header types
    4534                 :            :  * @hw: pointer to the hardware structure
    4535                 :            :  * @vsi_handle: software VSI handle
    4536                 :            :  * @hdrs: protocol header type
    4537                 :            :  *
    4538                 :            :  * This function will return the match fields of the first instance of flow
    4539                 :            :  * profile having the given header types and containing input VSI
    4540                 :            :  */
    4541                 :          0 : u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
    4542                 :            : {
    4543                 :            :         u64 rss_hash = ICE_HASH_INVALID;
    4544                 :            :         struct ice_rss_cfg *r;
    4545                 :            : 
    4546                 :            :         /* verify if the protocol header is non zero and VSI is valid */
    4547   [ #  #  #  # ]:          0 :         if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
    4548                 :          0 :                 return ICE_HASH_INVALID;
    4549                 :            : 
    4550                 :          0 :         ice_acquire_lock(&hw->rss_locks);
    4551   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
                   #  # ]
    4552                 :            :                             ice_rss_cfg, l_entry)
    4553         [ #  # ]:          0 :                 if (ice_is_bit_set(r->vsis, vsi_handle) &&
    4554         [ #  # ]:          0 :                     r->hash.addl_hdrs == hdrs) {
    4555                 :          0 :                         rss_hash = r->hash.hash_flds;
    4556                 :          0 :                         break;
    4557                 :            :                 }
    4558                 :            :         ice_release_lock(&hw->rss_locks);
    4559                 :            : 
    4560                 :          0 :         return rss_hash;
    4561                 :            : }

Generated by: LCOV version 1.14