1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2019, Intel Corporation. */ 3 4 #include "ice_common.h" 5 #include "ice_flow.h" 6 7 /* Describe properties of a protocol header field */ 8 struct ice_flow_field_info { 9 enum ice_flow_seg_hdr hdr; 10 s16 off; /* Offset from start of a protocol header, in bits */ 11 u16 size; /* Size of fields in bits */ 12 u16 mask; /* 16-bit mask for field */ 13 }; 14 15 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \ 16 .hdr = _hdr, \ 17 .off = (_offset_bytes) * BITS_PER_BYTE, \ 18 .size = (_size_bytes) * BITS_PER_BYTE, \ 19 .mask = 0, \ 20 } 21 22 #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \ 23 .hdr = _hdr, \ 24 .off = (_offset_bytes) * BITS_PER_BYTE, \ 25 .size = (_size_bytes) * BITS_PER_BYTE, \ 26 .mask = _mask, \ 27 } 28 29 /* Table containing properties of supported protocol header fields */ 30 static const 31 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = { 32 /* Ether */ 33 /* ICE_FLOW_FIELD_IDX_ETH_DA */ 34 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN), 35 /* ICE_FLOW_FIELD_IDX_ETH_SA */ 36 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN), 37 /* ICE_FLOW_FIELD_IDX_S_VLAN */ 38 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, sizeof(__be16)), 39 /* ICE_FLOW_FIELD_IDX_C_VLAN */ 40 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, sizeof(__be16)), 41 /* ICE_FLOW_FIELD_IDX_ETH_TYPE */ 42 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, sizeof(__be16)), 43 /* IPv4 / IPv6 */ 44 /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */ 45 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, 1, 0x00fc), 46 /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */ 47 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, 1, 0x0ff0), 48 /* ICE_FLOW_FIELD_IDX_IPV4_TTL */ 49 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0xff00), 50 /* ICE_FLOW_FIELD_IDX_IPV4_PROT */ 51 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0x00ff), 52 /* ICE_FLOW_FIELD_IDX_IPV6_TTL */ 53 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0x00ff), 54 /* ICE_FLOW_FIELD_IDX_IPV6_PROT */ 55 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0xff00), 56 /* ICE_FLOW_FIELD_IDX_IPV4_SA */ 57 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)), 58 /* ICE_FLOW_FIELD_IDX_IPV4_DA */ 59 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)), 60 /* ICE_FLOW_FIELD_IDX_IPV6_SA */ 61 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)), 62 /* ICE_FLOW_FIELD_IDX_IPV6_DA */ 63 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)), 64 /* Transport */ 65 /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */ 66 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)), 67 /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */ 68 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)), 69 /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */ 70 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)), 71 /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */ 72 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)), 73 /* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */ 74 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, sizeof(__be16)), 75 /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */ 76 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)), 77 /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */ 78 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, 1), 79 /* ARP */ 80 /* ICE_FLOW_FIELD_IDX_ARP_SIP */ 81 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)), 82 /* ICE_FLOW_FIELD_IDX_ARP_DIP */ 83 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, sizeof(struct in_addr)), 84 /* ICE_FLOW_FIELD_IDX_ARP_SHA */ 85 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN), 86 /* ICE_FLOW_FIELD_IDX_ARP_DHA */ 87 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN), 88 /* ICE_FLOW_FIELD_IDX_ARP_OP */ 89 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, sizeof(__be16)), 90 /* ICMP */ 91 /* ICE_FLOW_FIELD_IDX_ICMP_TYPE */ 92 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, 1), 93 /* ICE_FLOW_FIELD_IDX_ICMP_CODE */ 94 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, 1), 95 /* GRE */ 96 /* ICE_FLOW_FIELD_IDX_GRE_KEYID */ 97 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12, 98 sizeof_field(struct gre_full_hdr, key)), 99 /* GTP */ 100 /* ICE_FLOW_FIELD_IDX_GTPC_TEID */ 101 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12, sizeof(__be32)), 102 /* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */ 103 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12, sizeof(__be32)), 104 /* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */ 105 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12, sizeof(__be32)), 106 /* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */ 107 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16), 108 0x3f00), 109 /* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */ 110 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, sizeof(__be32)), 111 /* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */ 112 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, sizeof(__be32)), 113 /* PPPoE */ 114 /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */ 115 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)), 116 /* PFCP */ 117 /* ICE_FLOW_FIELD_IDX_PFCP_SEID */ 118 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)), 119 /* L2TPv3 */ 120 /* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */ 121 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)), 122 /* ESP */ 123 /* ICE_FLOW_FIELD_IDX_ESP_SPI */ 124 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)), 125 /* AH */ 126 /* ICE_FLOW_FIELD_IDX_AH_SPI */ 127 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)), 128 /* NAT_T_ESP */ 129 /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */ 130 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)), 131 }; 132 133 /* Bitmaps indicating relevant packet types for a particular protocol header 134 * 135 * Packet types for packets with an Outer/First/Single MAC header 136 */ 137 static const u32 ice_ptypes_mac_ofos[] = { 138 0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB, 139 0x0000077E, 0x00000000, 0x00000000, 0x00000000, 140 0x00400000, 0x03FFF000, 0x7FFFFFE0, 0x00000000, 141 0x00000000, 0x00000000, 0x00000000, 0x00000000, 142 0x00000000, 0x00000000, 0x00000000, 0x00000000, 143 0x00000000, 0x00000000, 0x00000000, 0x00000000, 144 0x00000000, 0x00000000, 0x00000000, 0x00000000, 145 0x00000000, 0x00000000, 0x00000000, 0x00000000, 146 }; 147 148 /* Packet types for packets with an Innermost/Last MAC VLAN header */ 149 static const u32 ice_ptypes_macvlan_il[] = { 150 0x00000000, 0xBC000000, 0x000001DF, 0xF0000000, 151 0x0000077E, 0x00000000, 0x00000000, 0x00000000, 152 0x00000000, 0x00000000, 0x00000000, 0x00000000, 153 0x00000000, 0x00000000, 0x00000000, 0x00000000, 154 0x00000000, 0x00000000, 0x00000000, 0x00000000, 155 0x00000000, 0x00000000, 0x00000000, 0x00000000, 156 0x00000000, 0x00000000, 0x00000000, 0x00000000, 157 0x00000000, 0x00000000, 0x00000000, 0x00000000, 158 }; 159 160 /* Packet types for packets with an Outer/First/Single IPv4 header, does NOT 161 * include IPv4 other PTYPEs 162 */ 163 static const u32 ice_ptypes_ipv4_ofos[] = { 164 0x1DC00000, 0x04000800, 0x00000000, 0x00000000, 165 0x00000000, 0x00000155, 0x00000000, 0x00000000, 166 0x00000000, 0x000FC000, 0x00000000, 0x00000000, 167 0x00000000, 0x00000000, 0x00000000, 0x00000000, 168 0x00000000, 0x00000000, 0x00000000, 0x00000000, 169 0x00000000, 0x00000000, 0x00000000, 0x00000000, 170 0x00000000, 0x00000000, 0x00000000, 0x00000000, 171 0x00000000, 0x00000000, 0x00000000, 0x00000000, 172 }; 173 174 /* Packet types for packets with an Outer/First/Single IPv4 header, includes 175 * IPv4 other PTYPEs 176 */ 177 static const u32 ice_ptypes_ipv4_ofos_all[] = { 178 0x1DC00000, 0x04000800, 0x00000000, 0x00000000, 179 0x00000000, 0x00000155, 0x00000000, 0x00000000, 180 0x00000000, 0x000FC000, 0x83E0F800, 0x00000101, 181 0x00000000, 0x00000000, 0x00000000, 0x00000000, 182 0x00000000, 0x00000000, 0x00000000, 0x00000000, 183 0x00000000, 0x00000000, 0x00000000, 0x00000000, 184 0x00000000, 0x00000000, 0x00000000, 0x00000000, 185 0x00000000, 0x00000000, 0x00000000, 0x00000000, 186 }; 187 188 /* Packet types for packets with an Innermost/Last IPv4 header */ 189 static const u32 ice_ptypes_ipv4_il[] = { 190 0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B, 191 0x0000000E, 0x00000000, 0x00000000, 0x00000000, 192 0x00000000, 0x00000000, 0x001FF800, 0x00000000, 193 0x00000000, 0x00000000, 0x00000000, 0x00000000, 194 0x00000000, 0x00000000, 0x00000000, 0x00000000, 195 0x00000000, 0x00000000, 0x00000000, 0x00000000, 196 0x00000000, 0x00000000, 0x00000000, 0x00000000, 197 0x00000000, 0x00000000, 0x00000000, 0x00000000, 198 }; 199 200 /* Packet types for packets with an Outer/First/Single IPv6 header, does NOT 201 * include IPv6 other PTYPEs 202 */ 203 static const u32 ice_ptypes_ipv6_ofos[] = { 204 0x00000000, 0x00000000, 0x77000000, 0x10002000, 205 0x00000000, 0x000002AA, 0x00000000, 0x00000000, 206 0x00000000, 0x03F00000, 0x00000000, 0x00000000, 207 0x00000000, 0x00000000, 0x00000000, 0x00000000, 208 0x00000000, 0x00000000, 0x00000000, 0x00000000, 209 0x00000000, 0x00000000, 0x00000000, 0x00000000, 210 0x00000000, 0x00000000, 0x00000000, 0x00000000, 211 0x00000000, 0x00000000, 0x00000000, 0x00000000, 212 }; 213 214 /* Packet types for packets with an Outer/First/Single IPv6 header, includes 215 * IPv6 other PTYPEs 216 */ 217 static const u32 ice_ptypes_ipv6_ofos_all[] = { 218 0x00000000, 0x00000000, 0x77000000, 0x10002000, 219 0x00000000, 0x000002AA, 0x00000000, 0x00000000, 220 0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206, 221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 222 0x00000000, 0x00000000, 0x00000000, 0x00000000, 223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 224 0x00000000, 0x00000000, 0x00000000, 0x00000000, 225 0x00000000, 0x00000000, 0x00000000, 0x00000000, 226 }; 227 228 /* Packet types for packets with an Innermost/Last IPv6 header */ 229 static const u32 ice_ptypes_ipv6_il[] = { 230 0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000, 231 0x00000770, 0x00000000, 0x00000000, 0x00000000, 232 0x00000000, 0x00000000, 0x7FE00000, 0x00000000, 233 0x00000000, 0x00000000, 0x00000000, 0x00000000, 234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 235 0x00000000, 0x00000000, 0x00000000, 0x00000000, 236 0x00000000, 0x00000000, 0x00000000, 0x00000000, 237 0x00000000, 0x00000000, 0x00000000, 0x00000000, 238 }; 239 240 /* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */ 241 static const u32 ice_ptypes_ipv4_ofos_no_l4[] = { 242 0x10C00000, 0x04000800, 0x00000000, 0x00000000, 243 0x00000000, 0x00000000, 0x00000000, 0x00000000, 244 0x00000000, 0x00000000, 0x00000000, 0x00000000, 245 0x00000000, 0x00000000, 0x00000000, 0x00000000, 246 0x00000000, 0x00000000, 0x00000000, 0x00000000, 247 0x00000000, 0x00000000, 0x00000000, 0x00000000, 248 0x00000000, 0x00000000, 0x00000000, 0x00000000, 249 0x00000000, 0x00000000, 0x00000000, 0x00000000, 250 }; 251 252 /* Packet types for packets with an Outermost/First ARP header */ 253 static const u32 ice_ptypes_arp_of[] = { 254 0x00000800, 0x00000000, 0x00000000, 0x00000000, 255 0x00000000, 0x00000000, 0x00000000, 0x00000000, 256 0x00000000, 0x00000000, 0x00000000, 0x00000000, 257 0x00000000, 0x00000000, 0x00000000, 0x00000000, 258 0x00000000, 0x00000000, 0x00000000, 0x00000000, 259 0x00000000, 0x00000000, 0x00000000, 0x00000000, 260 0x00000000, 0x00000000, 0x00000000, 0x00000000, 261 0x00000000, 0x00000000, 0x00000000, 0x00000000, 262 }; 263 264 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */ 265 static const u32 ice_ptypes_ipv4_il_no_l4[] = { 266 0x60000000, 0x18043008, 0x80000002, 0x6010c021, 267 0x00000008, 0x00000000, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000, 274 }; 275 276 /* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */ 277 static const u32 ice_ptypes_ipv6_ofos_no_l4[] = { 278 0x00000000, 0x00000000, 0x43000000, 0x10002000, 279 0x00000000, 0x00000000, 0x00000000, 0x00000000, 280 0x00000000, 0x00000000, 0x00000000, 0x00000000, 281 0x00000000, 0x00000000, 0x00000000, 0x00000000, 282 0x00000000, 0x00000000, 0x00000000, 0x00000000, 283 0x00000000, 0x00000000, 0x00000000, 0x00000000, 284 0x00000000, 0x00000000, 0x00000000, 0x00000000, 285 0x00000000, 0x00000000, 0x00000000, 0x00000000, 286 }; 287 288 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */ 289 static const u32 ice_ptypes_ipv6_il_no_l4[] = { 290 0x00000000, 0x02180430, 0x0000010c, 0x086010c0, 291 0x00000430, 0x00000000, 0x00000000, 0x00000000, 292 0x00000000, 0x00000000, 0x00000000, 0x00000000, 293 0x00000000, 0x00000000, 0x00000000, 0x00000000, 294 0x00000000, 0x00000000, 0x00000000, 0x00000000, 295 0x00000000, 0x00000000, 0x00000000, 0x00000000, 296 0x00000000, 0x00000000, 0x00000000, 0x00000000, 297 0x00000000, 0x00000000, 0x00000000, 0x00000000, 298 }; 299 300 /* UDP Packet types for non-tunneled packets or tunneled 301 * packets with inner UDP. 302 */ 303 static const u32 ice_ptypes_udp_il[] = { 304 0x81000000, 0x20204040, 0x04000010, 0x80810102, 305 0x00000040, 0x00000000, 0x00000000, 0x00000000, 306 0x00000000, 0x00410000, 0x90842000, 0x00000007, 307 0x00000000, 0x00000000, 0x00000000, 0x00000000, 308 0x00000000, 0x00000000, 0x00000000, 0x00000000, 309 0x00000000, 0x00000000, 0x00000000, 0x00000000, 310 0x00000000, 0x00000000, 0x00000000, 0x00000000, 311 0x00000000, 0x00000000, 0x00000000, 0x00000000, 312 }; 313 314 /* Packet types for packets with an Innermost/Last TCP header */ 315 static const u32 ice_ptypes_tcp_il[] = { 316 0x04000000, 0x80810102, 0x10000040, 0x02040408, 317 0x00000102, 0x00000000, 0x00000000, 0x00000000, 318 0x00000000, 0x00820000, 0x21084000, 0x00000000, 319 0x00000000, 0x00000000, 0x00000000, 0x00000000, 320 0x00000000, 0x00000000, 0x00000000, 0x00000000, 321 0x00000000, 0x00000000, 0x00000000, 0x00000000, 322 0x00000000, 0x00000000, 0x00000000, 0x00000000, 323 0x00000000, 0x00000000, 0x00000000, 0x00000000, 324 }; 325 326 /* Packet types for packets with an Innermost/Last SCTP header */ 327 static const u32 ice_ptypes_sctp_il[] = { 328 0x08000000, 0x01020204, 0x20000081, 0x04080810, 329 0x00000204, 0x00000000, 0x00000000, 0x00000000, 330 0x00000000, 0x01040000, 0x00000000, 0x00000000, 331 0x00000000, 0x00000000, 0x00000000, 0x00000000, 332 0x00000000, 0x00000000, 0x00000000, 0x00000000, 333 0x00000000, 0x00000000, 0x00000000, 0x00000000, 334 0x00000000, 0x00000000, 0x00000000, 0x00000000, 335 0x00000000, 0x00000000, 0x00000000, 0x00000000, 336 }; 337 338 /* Packet types for packets with an Outermost/First ICMP header */ 339 static const u32 ice_ptypes_icmp_of[] = { 340 0x10000000, 0x00000000, 0x00000000, 0x00000000, 341 0x00000000, 0x00000000, 0x00000000, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000, 348 }; 349 350 /* Packet types for packets with an Innermost/Last ICMP header */ 351 static const u32 ice_ptypes_icmp_il[] = { 352 0x00000000, 0x02040408, 0x40000102, 0x08101020, 353 0x00000408, 0x00000000, 0x00000000, 0x00000000, 354 0x00000000, 0x00000000, 0x42108000, 0x00000000, 355 0x00000000, 0x00000000, 0x00000000, 0x00000000, 356 0x00000000, 0x00000000, 0x00000000, 0x00000000, 357 0x00000000, 0x00000000, 0x00000000, 0x00000000, 358 0x00000000, 0x00000000, 0x00000000, 0x00000000, 359 0x00000000, 0x00000000, 0x00000000, 0x00000000, 360 }; 361 362 /* Packet types for packets with an Outermost/First GRE header */ 363 static const u32 ice_ptypes_gre_of[] = { 364 0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000, 365 0x0000017E, 0x00000000, 0x00000000, 0x00000000, 366 0x00000000, 0x00000000, 0x00000000, 0x00000000, 367 0x00000000, 0x00000000, 0x00000000, 0x00000000, 368 0x00000000, 0x00000000, 0x00000000, 0x00000000, 369 0x00000000, 0x00000000, 0x00000000, 0x00000000, 370 0x00000000, 0x00000000, 0x00000000, 0x00000000, 371 0x00000000, 0x00000000, 0x00000000, 0x00000000, 372 }; 373 374 /* Packet types for packets with an Innermost/Last MAC header */ 375 static const u32 ice_ptypes_mac_il[] = { 376 0x00000000, 0x00000000, 0x00000000, 0x00000000, 377 0x00000000, 0x00000000, 0x00000000, 0x00000000, 378 0x00000000, 0x00000000, 0x00000000, 0x00000000, 379 0x00000000, 0x00000000, 0x00000000, 0x00000000, 380 0x00000000, 0x00000000, 0x00000000, 0x00000000, 381 0x00000000, 0x00000000, 0x00000000, 0x00000000, 382 0x00000000, 0x00000000, 0x00000000, 0x00000000, 383 0x00000000, 0x00000000, 0x00000000, 0x00000000, 384 }; 385 386 /* Packet types for GTPC */ 387 static const u32 ice_ptypes_gtpc[] = { 388 0x00000000, 0x00000000, 0x00000000, 0x00000000, 389 0x00000000, 0x00000000, 0x00000000, 0x00000000, 390 0x00000000, 0x00000000, 0x00000180, 0x00000000, 391 0x00000000, 0x00000000, 0x00000000, 0x00000000, 392 0x00000000, 0x00000000, 0x00000000, 0x00000000, 393 0x00000000, 0x00000000, 0x00000000, 0x00000000, 394 0x00000000, 0x00000000, 0x00000000, 0x00000000, 395 0x00000000, 0x00000000, 0x00000000, 0x00000000, 396 }; 397 398 /* Packet types for GTPC with TEID */ 399 static const u32 ice_ptypes_gtpc_tid[] = { 400 0x00000000, 0x00000000, 0x00000000, 0x00000000, 401 0x00000000, 0x00000000, 0x00000000, 0x00000000, 402 0x00000000, 0x00000000, 0x00000060, 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 }; 409 410 /* Packet types for GTPU */ 411 static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = { 412 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, 413 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 414 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 415 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 416 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 417 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, 418 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 419 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 420 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 421 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 422 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, 423 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 424 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 425 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 426 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH }, 427 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, 428 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 429 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 430 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 431 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH }, 432 }; 433 434 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = { 435 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 436 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 437 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 438 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 439 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 440 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 441 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 442 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 443 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 444 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 445 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 446 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 447 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 448 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 449 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 450 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 451 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 452 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 453 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 454 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 455 }; 456 457 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = { 458 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK }, 459 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 460 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 461 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK }, 462 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK }, 463 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK }, 464 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 465 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 466 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK }, 467 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK }, 468 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK }, 469 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 470 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 471 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK }, 472 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK }, 473 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK }, 474 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 475 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 476 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK }, 477 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK }, 478 }; 479 480 static const u32 ice_ptypes_gtpu[] = { 481 0x00000000, 0x00000000, 0x00000000, 0x00000000, 482 0x00000000, 0x00000000, 0x00000000, 0x00000000, 483 0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000, 484 0x00000000, 0x00000000, 0x00000000, 0x00000000, 485 0x00000000, 0x00000000, 0x00000000, 0x00000000, 486 0x00000000, 0x00000000, 0x00000000, 0x00000000, 487 0x00000000, 0x00000000, 0x00000000, 0x00000000, 488 0x00000000, 0x00000000, 0x00000000, 0x00000000, 489 }; 490 491 /* Packet types for PPPoE */ 492 static const u32 ice_ptypes_pppoe[] = { 493 0x00000000, 0x00000000, 0x00000000, 0x00000000, 494 0x00000000, 0x00000000, 0x00000000, 0x00000000, 495 0x00000000, 0x03ffe000, 0x00000000, 0x00000000, 496 0x00000000, 0x00000000, 0x00000000, 0x00000000, 497 0x00000000, 0x00000000, 0x00000000, 0x00000000, 498 0x00000000, 0x00000000, 0x00000000, 0x00000000, 499 0x00000000, 0x00000000, 0x00000000, 0x00000000, 500 0x00000000, 0x00000000, 0x00000000, 0x00000000, 501 }; 502 503 /* Packet types for packets with PFCP NODE header */ 504 static const u32 ice_ptypes_pfcp_node[] = { 505 0x00000000, 0x00000000, 0x00000000, 0x00000000, 506 0x00000000, 0x00000000, 0x00000000, 0x00000000, 507 0x00000000, 0x00000000, 0x80000000, 0x00000002, 508 0x00000000, 0x00000000, 0x00000000, 0x00000000, 509 0x00000000, 0x00000000, 0x00000000, 0x00000000, 510 0x00000000, 0x00000000, 0x00000000, 0x00000000, 511 0x00000000, 0x00000000, 0x00000000, 0x00000000, 512 0x00000000, 0x00000000, 0x00000000, 0x00000000, 513 }; 514 515 /* Packet types for packets with PFCP SESSION header */ 516 static const u32 ice_ptypes_pfcp_session[] = { 517 0x00000000, 0x00000000, 0x00000000, 0x00000000, 518 0x00000000, 0x00000000, 0x00000000, 0x00000000, 519 0x00000000, 0x00000000, 0x00000000, 0x00000005, 520 0x00000000, 0x00000000, 0x00000000, 0x00000000, 521 0x00000000, 0x00000000, 0x00000000, 0x00000000, 522 0x00000000, 0x00000000, 0x00000000, 0x00000000, 523 0x00000000, 0x00000000, 0x00000000, 0x00000000, 524 0x00000000, 0x00000000, 0x00000000, 0x00000000, 525 }; 526 527 /* Packet types for L2TPv3 */ 528 static const u32 ice_ptypes_l2tpv3[] = { 529 0x00000000, 0x00000000, 0x00000000, 0x00000000, 530 0x00000000, 0x00000000, 0x00000000, 0x00000000, 531 0x00000000, 0x00000000, 0x00000000, 0x00000300, 532 0x00000000, 0x00000000, 0x00000000, 0x00000000, 533 0x00000000, 0x00000000, 0x00000000, 0x00000000, 534 0x00000000, 0x00000000, 0x00000000, 0x00000000, 535 0x00000000, 0x00000000, 0x00000000, 0x00000000, 536 0x00000000, 0x00000000, 0x00000000, 0x00000000, 537 }; 538 539 /* Packet types for ESP */ 540 static const u32 ice_ptypes_esp[] = { 541 0x00000000, 0x00000000, 0x00000000, 0x00000000, 542 0x00000000, 0x00000003, 0x00000000, 0x00000000, 543 0x00000000, 0x00000000, 0x00000000, 0x00000000, 544 0x00000000, 0x00000000, 0x00000000, 0x00000000, 545 0x00000000, 0x00000000, 0x00000000, 0x00000000, 546 0x00000000, 0x00000000, 0x00000000, 0x00000000, 547 0x00000000, 0x00000000, 0x00000000, 0x00000000, 548 0x00000000, 0x00000000, 0x00000000, 0x00000000, 549 }; 550 551 /* Packet types for AH */ 552 static const u32 ice_ptypes_ah[] = { 553 0x00000000, 0x00000000, 0x00000000, 0x00000000, 554 0x00000000, 0x0000000C, 0x00000000, 0x00000000, 555 0x00000000, 0x00000000, 0x00000000, 0x00000000, 556 0x00000000, 0x00000000, 0x00000000, 0x00000000, 557 0x00000000, 0x00000000, 0x00000000, 0x00000000, 558 0x00000000, 0x00000000, 0x00000000, 0x00000000, 559 0x00000000, 0x00000000, 0x00000000, 0x00000000, 560 0x00000000, 0x00000000, 0x00000000, 0x00000000, 561 }; 562 563 /* Packet types for packets with NAT_T ESP header */ 564 static const u32 ice_ptypes_nat_t_esp[] = { 565 0x00000000, 0x00000000, 0x00000000, 0x00000000, 566 0x00000000, 0x00000030, 0x00000000, 0x00000000, 567 0x00000000, 0x00000000, 0x00000000, 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 static const u32 ice_ptypes_mac_non_ip_ofos[] = { 576 0x00000846, 0x00000000, 0x00000000, 0x00000000, 577 0x00000000, 0x00000000, 0x00000000, 0x00000000, 578 0x00400000, 0x03FFF000, 0x00000000, 0x00000000, 579 0x00000000, 0x00000000, 0x00000000, 0x00000000, 580 0x00000000, 0x00000000, 0x00000000, 0x00000000, 581 0x00000000, 0x00000000, 0x00000000, 0x00000000, 582 0x00000000, 0x00000000, 0x00000000, 0x00000000, 583 0x00000000, 0x00000000, 0x00000000, 0x00000000, 584 }; 585 586 /* Manage parameters and info. used during the creation of a flow profile */ 587 struct ice_flow_prof_params { 588 enum ice_block blk; 589 u16 entry_length; /* # of bytes formatted entry will require */ 590 u8 es_cnt; 591 struct ice_flow_prof *prof; 592 593 /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0 594 * This will give us the direction flags. 595 */ 596 struct ice_fv_word es[ICE_MAX_FV_WORDS]; 597 /* attributes can be used to add attributes to a particular PTYPE */ 598 const struct ice_ptype_attributes *attr; 599 u16 attr_cnt; 600 601 u16 mask[ICE_MAX_FV_WORDS]; 602 DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX); 603 }; 604 605 #define ICE_FLOW_RSS_HDRS_INNER_MASK \ 606 (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \ 607 ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \ 608 ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \ 609 ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \ 610 ICE_FLOW_SEG_HDR_NAT_T_ESP) 611 612 #define ICE_FLOW_SEG_HDRS_L2_MASK \ 613 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN) 614 #define ICE_FLOW_SEG_HDRS_L3_MASK \ 615 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP) 616 #define ICE_FLOW_SEG_HDRS_L4_MASK \ 617 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \ 618 ICE_FLOW_SEG_HDR_SCTP) 619 /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */ 620 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \ 621 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP) 622 623 /** 624 * ice_flow_val_hdrs - validates packet segments for valid protocol headers 625 * @segs: array of one or more packet segments that describe the flow 626 * @segs_cnt: number of packet segments provided 627 */ 628 static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt) 629 { 630 u8 i; 631 632 for (i = 0; i < segs_cnt; i++) { 633 /* Multiple L3 headers */ 634 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK && 635 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK)) 636 return -EINVAL; 637 638 /* Multiple L4 headers */ 639 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK && 640 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)) 641 return -EINVAL; 642 } 643 644 return 0; 645 } 646 647 /* Sizes of fixed known protocol headers without header options */ 648 #define ICE_FLOW_PROT_HDR_SZ_MAC 14 649 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN (ICE_FLOW_PROT_HDR_SZ_MAC + 2) 650 #define ICE_FLOW_PROT_HDR_SZ_IPV4 20 651 #define ICE_FLOW_PROT_HDR_SZ_IPV6 40 652 #define ICE_FLOW_PROT_HDR_SZ_ARP 28 653 #define ICE_FLOW_PROT_HDR_SZ_ICMP 8 654 #define ICE_FLOW_PROT_HDR_SZ_TCP 20 655 #define ICE_FLOW_PROT_HDR_SZ_UDP 8 656 #define ICE_FLOW_PROT_HDR_SZ_SCTP 12 657 658 /** 659 * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers 660 * @params: information about the flow to be processed 661 * @seg: index of packet segment whose header size is to be determined 662 */ 663 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg) 664 { 665 u16 sz; 666 667 /* L2 headers */ 668 sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ? 669 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC; 670 671 /* L3 headers */ 672 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) 673 sz += ICE_FLOW_PROT_HDR_SZ_IPV4; 674 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6) 675 sz += ICE_FLOW_PROT_HDR_SZ_IPV6; 676 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP) 677 sz += ICE_FLOW_PROT_HDR_SZ_ARP; 678 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK) 679 /* An L3 header is required if L4 is specified */ 680 return 0; 681 682 /* L4 headers */ 683 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP) 684 sz += ICE_FLOW_PROT_HDR_SZ_ICMP; 685 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP) 686 sz += ICE_FLOW_PROT_HDR_SZ_TCP; 687 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP) 688 sz += ICE_FLOW_PROT_HDR_SZ_UDP; 689 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP) 690 sz += ICE_FLOW_PROT_HDR_SZ_SCTP; 691 692 return sz; 693 } 694 695 /** 696 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments 697 * @params: information about the flow to be processed 698 * 699 * This function identifies the packet types associated with the protocol 700 * headers being present in packet segments of the specified flow profile. 701 */ 702 static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params) 703 { 704 struct ice_flow_prof *prof; 705 u8 i; 706 707 memset(params->ptypes, 0xff, sizeof(params->ptypes)); 708 709 prof = params->prof; 710 711 for (i = 0; i < params->prof->segs_cnt; i++) { 712 const unsigned long *src; 713 u32 hdrs; 714 715 hdrs = prof->segs[i].hdrs; 716 717 if (hdrs & ICE_FLOW_SEG_HDR_ETH) { 718 src = !i ? (const unsigned long *)ice_ptypes_mac_ofos : 719 (const unsigned long *)ice_ptypes_mac_il; 720 bitmap_and(params->ptypes, params->ptypes, src, 721 ICE_FLOW_PTYPE_MAX); 722 } 723 724 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) { 725 src = (const unsigned long *)ice_ptypes_macvlan_il; 726 bitmap_and(params->ptypes, params->ptypes, src, 727 ICE_FLOW_PTYPE_MAX); 728 } 729 730 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) { 731 bitmap_and(params->ptypes, params->ptypes, 732 (const unsigned long *)ice_ptypes_arp_of, 733 ICE_FLOW_PTYPE_MAX); 734 } 735 736 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) && 737 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) { 738 src = i ? (const unsigned long *)ice_ptypes_ipv4_il : 739 (const unsigned long *)ice_ptypes_ipv4_ofos_all; 740 bitmap_and(params->ptypes, params->ptypes, src, 741 ICE_FLOW_PTYPE_MAX); 742 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) && 743 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) { 744 src = i ? (const unsigned long *)ice_ptypes_ipv6_il : 745 (const unsigned long *)ice_ptypes_ipv6_ofos_all; 746 bitmap_and(params->ptypes, params->ptypes, src, 747 ICE_FLOW_PTYPE_MAX); 748 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) && 749 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) { 750 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 : 751 (const unsigned long *)ice_ptypes_ipv4_il_no_l4; 752 bitmap_and(params->ptypes, params->ptypes, src, 753 ICE_FLOW_PTYPE_MAX); 754 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) { 755 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos : 756 (const unsigned long *)ice_ptypes_ipv4_il; 757 bitmap_and(params->ptypes, params->ptypes, src, 758 ICE_FLOW_PTYPE_MAX); 759 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) && 760 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) { 761 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 : 762 (const unsigned long *)ice_ptypes_ipv6_il_no_l4; 763 bitmap_and(params->ptypes, params->ptypes, src, 764 ICE_FLOW_PTYPE_MAX); 765 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) { 766 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos : 767 (const unsigned long *)ice_ptypes_ipv6_il; 768 bitmap_and(params->ptypes, params->ptypes, src, 769 ICE_FLOW_PTYPE_MAX); 770 } 771 772 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) { 773 src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos; 774 bitmap_and(params->ptypes, params->ptypes, src, 775 ICE_FLOW_PTYPE_MAX); 776 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) { 777 src = (const unsigned long *)ice_ptypes_pppoe; 778 bitmap_and(params->ptypes, params->ptypes, src, 779 ICE_FLOW_PTYPE_MAX); 780 } else { 781 src = (const unsigned long *)ice_ptypes_pppoe; 782 bitmap_andnot(params->ptypes, params->ptypes, src, 783 ICE_FLOW_PTYPE_MAX); 784 } 785 786 if (hdrs & ICE_FLOW_SEG_HDR_UDP) { 787 src = (const unsigned long *)ice_ptypes_udp_il; 788 bitmap_and(params->ptypes, params->ptypes, src, 789 ICE_FLOW_PTYPE_MAX); 790 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) { 791 bitmap_and(params->ptypes, params->ptypes, 792 (const unsigned long *)ice_ptypes_tcp_il, 793 ICE_FLOW_PTYPE_MAX); 794 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) { 795 src = (const unsigned long *)ice_ptypes_sctp_il; 796 bitmap_and(params->ptypes, params->ptypes, src, 797 ICE_FLOW_PTYPE_MAX); 798 } 799 800 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) { 801 src = !i ? (const unsigned long *)ice_ptypes_icmp_of : 802 (const unsigned long *)ice_ptypes_icmp_il; 803 bitmap_and(params->ptypes, params->ptypes, src, 804 ICE_FLOW_PTYPE_MAX); 805 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) { 806 if (!i) { 807 src = (const unsigned long *)ice_ptypes_gre_of; 808 bitmap_and(params->ptypes, params->ptypes, 809 src, ICE_FLOW_PTYPE_MAX); 810 } 811 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) { 812 src = (const unsigned long *)ice_ptypes_gtpc; 813 bitmap_and(params->ptypes, params->ptypes, src, 814 ICE_FLOW_PTYPE_MAX); 815 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) { 816 src = (const unsigned long *)ice_ptypes_gtpc_tid; 817 bitmap_and(params->ptypes, params->ptypes, src, 818 ICE_FLOW_PTYPE_MAX); 819 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) { 820 src = (const unsigned long *)ice_ptypes_gtpu; 821 bitmap_and(params->ptypes, params->ptypes, src, 822 ICE_FLOW_PTYPE_MAX); 823 824 /* Attributes for GTP packet with downlink */ 825 params->attr = ice_attr_gtpu_down; 826 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down); 827 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) { 828 src = (const unsigned long *)ice_ptypes_gtpu; 829 bitmap_and(params->ptypes, params->ptypes, src, 830 ICE_FLOW_PTYPE_MAX); 831 832 /* Attributes for GTP packet with uplink */ 833 params->attr = ice_attr_gtpu_up; 834 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up); 835 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) { 836 src = (const unsigned long *)ice_ptypes_gtpu; 837 bitmap_and(params->ptypes, params->ptypes, src, 838 ICE_FLOW_PTYPE_MAX); 839 840 /* Attributes for GTP packet with Extension Header */ 841 params->attr = ice_attr_gtpu_eh; 842 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh); 843 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) { 844 src = (const unsigned long *)ice_ptypes_gtpu; 845 bitmap_and(params->ptypes, params->ptypes, src, 846 ICE_FLOW_PTYPE_MAX); 847 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) { 848 src = (const unsigned long *)ice_ptypes_l2tpv3; 849 bitmap_and(params->ptypes, params->ptypes, src, 850 ICE_FLOW_PTYPE_MAX); 851 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) { 852 src = (const unsigned long *)ice_ptypes_esp; 853 bitmap_and(params->ptypes, params->ptypes, src, 854 ICE_FLOW_PTYPE_MAX); 855 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) { 856 src = (const unsigned long *)ice_ptypes_ah; 857 bitmap_and(params->ptypes, params->ptypes, src, 858 ICE_FLOW_PTYPE_MAX); 859 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) { 860 src = (const unsigned long *)ice_ptypes_nat_t_esp; 861 bitmap_and(params->ptypes, params->ptypes, src, 862 ICE_FLOW_PTYPE_MAX); 863 } 864 865 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) { 866 if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE) 867 src = (const unsigned long *)ice_ptypes_pfcp_node; 868 else 869 src = (const unsigned long *)ice_ptypes_pfcp_session; 870 871 bitmap_and(params->ptypes, params->ptypes, src, 872 ICE_FLOW_PTYPE_MAX); 873 } else { 874 src = (const unsigned long *)ice_ptypes_pfcp_node; 875 bitmap_andnot(params->ptypes, params->ptypes, src, 876 ICE_FLOW_PTYPE_MAX); 877 878 src = (const unsigned long *)ice_ptypes_pfcp_session; 879 bitmap_andnot(params->ptypes, params->ptypes, src, 880 ICE_FLOW_PTYPE_MAX); 881 } 882 } 883 884 return 0; 885 } 886 887 /** 888 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field 889 * @hw: pointer to the HW struct 890 * @params: information about the flow to be processed 891 * @seg: packet segment index of the field to be extracted 892 * @fld: ID of field to be extracted 893 * @match: bit field of all fields 894 * 895 * This function determines the protocol ID, offset, and size of the given 896 * field. It then allocates one or more extraction sequence entries for the 897 * given field, and fill the entries with protocol ID and offset information. 898 */ 899 static int 900 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params, 901 u8 seg, enum ice_flow_field fld, u64 match) 902 { 903 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX; 904 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL; 905 u8 fv_words = hw->blk[params->blk].es.fvw; 906 struct ice_flow_fld_info *flds; 907 u16 cnt, ese_bits, i; 908 u16 sib_mask = 0; 909 u16 mask; 910 u16 off; 911 912 flds = params->prof->segs[seg].fields; 913 914 switch (fld) { 915 case ICE_FLOW_FIELD_IDX_ETH_DA: 916 case ICE_FLOW_FIELD_IDX_ETH_SA: 917 case ICE_FLOW_FIELD_IDX_S_VLAN: 918 case ICE_FLOW_FIELD_IDX_C_VLAN: 919 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL; 920 break; 921 case ICE_FLOW_FIELD_IDX_ETH_TYPE: 922 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL; 923 break; 924 case ICE_FLOW_FIELD_IDX_IPV4_DSCP: 925 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 926 break; 927 case ICE_FLOW_FIELD_IDX_IPV6_DSCP: 928 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 929 break; 930 case ICE_FLOW_FIELD_IDX_IPV4_TTL: 931 case ICE_FLOW_FIELD_IDX_IPV4_PROT: 932 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 933 934 /* TTL and PROT share the same extraction seq. entry. 935 * Each is considered a sibling to the other in terms of sharing 936 * the same extraction sequence entry. 937 */ 938 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL) 939 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT; 940 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT) 941 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL; 942 943 /* If the sibling field is also included, that field's 944 * mask needs to be included. 945 */ 946 if (match & BIT(sib)) 947 sib_mask = ice_flds_info[sib].mask; 948 break; 949 case ICE_FLOW_FIELD_IDX_IPV6_TTL: 950 case ICE_FLOW_FIELD_IDX_IPV6_PROT: 951 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 952 953 /* TTL and PROT share the same extraction seq. entry. 954 * Each is considered a sibling to the other in terms of sharing 955 * the same extraction sequence entry. 956 */ 957 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL) 958 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT; 959 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT) 960 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL; 961 962 /* If the sibling field is also included, that field's 963 * mask needs to be included. 964 */ 965 if (match & BIT(sib)) 966 sib_mask = ice_flds_info[sib].mask; 967 break; 968 case ICE_FLOW_FIELD_IDX_IPV4_SA: 969 case ICE_FLOW_FIELD_IDX_IPV4_DA: 970 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 971 break; 972 case ICE_FLOW_FIELD_IDX_IPV6_SA: 973 case ICE_FLOW_FIELD_IDX_IPV6_DA: 974 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 975 break; 976 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT: 977 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT: 978 case ICE_FLOW_FIELD_IDX_TCP_FLAGS: 979 prot_id = ICE_PROT_TCP_IL; 980 break; 981 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT: 982 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT: 983 prot_id = ICE_PROT_UDP_IL_OR_S; 984 break; 985 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT: 986 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT: 987 prot_id = ICE_PROT_SCTP_IL; 988 break; 989 case ICE_FLOW_FIELD_IDX_GTPC_TEID: 990 case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID: 991 case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID: 992 case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID: 993 case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID: 994 case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI: 995 /* GTP is accessed through UDP OF protocol */ 996 prot_id = ICE_PROT_UDP_OF; 997 break; 998 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID: 999 prot_id = ICE_PROT_PPPOE; 1000 break; 1001 case ICE_FLOW_FIELD_IDX_PFCP_SEID: 1002 prot_id = ICE_PROT_UDP_IL_OR_S; 1003 break; 1004 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID: 1005 prot_id = ICE_PROT_L2TPV3; 1006 break; 1007 case ICE_FLOW_FIELD_IDX_ESP_SPI: 1008 prot_id = ICE_PROT_ESP_F; 1009 break; 1010 case ICE_FLOW_FIELD_IDX_AH_SPI: 1011 prot_id = ICE_PROT_ESP_2; 1012 break; 1013 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI: 1014 prot_id = ICE_PROT_UDP_IL_OR_S; 1015 break; 1016 case ICE_FLOW_FIELD_IDX_ARP_SIP: 1017 case ICE_FLOW_FIELD_IDX_ARP_DIP: 1018 case ICE_FLOW_FIELD_IDX_ARP_SHA: 1019 case ICE_FLOW_FIELD_IDX_ARP_DHA: 1020 case ICE_FLOW_FIELD_IDX_ARP_OP: 1021 prot_id = ICE_PROT_ARP_OF; 1022 break; 1023 case ICE_FLOW_FIELD_IDX_ICMP_TYPE: 1024 case ICE_FLOW_FIELD_IDX_ICMP_CODE: 1025 /* ICMP type and code share the same extraction seq. entry */ 1026 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ? 1027 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL; 1028 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ? 1029 ICE_FLOW_FIELD_IDX_ICMP_CODE : 1030 ICE_FLOW_FIELD_IDX_ICMP_TYPE; 1031 break; 1032 case ICE_FLOW_FIELD_IDX_GRE_KEYID: 1033 prot_id = ICE_PROT_GRE_OF; 1034 break; 1035 default: 1036 return -EOPNOTSUPP; 1037 } 1038 1039 /* Each extraction sequence entry is a word in size, and extracts a 1040 * word-aligned offset from a protocol header. 1041 */ 1042 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE; 1043 1044 flds[fld].xtrct.prot_id = prot_id; 1045 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) * 1046 ICE_FLOW_FV_EXTRACT_SZ; 1047 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits); 1048 flds[fld].xtrct.idx = params->es_cnt; 1049 flds[fld].xtrct.mask = ice_flds_info[fld].mask; 1050 1051 /* Adjust the next field-entry index after accommodating the number of 1052 * entries this field consumes 1053 */ 1054 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size, 1055 ese_bits); 1056 1057 /* Fill in the extraction sequence entries needed for this field */ 1058 off = flds[fld].xtrct.off; 1059 mask = flds[fld].xtrct.mask; 1060 for (i = 0; i < cnt; i++) { 1061 /* Only consume an extraction sequence entry if there is no 1062 * sibling field associated with this field or the sibling entry 1063 * already extracts the word shared with this field. 1064 */ 1065 if (sib == ICE_FLOW_FIELD_IDX_MAX || 1066 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL || 1067 flds[sib].xtrct.off != off) { 1068 u8 idx; 1069 1070 /* Make sure the number of extraction sequence required 1071 * does not exceed the block's capability 1072 */ 1073 if (params->es_cnt >= fv_words) 1074 return -ENOSPC; 1075 1076 /* some blocks require a reversed field vector layout */ 1077 if (hw->blk[params->blk].es.reverse) 1078 idx = fv_words - params->es_cnt - 1; 1079 else 1080 idx = params->es_cnt; 1081 1082 params->es[idx].prot_id = prot_id; 1083 params->es[idx].off = off; 1084 params->mask[idx] = mask | sib_mask; 1085 params->es_cnt++; 1086 } 1087 1088 off += ICE_FLOW_FV_EXTRACT_SZ; 1089 } 1090 1091 return 0; 1092 } 1093 1094 /** 1095 * ice_flow_xtract_raws - Create extract sequence entries for raw bytes 1096 * @hw: pointer to the HW struct 1097 * @params: information about the flow to be processed 1098 * @seg: index of packet segment whose raw fields are to be extracted 1099 */ 1100 static int 1101 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params, 1102 u8 seg) 1103 { 1104 u16 fv_words; 1105 u16 hdrs_sz; 1106 u8 i; 1107 1108 if (!params->prof->segs[seg].raws_cnt) 1109 return 0; 1110 1111 if (params->prof->segs[seg].raws_cnt > 1112 ARRAY_SIZE(params->prof->segs[seg].raws)) 1113 return -ENOSPC; 1114 1115 /* Offsets within the segment headers are not supported */ 1116 hdrs_sz = ice_flow_calc_seg_sz(params, seg); 1117 if (!hdrs_sz) 1118 return -EINVAL; 1119 1120 fv_words = hw->blk[params->blk].es.fvw; 1121 1122 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) { 1123 struct ice_flow_seg_fld_raw *raw; 1124 u16 off, cnt, j; 1125 1126 raw = ¶ms->prof->segs[seg].raws[i]; 1127 1128 /* Storing extraction information */ 1129 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S; 1130 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) * 1131 ICE_FLOW_FV_EXTRACT_SZ; 1132 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) * 1133 BITS_PER_BYTE; 1134 raw->info.xtrct.idx = params->es_cnt; 1135 1136 /* Determine the number of field vector entries this raw field 1137 * consumes. 1138 */ 1139 cnt = DIV_ROUND_UP(raw->info.xtrct.disp + 1140 (raw->info.src.last * BITS_PER_BYTE), 1141 (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE)); 1142 off = raw->info.xtrct.off; 1143 for (j = 0; j < cnt; j++) { 1144 u16 idx; 1145 1146 /* Make sure the number of extraction sequence required 1147 * does not exceed the block's capability 1148 */ 1149 if (params->es_cnt >= hw->blk[params->blk].es.count || 1150 params->es_cnt >= ICE_MAX_FV_WORDS) 1151 return -ENOSPC; 1152 1153 /* some blocks require a reversed field vector layout */ 1154 if (hw->blk[params->blk].es.reverse) 1155 idx = fv_words - params->es_cnt - 1; 1156 else 1157 idx = params->es_cnt; 1158 1159 params->es[idx].prot_id = raw->info.xtrct.prot_id; 1160 params->es[idx].off = off; 1161 params->es_cnt++; 1162 off += ICE_FLOW_FV_EXTRACT_SZ; 1163 } 1164 } 1165 1166 return 0; 1167 } 1168 1169 /** 1170 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments 1171 * @hw: pointer to the HW struct 1172 * @params: information about the flow to be processed 1173 * 1174 * This function iterates through all matched fields in the given segments, and 1175 * creates an extraction sequence for the fields. 1176 */ 1177 static int 1178 ice_flow_create_xtrct_seq(struct ice_hw *hw, 1179 struct ice_flow_prof_params *params) 1180 { 1181 struct ice_flow_prof *prof = params->prof; 1182 int status = 0; 1183 u8 i; 1184 1185 for (i = 0; i < prof->segs_cnt; i++) { 1186 u64 match = params->prof->segs[i].match; 1187 enum ice_flow_field j; 1188 1189 for_each_set_bit(j, (unsigned long *)&match, 1190 ICE_FLOW_FIELD_IDX_MAX) { 1191 status = ice_flow_xtract_fld(hw, params, i, j, match); 1192 if (status) 1193 return status; 1194 clear_bit(j, (unsigned long *)&match); 1195 } 1196 1197 /* Process raw matching bytes */ 1198 status = ice_flow_xtract_raws(hw, params, i); 1199 if (status) 1200 return status; 1201 } 1202 1203 return status; 1204 } 1205 1206 /** 1207 * ice_flow_proc_segs - process all packet segments associated with a profile 1208 * @hw: pointer to the HW struct 1209 * @params: information about the flow to be processed 1210 */ 1211 static int 1212 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params) 1213 { 1214 int status; 1215 1216 status = ice_flow_proc_seg_hdrs(params); 1217 if (status) 1218 return status; 1219 1220 status = ice_flow_create_xtrct_seq(hw, params); 1221 if (status) 1222 return status; 1223 1224 switch (params->blk) { 1225 case ICE_BLK_FD: 1226 case ICE_BLK_RSS: 1227 status = 0; 1228 break; 1229 default: 1230 return -EOPNOTSUPP; 1231 } 1232 1233 return status; 1234 } 1235 1236 #define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001 1237 #define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002 1238 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004 1239 1240 /** 1241 * ice_flow_find_prof_conds - Find a profile matching headers and conditions 1242 * @hw: pointer to the HW struct 1243 * @blk: classification stage 1244 * @dir: flow direction 1245 * @segs: array of one or more packet segments that describe the flow 1246 * @segs_cnt: number of packet segments provided 1247 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI) 1248 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*) 1249 */ 1250 static struct ice_flow_prof * 1251 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk, 1252 enum ice_flow_dir dir, struct ice_flow_seg_info *segs, 1253 u8 segs_cnt, u16 vsi_handle, u32 conds) 1254 { 1255 struct ice_flow_prof *p, *prof = NULL; 1256 1257 mutex_lock(&hw->fl_profs_locks[blk]); 1258 list_for_each_entry(p, &hw->fl_profs[blk], l_entry) 1259 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) && 1260 segs_cnt && segs_cnt == p->segs_cnt) { 1261 u8 i; 1262 1263 /* Check for profile-VSI association if specified */ 1264 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) && 1265 ice_is_vsi_valid(hw, vsi_handle) && 1266 !test_bit(vsi_handle, p->vsis)) 1267 continue; 1268 1269 /* Protocol headers must be checked. Matched fields are 1270 * checked if specified. 1271 */ 1272 for (i = 0; i < segs_cnt; i++) 1273 if (segs[i].hdrs != p->segs[i].hdrs || 1274 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) && 1275 segs[i].match != p->segs[i].match)) 1276 break; 1277 1278 /* A match is found if all segments are matched */ 1279 if (i == segs_cnt) { 1280 prof = p; 1281 break; 1282 } 1283 } 1284 mutex_unlock(&hw->fl_profs_locks[blk]); 1285 1286 return prof; 1287 } 1288 1289 /** 1290 * ice_flow_find_prof_id - Look up a profile with given profile ID 1291 * @hw: pointer to the HW struct 1292 * @blk: classification stage 1293 * @prof_id: unique ID to identify this flow profile 1294 */ 1295 static struct ice_flow_prof * 1296 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id) 1297 { 1298 struct ice_flow_prof *p; 1299 1300 list_for_each_entry(p, &hw->fl_profs[blk], l_entry) 1301 if (p->id == prof_id) 1302 return p; 1303 1304 return NULL; 1305 } 1306 1307 /** 1308 * ice_dealloc_flow_entry - Deallocate flow entry memory 1309 * @hw: pointer to the HW struct 1310 * @entry: flow entry to be removed 1311 */ 1312 static void 1313 ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry) 1314 { 1315 if (!entry) 1316 return; 1317 1318 if (entry->entry) 1319 devm_kfree(ice_hw_to_dev(hw), entry->entry); 1320 1321 devm_kfree(ice_hw_to_dev(hw), entry); 1322 } 1323 1324 /** 1325 * ice_flow_rem_entry_sync - Remove a flow entry 1326 * @hw: pointer to the HW struct 1327 * @blk: classification stage 1328 * @entry: flow entry to be removed 1329 */ 1330 static int 1331 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk, 1332 struct ice_flow_entry *entry) 1333 { 1334 if (!entry) 1335 return -EINVAL; 1336 1337 list_del(&entry->l_entry); 1338 1339 ice_dealloc_flow_entry(hw, entry); 1340 1341 return 0; 1342 } 1343 1344 /** 1345 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields 1346 * @hw: pointer to the HW struct 1347 * @blk: classification stage 1348 * @dir: flow direction 1349 * @prof_id: unique ID to identify this flow profile 1350 * @segs: array of one or more packet segments that describe the flow 1351 * @segs_cnt: number of packet segments provided 1352 * @prof: stores the returned flow profile added 1353 * 1354 * Assumption: the caller has acquired the lock to the profile list 1355 */ 1356 static int 1357 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk, 1358 enum ice_flow_dir dir, u64 prof_id, 1359 struct ice_flow_seg_info *segs, u8 segs_cnt, 1360 struct ice_flow_prof **prof) 1361 { 1362 struct ice_flow_prof_params *params; 1363 int status; 1364 u8 i; 1365 1366 if (!prof) 1367 return -EINVAL; 1368 1369 params = kzalloc(sizeof(*params), GFP_KERNEL); 1370 if (!params) 1371 return -ENOMEM; 1372 1373 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof), 1374 GFP_KERNEL); 1375 if (!params->prof) { 1376 status = -ENOMEM; 1377 goto free_params; 1378 } 1379 1380 /* initialize extraction sequence to all invalid (0xff) */ 1381 for (i = 0; i < ICE_MAX_FV_WORDS; i++) { 1382 params->es[i].prot_id = ICE_PROT_INVALID; 1383 params->es[i].off = ICE_FV_OFFSET_INVAL; 1384 } 1385 1386 params->blk = blk; 1387 params->prof->id = prof_id; 1388 params->prof->dir = dir; 1389 params->prof->segs_cnt = segs_cnt; 1390 1391 /* Make a copy of the segments that need to be persistent in the flow 1392 * profile instance 1393 */ 1394 for (i = 0; i < segs_cnt; i++) 1395 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs)); 1396 1397 status = ice_flow_proc_segs(hw, params); 1398 if (status) { 1399 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n"); 1400 goto out; 1401 } 1402 1403 /* Add a HW profile for this flow profile */ 1404 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes, 1405 params->attr, params->attr_cnt, params->es, 1406 params->mask); 1407 if (status) { 1408 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n"); 1409 goto out; 1410 } 1411 1412 INIT_LIST_HEAD(¶ms->prof->entries); 1413 mutex_init(¶ms->prof->entries_lock); 1414 *prof = params->prof; 1415 1416 out: 1417 if (status) 1418 devm_kfree(ice_hw_to_dev(hw), params->prof); 1419 free_params: 1420 kfree(params); 1421 1422 return status; 1423 } 1424 1425 /** 1426 * ice_flow_rem_prof_sync - remove a flow profile 1427 * @hw: pointer to the hardware structure 1428 * @blk: classification stage 1429 * @prof: pointer to flow profile to remove 1430 * 1431 * Assumption: the caller has acquired the lock to the profile list 1432 */ 1433 static int 1434 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk, 1435 struct ice_flow_prof *prof) 1436 { 1437 int status; 1438 1439 /* Remove all remaining flow entries before removing the flow profile */ 1440 if (!list_empty(&prof->entries)) { 1441 struct ice_flow_entry *e, *t; 1442 1443 mutex_lock(&prof->entries_lock); 1444 1445 list_for_each_entry_safe(e, t, &prof->entries, l_entry) { 1446 status = ice_flow_rem_entry_sync(hw, blk, e); 1447 if (status) 1448 break; 1449 } 1450 1451 mutex_unlock(&prof->entries_lock); 1452 } 1453 1454 /* Remove all hardware profiles associated with this flow profile */ 1455 status = ice_rem_prof(hw, blk, prof->id); 1456 if (!status) { 1457 list_del(&prof->l_entry); 1458 mutex_destroy(&prof->entries_lock); 1459 devm_kfree(ice_hw_to_dev(hw), prof); 1460 } 1461 1462 return status; 1463 } 1464 1465 /** 1466 * ice_flow_assoc_prof - associate a VSI with a flow profile 1467 * @hw: pointer to the hardware structure 1468 * @blk: classification stage 1469 * @prof: pointer to flow profile 1470 * @vsi_handle: software VSI handle 1471 * 1472 * Assumption: the caller has acquired the lock to the profile list 1473 * and the software VSI handle has been validated 1474 */ 1475 static int 1476 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk, 1477 struct ice_flow_prof *prof, u16 vsi_handle) 1478 { 1479 int status = 0; 1480 1481 if (!test_bit(vsi_handle, prof->vsis)) { 1482 status = ice_add_prof_id_flow(hw, blk, 1483 ice_get_hw_vsi_num(hw, 1484 vsi_handle), 1485 prof->id); 1486 if (!status) 1487 set_bit(vsi_handle, prof->vsis); 1488 else 1489 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n", 1490 status); 1491 } 1492 1493 return status; 1494 } 1495 1496 /** 1497 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile 1498 * @hw: pointer to the hardware structure 1499 * @blk: classification stage 1500 * @prof: pointer to flow profile 1501 * @vsi_handle: software VSI handle 1502 * 1503 * Assumption: the caller has acquired the lock to the profile list 1504 * and the software VSI handle has been validated 1505 */ 1506 static int 1507 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk, 1508 struct ice_flow_prof *prof, u16 vsi_handle) 1509 { 1510 int status = 0; 1511 1512 if (test_bit(vsi_handle, prof->vsis)) { 1513 status = ice_rem_prof_id_flow(hw, blk, 1514 ice_get_hw_vsi_num(hw, 1515 vsi_handle), 1516 prof->id); 1517 if (!status) 1518 clear_bit(vsi_handle, prof->vsis); 1519 else 1520 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n", 1521 status); 1522 } 1523 1524 return status; 1525 } 1526 1527 /** 1528 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields 1529 * @hw: pointer to the HW struct 1530 * @blk: classification stage 1531 * @dir: flow direction 1532 * @prof_id: unique ID to identify this flow profile 1533 * @segs: array of one or more packet segments that describe the flow 1534 * @segs_cnt: number of packet segments provided 1535 * @prof: stores the returned flow profile added 1536 */ 1537 int 1538 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir, 1539 u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt, 1540 struct ice_flow_prof **prof) 1541 { 1542 int status; 1543 1544 if (segs_cnt > ICE_FLOW_SEG_MAX) 1545 return -ENOSPC; 1546 1547 if (!segs_cnt) 1548 return -EINVAL; 1549 1550 if (!segs) 1551 return -EINVAL; 1552 1553 status = ice_flow_val_hdrs(segs, segs_cnt); 1554 if (status) 1555 return status; 1556 1557 mutex_lock(&hw->fl_profs_locks[blk]); 1558 1559 status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt, 1560 prof); 1561 if (!status) 1562 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]); 1563 1564 mutex_unlock(&hw->fl_profs_locks[blk]); 1565 1566 return status; 1567 } 1568 1569 /** 1570 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it 1571 * @hw: pointer to the HW struct 1572 * @blk: the block for which the flow profile is to be removed 1573 * @prof_id: unique ID of the flow profile to be removed 1574 */ 1575 int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id) 1576 { 1577 struct ice_flow_prof *prof; 1578 int status; 1579 1580 mutex_lock(&hw->fl_profs_locks[blk]); 1581 1582 prof = ice_flow_find_prof_id(hw, blk, prof_id); 1583 if (!prof) { 1584 status = -ENOENT; 1585 goto out; 1586 } 1587 1588 /* prof becomes invalid after the call */ 1589 status = ice_flow_rem_prof_sync(hw, blk, prof); 1590 1591 out: 1592 mutex_unlock(&hw->fl_profs_locks[blk]); 1593 1594 return status; 1595 } 1596 1597 /** 1598 * ice_flow_add_entry - Add a flow entry 1599 * @hw: pointer to the HW struct 1600 * @blk: classification stage 1601 * @prof_id: ID of the profile to add a new flow entry to 1602 * @entry_id: unique ID to identify this flow entry 1603 * @vsi_handle: software VSI handle for the flow entry 1604 * @prio: priority of the flow entry 1605 * @data: pointer to a data buffer containing flow entry's match values/masks 1606 * @entry_h: pointer to buffer that receives the new flow entry's handle 1607 */ 1608 int 1609 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id, 1610 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio, 1611 void *data, u64 *entry_h) 1612 { 1613 struct ice_flow_entry *e = NULL; 1614 struct ice_flow_prof *prof; 1615 int status; 1616 1617 /* No flow entry data is expected for RSS */ 1618 if (!entry_h || (!data && blk != ICE_BLK_RSS)) 1619 return -EINVAL; 1620 1621 if (!ice_is_vsi_valid(hw, vsi_handle)) 1622 return -EINVAL; 1623 1624 mutex_lock(&hw->fl_profs_locks[blk]); 1625 1626 prof = ice_flow_find_prof_id(hw, blk, prof_id); 1627 if (!prof) { 1628 status = -ENOENT; 1629 } else { 1630 /* Allocate memory for the entry being added and associate 1631 * the VSI to the found flow profile 1632 */ 1633 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL); 1634 if (!e) 1635 status = -ENOMEM; 1636 else 1637 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle); 1638 } 1639 1640 mutex_unlock(&hw->fl_profs_locks[blk]); 1641 if (status) 1642 goto out; 1643 1644 e->id = entry_id; 1645 e->vsi_handle = vsi_handle; 1646 e->prof = prof; 1647 e->priority = prio; 1648 1649 switch (blk) { 1650 case ICE_BLK_FD: 1651 case ICE_BLK_RSS: 1652 break; 1653 default: 1654 status = -EOPNOTSUPP; 1655 goto out; 1656 } 1657 1658 mutex_lock(&prof->entries_lock); 1659 list_add(&e->l_entry, &prof->entries); 1660 mutex_unlock(&prof->entries_lock); 1661 1662 *entry_h = ICE_FLOW_ENTRY_HNDL(e); 1663 1664 out: 1665 if (status && e) { 1666 if (e->entry) 1667 devm_kfree(ice_hw_to_dev(hw), e->entry); 1668 devm_kfree(ice_hw_to_dev(hw), e); 1669 } 1670 1671 return status; 1672 } 1673 1674 /** 1675 * ice_flow_rem_entry - Remove a flow entry 1676 * @hw: pointer to the HW struct 1677 * @blk: classification stage 1678 * @entry_h: handle to the flow entry to be removed 1679 */ 1680 int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h) 1681 { 1682 struct ice_flow_entry *entry; 1683 struct ice_flow_prof *prof; 1684 int status = 0; 1685 1686 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL) 1687 return -EINVAL; 1688 1689 entry = ICE_FLOW_ENTRY_PTR(entry_h); 1690 1691 /* Retain the pointer to the flow profile as the entry will be freed */ 1692 prof = entry->prof; 1693 1694 if (prof) { 1695 mutex_lock(&prof->entries_lock); 1696 status = ice_flow_rem_entry_sync(hw, blk, entry); 1697 mutex_unlock(&prof->entries_lock); 1698 } 1699 1700 return status; 1701 } 1702 1703 /** 1704 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer 1705 * @seg: packet segment the field being set belongs to 1706 * @fld: field to be set 1707 * @field_type: type of the field 1708 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 1709 * entry's input buffer 1710 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's 1711 * input buffer 1712 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from 1713 * entry's input buffer 1714 * 1715 * This helper function stores information of a field being matched, including 1716 * the type of the field and the locations of the value to match, the mask, and 1717 * the upper-bound value in the start of the input buffer for a flow entry. 1718 * This function should only be used for fixed-size data structures. 1719 * 1720 * This function also opportunistically determines the protocol headers to be 1721 * present based on the fields being set. Some fields cannot be used alone to 1722 * determine the protocol headers present. Sometimes, fields for particular 1723 * protocol headers are not matched. In those cases, the protocol headers 1724 * must be explicitly set. 1725 */ 1726 static void 1727 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 1728 enum ice_flow_fld_match_type field_type, u16 val_loc, 1729 u16 mask_loc, u16 last_loc) 1730 { 1731 u64 bit = BIT_ULL(fld); 1732 1733 seg->match |= bit; 1734 if (field_type == ICE_FLOW_FLD_TYPE_RANGE) 1735 seg->range |= bit; 1736 1737 seg->fields[fld].type = field_type; 1738 seg->fields[fld].src.val = val_loc; 1739 seg->fields[fld].src.mask = mask_loc; 1740 seg->fields[fld].src.last = last_loc; 1741 1742 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr); 1743 } 1744 1745 /** 1746 * ice_flow_set_fld - specifies locations of field from entry's input buffer 1747 * @seg: packet segment the field being set belongs to 1748 * @fld: field to be set 1749 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 1750 * entry's input buffer 1751 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's 1752 * input buffer 1753 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from 1754 * entry's input buffer 1755 * @range: indicate if field being matched is to be in a range 1756 * 1757 * This function specifies the locations, in the form of byte offsets from the 1758 * start of the input buffer for a flow entry, from where the value to match, 1759 * the mask value, and upper value can be extracted. These locations are then 1760 * stored in the flow profile. When adding a flow entry associated with the 1761 * flow profile, these locations will be used to quickly extract the values and 1762 * create the content of a match entry. This function should only be used for 1763 * fixed-size data structures. 1764 */ 1765 void 1766 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 1767 u16 val_loc, u16 mask_loc, u16 last_loc, bool range) 1768 { 1769 enum ice_flow_fld_match_type t = range ? 1770 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG; 1771 1772 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc); 1773 } 1774 1775 /** 1776 * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf 1777 * @seg: packet segment the field being set belongs to 1778 * @off: offset of the raw field from the beginning of the segment in bytes 1779 * @len: length of the raw pattern to be matched 1780 * @val_loc: location of the value to match from entry's input buffer 1781 * @mask_loc: location of mask value from entry's input buffer 1782 * 1783 * This function specifies the offset of the raw field to be match from the 1784 * beginning of the specified packet segment, and the locations, in the form of 1785 * byte offsets from the start of the input buffer for a flow entry, from where 1786 * the value to match and the mask value to be extracted. These locations are 1787 * then stored in the flow profile. When adding flow entries to the associated 1788 * flow profile, these locations can be used to quickly extract the values to 1789 * create the content of a match entry. This function should only be used for 1790 * fixed-size data structures. 1791 */ 1792 void 1793 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len, 1794 u16 val_loc, u16 mask_loc) 1795 { 1796 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) { 1797 seg->raws[seg->raws_cnt].off = off; 1798 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE; 1799 seg->raws[seg->raws_cnt].info.src.val = val_loc; 1800 seg->raws[seg->raws_cnt].info.src.mask = mask_loc; 1801 /* The "last" field is used to store the length of the field */ 1802 seg->raws[seg->raws_cnt].info.src.last = len; 1803 } 1804 1805 /* Overflows of "raws" will be handled as an error condition later in 1806 * the flow when this information is processed. 1807 */ 1808 seg->raws_cnt++; 1809 } 1810 1811 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \ 1812 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN) 1813 1814 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \ 1815 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6) 1816 1817 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \ 1818 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP) 1819 1820 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \ 1821 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \ 1822 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \ 1823 ICE_FLOW_RSS_SEG_HDR_L4_MASKS) 1824 1825 /** 1826 * ice_flow_set_rss_seg_info - setup packet segments for RSS 1827 * @segs: pointer to the flow field segment(s) 1828 * @hash_fields: fields to be hashed on for the segment(s) 1829 * @flow_hdr: protocol header fields within a packet segment 1830 * 1831 * Helper function to extract fields from hash bitmap and use flow 1832 * header value to set flow field segment for further use in flow 1833 * profile entry or removal. 1834 */ 1835 static int 1836 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields, 1837 u32 flow_hdr) 1838 { 1839 u64 val; 1840 u8 i; 1841 1842 for_each_set_bit(i, (unsigned long *)&hash_fields, 1843 ICE_FLOW_FIELD_IDX_MAX) 1844 ice_flow_set_fld(segs, (enum ice_flow_field)i, 1845 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, 1846 ICE_FLOW_FLD_OFF_INVAL, false); 1847 1848 ICE_FLOW_SET_HDRS(segs, flow_hdr); 1849 1850 if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS & 1851 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER) 1852 return -EINVAL; 1853 1854 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS); 1855 if (val && !is_power_of_2(val)) 1856 return -EIO; 1857 1858 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS); 1859 if (val && !is_power_of_2(val)) 1860 return -EIO; 1861 1862 return 0; 1863 } 1864 1865 /** 1866 * ice_rem_vsi_rss_list - remove VSI from RSS list 1867 * @hw: pointer to the hardware structure 1868 * @vsi_handle: software VSI handle 1869 * 1870 * Remove the VSI from all RSS configurations in the list. 1871 */ 1872 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle) 1873 { 1874 struct ice_rss_cfg *r, *tmp; 1875 1876 if (list_empty(&hw->rss_list_head)) 1877 return; 1878 1879 mutex_lock(&hw->rss_locks); 1880 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry) 1881 if (test_and_clear_bit(vsi_handle, r->vsis)) 1882 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) { 1883 list_del(&r->l_entry); 1884 devm_kfree(ice_hw_to_dev(hw), r); 1885 } 1886 mutex_unlock(&hw->rss_locks); 1887 } 1888 1889 /** 1890 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI 1891 * @hw: pointer to the hardware structure 1892 * @vsi_handle: software VSI handle 1893 * 1894 * This function will iterate through all flow profiles and disassociate 1895 * the VSI from that profile. If the flow profile has no VSIs it will 1896 * be removed. 1897 */ 1898 int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle) 1899 { 1900 const enum ice_block blk = ICE_BLK_RSS; 1901 struct ice_flow_prof *p, *t; 1902 int status = 0; 1903 1904 if (!ice_is_vsi_valid(hw, vsi_handle)) 1905 return -EINVAL; 1906 1907 if (list_empty(&hw->fl_profs[blk])) 1908 return 0; 1909 1910 mutex_lock(&hw->rss_locks); 1911 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry) 1912 if (test_bit(vsi_handle, p->vsis)) { 1913 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle); 1914 if (status) 1915 break; 1916 1917 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) { 1918 status = ice_flow_rem_prof(hw, blk, p->id); 1919 if (status) 1920 break; 1921 } 1922 } 1923 mutex_unlock(&hw->rss_locks); 1924 1925 return status; 1926 } 1927 1928 /** 1929 * ice_rem_rss_list - remove RSS configuration from list 1930 * @hw: pointer to the hardware structure 1931 * @vsi_handle: software VSI handle 1932 * @prof: pointer to flow profile 1933 * 1934 * Assumption: lock has already been acquired for RSS list 1935 */ 1936 static void 1937 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof) 1938 { 1939 struct ice_rss_cfg *r, *tmp; 1940 1941 /* Search for RSS hash fields associated to the VSI that match the 1942 * hash configurations associated to the flow profile. If found 1943 * remove from the RSS entry list of the VSI context and delete entry. 1944 */ 1945 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry) 1946 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match && 1947 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) { 1948 clear_bit(vsi_handle, r->vsis); 1949 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) { 1950 list_del(&r->l_entry); 1951 devm_kfree(ice_hw_to_dev(hw), r); 1952 } 1953 return; 1954 } 1955 } 1956 1957 /** 1958 * ice_add_rss_list - add RSS configuration to list 1959 * @hw: pointer to the hardware structure 1960 * @vsi_handle: software VSI handle 1961 * @prof: pointer to flow profile 1962 * 1963 * Assumption: lock has already been acquired for RSS list 1964 */ 1965 static int 1966 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof) 1967 { 1968 struct ice_rss_cfg *r, *rss_cfg; 1969 1970 list_for_each_entry(r, &hw->rss_list_head, l_entry) 1971 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match && 1972 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) { 1973 set_bit(vsi_handle, r->vsis); 1974 return 0; 1975 } 1976 1977 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg), 1978 GFP_KERNEL); 1979 if (!rss_cfg) 1980 return -ENOMEM; 1981 1982 rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match; 1983 rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs; 1984 set_bit(vsi_handle, rss_cfg->vsis); 1985 1986 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head); 1987 1988 return 0; 1989 } 1990 1991 #define ICE_FLOW_PROF_HASH_S 0 1992 #define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S) 1993 #define ICE_FLOW_PROF_HDR_S 32 1994 #define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S) 1995 #define ICE_FLOW_PROF_ENCAP_S 63 1996 #define ICE_FLOW_PROF_ENCAP_M (BIT_ULL(ICE_FLOW_PROF_ENCAP_S)) 1997 1998 #define ICE_RSS_OUTER_HEADERS 1 1999 #define ICE_RSS_INNER_HEADERS 2 2000 2001 /* Flow profile ID format: 2002 * [0:31] - Packet match fields 2003 * [32:62] - Protocol header 2004 * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled 2005 */ 2006 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \ 2007 ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \ 2008 (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \ 2009 ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0))) 2010 2011 /** 2012 * ice_add_rss_cfg_sync - add an RSS configuration 2013 * @hw: pointer to the hardware structure 2014 * @vsi_handle: software VSI handle 2015 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure 2016 * @addl_hdrs: protocol header fields 2017 * @segs_cnt: packet segment count 2018 * 2019 * Assumption: lock has already been acquired for RSS list 2020 */ 2021 static int 2022 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 2023 u32 addl_hdrs, u8 segs_cnt) 2024 { 2025 const enum ice_block blk = ICE_BLK_RSS; 2026 struct ice_flow_prof *prof = NULL; 2027 struct ice_flow_seg_info *segs; 2028 int status; 2029 2030 if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX) 2031 return -EINVAL; 2032 2033 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL); 2034 if (!segs) 2035 return -ENOMEM; 2036 2037 /* Construct the packet segment info from the hashed fields */ 2038 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds, 2039 addl_hdrs); 2040 if (status) 2041 goto exit; 2042 2043 /* Search for a flow profile that has matching headers, hash fields 2044 * and has the input VSI associated to it. If found, no further 2045 * operations required and exit. 2046 */ 2047 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2048 vsi_handle, 2049 ICE_FLOW_FIND_PROF_CHK_FLDS | 2050 ICE_FLOW_FIND_PROF_CHK_VSI); 2051 if (prof) 2052 goto exit; 2053 2054 /* Check if a flow profile exists with the same protocol headers and 2055 * associated with the input VSI. If so disassociate the VSI from 2056 * this profile. The VSI will be added to a new profile created with 2057 * the protocol header and new hash field configuration. 2058 */ 2059 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2060 vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI); 2061 if (prof) { 2062 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle); 2063 if (!status) 2064 ice_rem_rss_list(hw, vsi_handle, prof); 2065 else 2066 goto exit; 2067 2068 /* Remove profile if it has no VSIs associated */ 2069 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) { 2070 status = ice_flow_rem_prof(hw, blk, prof->id); 2071 if (status) 2072 goto exit; 2073 } 2074 } 2075 2076 /* Search for a profile that has same match fields only. If this 2077 * exists then associate the VSI to this profile. 2078 */ 2079 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2080 vsi_handle, 2081 ICE_FLOW_FIND_PROF_CHK_FLDS); 2082 if (prof) { 2083 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle); 2084 if (!status) 2085 status = ice_add_rss_list(hw, vsi_handle, prof); 2086 goto exit; 2087 } 2088 2089 /* Create a new flow profile with generated profile and packet 2090 * segment information. 2091 */ 2092 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX, 2093 ICE_FLOW_GEN_PROFID(hashed_flds, 2094 segs[segs_cnt - 1].hdrs, 2095 segs_cnt), 2096 segs, segs_cnt, &prof); 2097 if (status) 2098 goto exit; 2099 2100 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle); 2101 /* If association to a new flow profile failed then this profile can 2102 * be removed. 2103 */ 2104 if (status) { 2105 ice_flow_rem_prof(hw, blk, prof->id); 2106 goto exit; 2107 } 2108 2109 status = ice_add_rss_list(hw, vsi_handle, prof); 2110 2111 exit: 2112 kfree(segs); 2113 return status; 2114 } 2115 2116 /** 2117 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields 2118 * @hw: pointer to the hardware structure 2119 * @vsi_handle: software VSI handle 2120 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure 2121 * @addl_hdrs: protocol header fields 2122 * 2123 * This function will generate a flow profile based on fields associated with 2124 * the input fields to hash on, the flow type and use the VSI number to add 2125 * a flow entry to the profile. 2126 */ 2127 int 2128 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 2129 u32 addl_hdrs) 2130 { 2131 int status; 2132 2133 if (hashed_flds == ICE_HASH_INVALID || 2134 !ice_is_vsi_valid(hw, vsi_handle)) 2135 return -EINVAL; 2136 2137 mutex_lock(&hw->rss_locks); 2138 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs, 2139 ICE_RSS_OUTER_HEADERS); 2140 if (!status) 2141 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, 2142 addl_hdrs, ICE_RSS_INNER_HEADERS); 2143 mutex_unlock(&hw->rss_locks); 2144 2145 return status; 2146 } 2147 2148 /** 2149 * ice_rem_rss_cfg_sync - remove an existing RSS configuration 2150 * @hw: pointer to the hardware structure 2151 * @vsi_handle: software VSI handle 2152 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove 2153 * @addl_hdrs: Protocol header fields within a packet segment 2154 * @segs_cnt: packet segment count 2155 * 2156 * Assumption: lock has already been acquired for RSS list 2157 */ 2158 static int 2159 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 2160 u32 addl_hdrs, u8 segs_cnt) 2161 { 2162 const enum ice_block blk = ICE_BLK_RSS; 2163 struct ice_flow_seg_info *segs; 2164 struct ice_flow_prof *prof; 2165 int status; 2166 2167 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL); 2168 if (!segs) 2169 return -ENOMEM; 2170 2171 /* Construct the packet segment info from the hashed fields */ 2172 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds, 2173 addl_hdrs); 2174 if (status) 2175 goto out; 2176 2177 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2178 vsi_handle, 2179 ICE_FLOW_FIND_PROF_CHK_FLDS); 2180 if (!prof) { 2181 status = -ENOENT; 2182 goto out; 2183 } 2184 2185 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle); 2186 if (status) 2187 goto out; 2188 2189 /* Remove RSS configuration from VSI context before deleting 2190 * the flow profile. 2191 */ 2192 ice_rem_rss_list(hw, vsi_handle, prof); 2193 2194 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) 2195 status = ice_flow_rem_prof(hw, blk, prof->id); 2196 2197 out: 2198 kfree(segs); 2199 return status; 2200 } 2201 2202 /** 2203 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields 2204 * @hw: pointer to the hardware structure 2205 * @vsi_handle: software VSI handle 2206 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove 2207 * @addl_hdrs: Protocol header fields within a packet segment 2208 * 2209 * This function will lookup the flow profile based on the input 2210 * hash field bitmap, iterate through the profile entry list of 2211 * that profile and find entry associated with input VSI to be 2212 * removed. Calls are made to underlying flow s which will APIs 2213 * turn build or update buffers for RSS XLT1 section. 2214 */ 2215 int __maybe_unused 2216 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 2217 u32 addl_hdrs) 2218 { 2219 int status; 2220 2221 if (hashed_flds == ICE_HASH_INVALID || 2222 !ice_is_vsi_valid(hw, vsi_handle)) 2223 return -EINVAL; 2224 2225 mutex_lock(&hw->rss_locks); 2226 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs, 2227 ICE_RSS_OUTER_HEADERS); 2228 if (!status) 2229 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, 2230 addl_hdrs, ICE_RSS_INNER_HEADERS); 2231 mutex_unlock(&hw->rss_locks); 2232 2233 return status; 2234 } 2235 2236 /* Mapping of AVF hash bit fields to an L3-L4 hash combination. 2237 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash, 2238 * convert its values to their appropriate flow L3, L4 values. 2239 */ 2240 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \ 2241 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \ 2242 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4)) 2243 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \ 2244 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \ 2245 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP)) 2246 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \ 2247 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \ 2248 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \ 2249 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP)) 2250 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \ 2251 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \ 2252 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) 2253 2254 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \ 2255 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \ 2256 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6)) 2257 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \ 2258 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \ 2259 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \ 2260 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP)) 2261 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \ 2262 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \ 2263 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP)) 2264 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \ 2265 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \ 2266 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) 2267 2268 /** 2269 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver 2270 * @hw: pointer to the hardware structure 2271 * @vsi_handle: software VSI handle 2272 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure 2273 * 2274 * This function will take the hash bitmap provided by the AVF driver via a 2275 * message, convert it to ICE-compatible values, and configure RSS flow 2276 * profiles. 2277 */ 2278 int ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash) 2279 { 2280 int status = 0; 2281 u64 hash_flds; 2282 2283 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID || 2284 !ice_is_vsi_valid(hw, vsi_handle)) 2285 return -EINVAL; 2286 2287 /* Make sure no unsupported bits are specified */ 2288 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS | 2289 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)) 2290 return -EIO; 2291 2292 hash_flds = avf_hash; 2293 2294 /* Always create an L3 RSS configuration for any L4 RSS configuration */ 2295 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) 2296 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS; 2297 2298 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) 2299 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS; 2300 2301 /* Create the corresponding RSS configuration for each valid hash bit */ 2302 while (hash_flds) { 2303 u64 rss_hash = ICE_HASH_INVALID; 2304 2305 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) { 2306 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) { 2307 rss_hash = ICE_FLOW_HASH_IPV4; 2308 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS; 2309 } else if (hash_flds & 2310 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) { 2311 rss_hash = ICE_FLOW_HASH_IPV4 | 2312 ICE_FLOW_HASH_TCP_PORT; 2313 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS; 2314 } else if (hash_flds & 2315 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) { 2316 rss_hash = ICE_FLOW_HASH_IPV4 | 2317 ICE_FLOW_HASH_UDP_PORT; 2318 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS; 2319 } else if (hash_flds & 2320 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) { 2321 rss_hash = ICE_FLOW_HASH_IPV4 | 2322 ICE_FLOW_HASH_SCTP_PORT; 2323 hash_flds &= 2324 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP); 2325 } 2326 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) { 2327 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) { 2328 rss_hash = ICE_FLOW_HASH_IPV6; 2329 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS; 2330 } else if (hash_flds & 2331 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) { 2332 rss_hash = ICE_FLOW_HASH_IPV6 | 2333 ICE_FLOW_HASH_TCP_PORT; 2334 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS; 2335 } else if (hash_flds & 2336 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) { 2337 rss_hash = ICE_FLOW_HASH_IPV6 | 2338 ICE_FLOW_HASH_UDP_PORT; 2339 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS; 2340 } else if (hash_flds & 2341 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) { 2342 rss_hash = ICE_FLOW_HASH_IPV6 | 2343 ICE_FLOW_HASH_SCTP_PORT; 2344 hash_flds &= 2345 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP); 2346 } 2347 } 2348 2349 if (rss_hash == ICE_HASH_INVALID) 2350 return -EIO; 2351 2352 status = ice_add_rss_cfg(hw, vsi_handle, rss_hash, 2353 ICE_FLOW_SEG_HDR_NONE); 2354 if (status) 2355 break; 2356 } 2357 2358 return status; 2359 } 2360 2361 /** 2362 * ice_replay_rss_cfg - replay RSS configurations associated with VSI 2363 * @hw: pointer to the hardware structure 2364 * @vsi_handle: software VSI handle 2365 */ 2366 int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle) 2367 { 2368 struct ice_rss_cfg *r; 2369 int status = 0; 2370 2371 if (!ice_is_vsi_valid(hw, vsi_handle)) 2372 return -EINVAL; 2373 2374 mutex_lock(&hw->rss_locks); 2375 list_for_each_entry(r, &hw->rss_list_head, l_entry) { 2376 if (test_bit(vsi_handle, r->vsis)) { 2377 status = ice_add_rss_cfg_sync(hw, vsi_handle, 2378 r->hashed_flds, 2379 r->packet_hdr, 2380 ICE_RSS_OUTER_HEADERS); 2381 if (status) 2382 break; 2383 status = ice_add_rss_cfg_sync(hw, vsi_handle, 2384 r->hashed_flds, 2385 r->packet_hdr, 2386 ICE_RSS_INNER_HEADERS); 2387 if (status) 2388 break; 2389 } 2390 } 2391 mutex_unlock(&hw->rss_locks); 2392 2393 return status; 2394 } 2395 2396 /** 2397 * ice_get_rss_cfg - returns hashed fields for the given header types 2398 * @hw: pointer to the hardware structure 2399 * @vsi_handle: software VSI handle 2400 * @hdrs: protocol header type 2401 * 2402 * This function will return the match fields of the first instance of flow 2403 * profile having the given header types and containing input VSI 2404 */ 2405 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs) 2406 { 2407 u64 rss_hash = ICE_HASH_INVALID; 2408 struct ice_rss_cfg *r; 2409 2410 /* verify if the protocol header is non zero and VSI is valid */ 2411 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle)) 2412 return ICE_HASH_INVALID; 2413 2414 mutex_lock(&hw->rss_locks); 2415 list_for_each_entry(r, &hw->rss_list_head, l_entry) 2416 if (test_bit(vsi_handle, r->vsis) && 2417 r->packet_hdr == hdrs) { 2418 rss_hash = r->hashed_flds; 2419 break; 2420 } 2421 mutex_unlock(&hw->rss_locks); 2422 2423 return rss_hash; 2424 } 2425