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