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