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 #include <net/gre.h> 7 8 /* Size of known protocol header fields */ 9 #define ICE_FLOW_FLD_SZ_ETH_TYPE 2 10 #define ICE_FLOW_FLD_SZ_VLAN 2 11 #define ICE_FLOW_FLD_SZ_IPV4_ADDR 4 12 #define ICE_FLOW_FLD_SZ_IPV6_ADDR 16 13 #define ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR 4 14 #define ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR 6 15 #define ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR 8 16 #define ICE_FLOW_FLD_SZ_IPV4_ID 2 17 #define ICE_FLOW_FLD_SZ_IPV6_ID 4 18 #define ICE_FLOW_FLD_SZ_IP_CHKSUM 2 19 #define ICE_FLOW_FLD_SZ_TCP_CHKSUM 2 20 #define ICE_FLOW_FLD_SZ_UDP_CHKSUM 2 21 #define ICE_FLOW_FLD_SZ_SCTP_CHKSUM 4 22 #define ICE_FLOW_FLD_SZ_IP_DSCP 1 23 #define ICE_FLOW_FLD_SZ_IP_TTL 1 24 #define ICE_FLOW_FLD_SZ_IP_PROT 1 25 #define ICE_FLOW_FLD_SZ_PORT 2 26 #define ICE_FLOW_FLD_SZ_TCP_FLAGS 1 27 #define ICE_FLOW_FLD_SZ_ICMP_TYPE 1 28 #define ICE_FLOW_FLD_SZ_ICMP_CODE 1 29 #define ICE_FLOW_FLD_SZ_ARP_OPER 2 30 #define ICE_FLOW_FLD_SZ_GRE_KEYID 4 31 #define ICE_FLOW_FLD_SZ_GTP_TEID 4 32 #define ICE_FLOW_FLD_SZ_GTP_QFI 2 33 #define ICE_FLOW_FLD_SZ_PFCP_SEID 8 34 #define ICE_FLOW_FLD_SZ_ESP_SPI 4 35 #define ICE_FLOW_FLD_SZ_AH_SPI 4 36 #define ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI 4 37 #define ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID 2 38 #define ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID 2 39 40 /* Describe properties of a protocol header field */ 41 struct ice_flow_field_info { 42 enum ice_flow_seg_hdr hdr; 43 s16 off; /* Offset from start of a protocol header, in bits */ 44 u16 size; /* Size of fields in bits */ 45 u16 mask; /* 16-bit mask for field */ 46 }; 47 48 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \ 49 .hdr = _hdr, \ 50 .off = (_offset_bytes) * BITS_PER_BYTE, \ 51 .size = (_size_bytes) * BITS_PER_BYTE, \ 52 .mask = 0, \ 53 } 54 55 /* QFI: 6-bit field in GTP-U PDU Session Container (3GPP TS 38.415) */ 56 #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \ 57 .hdr = _hdr, \ 58 .off = (_offset_bytes) * BITS_PER_BYTE, \ 59 .size = (_size_bytes) * BITS_PER_BYTE, \ 60 .mask = _mask, \ 61 } 62 63 /* Table containing properties of supported protocol header fields */ 64 static const 65 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = { 66 /* Ether */ 67 /* ICE_FLOW_FIELD_IDX_ETH_DA */ 68 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN), 69 /* ICE_FLOW_FIELD_IDX_ETH_SA */ 70 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN), 71 /* ICE_FLOW_FIELD_IDX_S_VLAN */ 72 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, sizeof(__be16)), 73 /* ICE_FLOW_FIELD_IDX_C_VLAN */ 74 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, sizeof(__be16)), 75 /* ICE_FLOW_FIELD_IDX_ETH_TYPE */ 76 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, sizeof(__be16)), 77 /* IPv4 / IPv6 */ 78 /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */ 79 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, 1, 0x00fc), 80 /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */ 81 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, 1, 0x0ff0), 82 /* ICE_FLOW_FIELD_IDX_IPV4_TTL */ 83 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0xff00), 84 /* ICE_FLOW_FIELD_IDX_IPV4_PROT */ 85 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0x00ff), 86 /* ICE_FLOW_FIELD_IDX_IPV6_TTL */ 87 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0x00ff), 88 /* ICE_FLOW_FIELD_IDX_IPV6_PROT */ 89 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0xff00), 90 /* ICE_FLOW_FIELD_IDX_IPV4_SA */ 91 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)), 92 /* ICE_FLOW_FIELD_IDX_IPV4_DA */ 93 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)), 94 /* ICE_FLOW_FIELD_IDX_IPV6_SA */ 95 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)), 96 /* ICE_FLOW_FIELD_IDX_IPV6_DA */ 97 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR), 98 /* ICE_FLOW_FIELD_IDX_IPV4_CHKSUM */ 99 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 10, ICE_FLOW_FLD_SZ_IP_CHKSUM), 100 /* ICE_FLOW_FIELD_IDX_IPV4_FRAG */ 101 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4, 102 ICE_FLOW_FLD_SZ_IPV4_ID), 103 /* ICE_FLOW_FIELD_IDX_IPV6_FRAG */ 104 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4, 105 ICE_FLOW_FLD_SZ_IPV6_ID), 106 /* ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA */ 107 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, 108 ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR), 109 /* ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA */ 110 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, 111 ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR), 112 /* ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA */ 113 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, 114 ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR), 115 /* ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA */ 116 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, 117 ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR), 118 /* ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA */ 119 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, 120 ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR), 121 /* ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA */ 122 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, 123 ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR), 124 /* Transport */ 125 /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */ 126 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)), 127 /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */ 128 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)), 129 /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */ 130 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)), 131 /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */ 132 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)), 133 /* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */ 134 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, sizeof(__be16)), 135 /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */ 136 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)), 137 /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */ 138 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, ICE_FLOW_FLD_SZ_TCP_FLAGS), 139 /* ICE_FLOW_FIELD_IDX_TCP_CHKSUM */ 140 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 16, ICE_FLOW_FLD_SZ_TCP_CHKSUM), 141 /* ICE_FLOW_FIELD_IDX_UDP_CHKSUM */ 142 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 6, ICE_FLOW_FLD_SZ_UDP_CHKSUM), 143 /* ICE_FLOW_FIELD_IDX_SCTP_CHKSUM */ 144 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 8, 145 ICE_FLOW_FLD_SZ_SCTP_CHKSUM), 146 /* ARP */ 147 /* ICE_FLOW_FIELD_IDX_ARP_SIP */ 148 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)), 149 /* ICE_FLOW_FIELD_IDX_ARP_DIP */ 150 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, sizeof(struct in_addr)), 151 /* ICE_FLOW_FIELD_IDX_ARP_SHA */ 152 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN), 153 /* ICE_FLOW_FIELD_IDX_ARP_DHA */ 154 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN), 155 /* ICE_FLOW_FIELD_IDX_ARP_OP */ 156 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, sizeof(__be16)), 157 /* ICMP */ 158 /* ICE_FLOW_FIELD_IDX_ICMP_TYPE */ 159 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, 1), 160 /* ICE_FLOW_FIELD_IDX_ICMP_CODE */ 161 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, 1), 162 /* GRE */ 163 /* ICE_FLOW_FIELD_IDX_GRE_KEYID */ 164 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12, 165 sizeof_field(struct gre_full_hdr, key)), 166 /* GTP */ 167 /* ICE_FLOW_FIELD_IDX_GTPC_TEID */ 168 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12, sizeof(__be32)), 169 /* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */ 170 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12, sizeof(__be32)), 171 /* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */ 172 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12, sizeof(__be32)), 173 /* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */ 174 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16), 175 0x3f00), 176 /* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */ 177 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, 178 ICE_FLOW_FLD_SZ_GTP_TEID), 179 /* ICE_FLOW_FIELD_IDX_GTPU_UP_QFI */ 180 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_UP, 22, 181 ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00), 182 /* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */ 183 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, 184 ICE_FLOW_FLD_SZ_GTP_TEID), 185 /* ICE_FLOW_FIELD_IDX_GTPU_DWN_QFI */ 186 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_DWN, 22, 187 ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00), 188 /* PPPoE */ 189 /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */ 190 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)), 191 /* PFCP */ 192 /* ICE_FLOW_FIELD_IDX_PFCP_SEID */ 193 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)), 194 /* L2TPv3 */ 195 /* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */ 196 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)), 197 /* ESP */ 198 /* ICE_FLOW_FIELD_IDX_ESP_SPI */ 199 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)), 200 /* AH */ 201 /* ICE_FLOW_FIELD_IDX_AH_SPI */ 202 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)), 203 /* NAT_T_ESP */ 204 /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */ 205 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, 206 ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI), 207 /* L2TPV2 */ 208 /* ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID */ 209 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 12, 210 ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID), 211 /* L2TPV2_LEN */ 212 /* ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID */ 213 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 14, 214 ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID), 215 }; 216 217 /* Bitmaps indicating relevant packet types for a particular protocol header 218 * 219 * Packet types for packets with an Outer/First/Single MAC header 220 */ 221 static const u32 ice_ptypes_mac_ofos[] = { 222 0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB, 223 0x0000077E, 0x000003FF, 0x00000000, 0x00000000, 224 0x00400000, 0x03FFF000, 0xFFFFFFE0, 0x00000707, 225 0xFFFFF000, 0x000003FF, 0x00000000, 0x00000000, 226 0x00000000, 0x00000000, 0x00000000, 0x00000000, 227 0x00000000, 0x00000000, 0x00000000, 0x00000000, 228 0x00000000, 0x00000000, 0x00000000, 0x00000000, 229 0x00000000, 0x00000000, 0x00000000, 0x00000000, 230 }; 231 232 /* Packet types for packets with an Innermost/Last MAC VLAN header */ 233 static const u32 ice_ptypes_macvlan_il[] = { 234 0x00000000, 0xBC000000, 0x000001DF, 0xF0000000, 235 0x0000077E, 0x00000000, 0x00000000, 0x00000000, 236 0x00000000, 0x00000000, 0x00000000, 0x00000000, 237 0x00000000, 0x00000000, 0x00000000, 0x00000000, 238 0x00000000, 0x00000000, 0x00000000, 0x00000000, 239 0x00000000, 0x00000000, 0x00000000, 0x00000000, 240 0x00000000, 0x00000000, 0x00000000, 0x00000000, 241 0x00000000, 0x00000000, 0x00000000, 0x00000000, 242 }; 243 244 /* Packet types for packets with an Outer/First/Single IPv4 header, does NOT 245 * include IPv4 other PTYPEs 246 */ 247 static const u32 ice_ptypes_ipv4_ofos[] = { 248 0x1D800000, 0xBFBF7800, 0x000001DF, 0x00000000, 249 0x00000000, 0x00000155, 0x00000000, 0x00000000, 250 0x00000000, 0x000FC000, 0x000002A0, 0x00000000, 251 0x00015000, 0x00000000, 0x00000000, 0x00000000, 252 0x00000000, 0x00000000, 0x00000000, 0x00000000, 253 0x00000000, 0x00000000, 0x00000000, 0x00000000, 254 0x00000000, 0x00000000, 0x00000000, 0x00000000, 255 0x00000000, 0x00000000, 0x00000000, 0x00000000, 256 }; 257 258 /* Packet types for packets with an Outer/First/Single IPv4 header, includes 259 * IPv4 other PTYPEs 260 */ 261 static const u32 ice_ptypes_ipv4_ofos_all[] = { 262 0x1D800000, 0x27BF7800, 0x00000000, 0x00000000, 263 0x00000000, 0x00000155, 0x00000000, 0x00000000, 264 0x00000000, 0x000FC000, 0x83E0FAA0, 0x00000101, 265 0x3FFD5000, 0x00000000, 0x02FBEFBC, 0x00000000, 266 0x00000000, 0x00000000, 0x00000000, 0x00000000, 267 0x00000000, 0x00000000, 0x00000000, 0x00000000, 268 0x00000000, 0x00000000, 0x00000000, 0x00000000, 269 0x00000000, 0x00000000, 0x00000000, 0x00000000, 270 }; 271 272 /* Packet types for packets with an Innermost/Last IPv4 header */ 273 static const u32 ice_ptypes_ipv4_il[] = { 274 0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B, 275 0x0000000E, 0x00000000, 0x00000000, 0x00000000, 276 0x00000000, 0x00000000, 0x001FF800, 0x00000000, 277 0xC0FC0000, 0x0000000F, 0xBC0BC0BC, 0x00000BC0, 278 0x00000000, 0x00000000, 0x00000000, 0x00000000, 279 0x00000000, 0x00000000, 0x00000000, 0x00000000, 280 0x00000000, 0x00000000, 0x00000000, 0x00000000, 281 0x00000000, 0x00000000, 0x00000000, 0x00000000, 282 }; 283 284 /* Packet types for packets with an Outer/First/Single IPv6 header, does NOT 285 * include IPv6 other PTYPEs 286 */ 287 static const u32 ice_ptypes_ipv6_ofos[] = { 288 0x00000000, 0x00000000, 0x76000000, 0x10002000, 289 0x00000000, 0x000002AA, 0x00000000, 0x00000000, 290 0x00000000, 0x03F00000, 0x00000540, 0x00000000, 291 0x0002A000, 0x00000000, 0x00000000, 0x00000000, 292 0x00000000, 0x00000000, 0x00000000, 0x00000000, 293 0x00000000, 0x00000000, 0x00000000, 0x00000000, 294 0x00000000, 0x00000000, 0x00000000, 0x00000000, 295 0x00000000, 0x00000000, 0x00000000, 0x00000000, 296 }; 297 298 /* Packet types for packets with an Outer/First/Single IPv6 header, includes 299 * IPv6 other PTYPEs 300 */ 301 static const u32 ice_ptypes_ipv6_ofos_all[] = { 302 0x00000000, 0x00000000, 0x76000000, 0xFEFDE000, 303 0x0000077E, 0x000002AA, 0x00000000, 0x00000000, 304 0x00000000, 0x03F00000, 0x7C1F0540, 0x00000206, 305 0xC002A000, 0x000003FF, 0xBC000000, 0x0002FBEF, 306 0x00000000, 0x00000000, 0x00000000, 0x00000000, 307 0x00000000, 0x00000000, 0x00000000, 0x00000000, 308 0x00000000, 0x00000000, 0x00000000, 0x00000000, 309 0x00000000, 0x00000000, 0x00000000, 0x00000000, 310 }; 311 312 /* Packet types for packets with an Innermost/Last IPv6 header */ 313 static const u32 ice_ptypes_ipv6_il[] = { 314 0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000, 315 0x00000770, 0x00000000, 0x00000000, 0x00000000, 316 0x00000000, 0x00000000, 0x7FE00000, 0x00000000, 317 0x3F000000, 0x000003F0, 0x02F02F00, 0x0002F02F, 318 0x00000000, 0x00000000, 0x00000000, 0x00000000, 319 0x00000000, 0x00000000, 0x00000000, 0x00000000, 320 0x00000000, 0x00000000, 0x00000000, 0x00000000, 321 0x00000000, 0x00000000, 0x00000000, 0x00000000, 322 }; 323 324 /* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */ 325 static const u32 ice_ptypes_ipv4_ofos_no_l4[] = { 326 0x10C00000, 0x04000800, 0x00000000, 0x00000000, 327 0x00000000, 0x00000000, 0x00000000, 0x00000000, 328 0x00000000, 0x00000000, 0x00000000, 0x00000000, 329 0x00000000, 0x00000000, 0x00000000, 0x00000000, 330 0x00000000, 0x00000000, 0x00000000, 0x00000000, 331 0x00000000, 0x00000000, 0x00000000, 0x00000000, 332 0x00000000, 0x00000000, 0x00000000, 0x00000000, 333 0x00000000, 0x00000000, 0x00000000, 0x00000000, 334 }; 335 336 /* Packet types for packets with an Outermost/First ARP header */ 337 static const u32 ice_ptypes_arp_of[] = { 338 0x00000800, 0x00000000, 0x00000000, 0x00000000, 339 0x00000000, 0x00000000, 0x00000000, 0x00000000, 340 0x00000000, 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 }; 347 348 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */ 349 static const u32 ice_ptypes_ipv4_il_no_l4[] = { 350 0x60000000, 0x18043008, 0x80000002, 0x6010c021, 351 0x00000008, 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 }; 359 360 /* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */ 361 static const u32 ice_ptypes_ipv6_ofos_no_l4[] = { 362 0x00000000, 0x00000000, 0x43000000, 0x10002000, 363 0x00000000, 0x00000000, 0x00000000, 0x00000000, 364 0x00000000, 0x00000000, 0x00000000, 0x00000000, 365 0x00000000, 0x00000000, 0x00000000, 0x00000000, 366 0x00000000, 0x00000000, 0x00000000, 0x00000000, 367 0x00000000, 0x00000000, 0x00000000, 0x00000000, 368 0x00000000, 0x00000000, 0x00000000, 0x00000000, 369 0x00000000, 0x00000000, 0x00000000, 0x00000000, 370 }; 371 372 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */ 373 static const u32 ice_ptypes_ipv6_il_no_l4[] = { 374 0x00000000, 0x02180430, 0x0000010c, 0x086010c0, 375 0x00000430, 0x00000000, 0x00000000, 0x00000000, 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 }; 383 384 /* UDP Packet types for non-tunneled packets or tunneled 385 * packets with inner UDP. 386 */ 387 static const u32 ice_ptypes_udp_il[] = { 388 0x81000000, 0x20204040, 0x04000010, 0x80810102, 389 0x00000040, 0x00000000, 0x00000000, 0x00000000, 390 0x00000000, 0x00410000, 0x908427E0, 0x00000007, 391 0x0413F000, 0x00000041, 0x10410410, 0x00004104, 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 packets with an Innermost/Last TCP header */ 399 static const u32 ice_ptypes_tcp_il[] = { 400 0x04000000, 0x80810102, 0x10000040, 0x02040408, 401 0x00000102, 0x00000000, 0x00000000, 0x00000000, 402 0x00000000, 0x00820000, 0x21084000, 0x00000000, 403 0x08200000, 0x00000082, 0x20820820, 0x00008208, 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 packets with an Innermost/Last SCTP header */ 411 static const u32 ice_ptypes_sctp_il[] = { 412 0x08000000, 0x01020204, 0x20000081, 0x04080810, 413 0x00000204, 0x00000000, 0x00000000, 0x00000000, 414 0x00000000, 0x01040000, 0x00000000, 0x00000000, 415 0x10400000, 0x00000104, 0x00000000, 0x00000000, 416 0x00000000, 0x00000000, 0x00000000, 0x00000000, 417 0x00000000, 0x00000000, 0x00000000, 0x00000000, 418 0x00000000, 0x00000000, 0x00000000, 0x00000000, 419 0x00000000, 0x00000000, 0x00000000, 0x00000000, 420 }; 421 422 /* Packet types for packets with an Outermost/First ICMP header */ 423 static const u32 ice_ptypes_icmp_of[] = { 424 0x10000000, 0x00000000, 0x00000000, 0x00000000, 425 0x00000000, 0x00000000, 0x00000000, 0x00000000, 426 0x00000000, 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 }; 433 434 /* Packet types for packets with an Innermost/Last ICMP header */ 435 static const u32 ice_ptypes_icmp_il[] = { 436 0x00000000, 0x02040408, 0x40000102, 0x08101020, 437 0x00000408, 0x00000000, 0x00000000, 0x00000000, 438 0x00000000, 0x00000000, 0x42108000, 0x00000000, 439 0x20800000, 0x00000208, 0x00000000, 0x00000000, 440 0x00000000, 0x00000000, 0x00000000, 0x00000000, 441 0x00000000, 0x00000000, 0x00000000, 0x00000000, 442 0x00000000, 0x00000000, 0x00000000, 0x00000000, 443 0x00000000, 0x00000000, 0x00000000, 0x00000000, 444 }; 445 446 /* Packet types for packets with an Outermost/First GRE header */ 447 static const u32 ice_ptypes_gre_of[] = { 448 0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000, 449 0x0000017E, 0x00000000, 0x00000000, 0x00000000, 450 0x00000000, 0x00000000, 0x00000000, 0x00000000, 451 0x00000000, 0x00000000, 0xBEFBEFBC, 0x0002FBEF, 452 0x00000000, 0x00000000, 0x00000000, 0x00000000, 453 0x00000000, 0x00000000, 0x00000000, 0x00000000, 454 0x00000000, 0x00000000, 0x00000000, 0x00000000, 455 0x00000000, 0x00000000, 0x00000000, 0x00000000, 456 }; 457 458 /* Packet types for packets with an Innermost/Last MAC header */ 459 static const u32 ice_ptypes_mac_il[] = { 460 0x00000000, 0x20000000, 0x00000000, 0x00000000, 461 0x00000000, 0x00000000, 0x00000000, 0x00000000, 462 0x00000000, 0x00000000, 0x00000000, 0x00000000, 463 0x00000000, 0x00000000, 0x00000000, 0x00000000, 464 0x00000000, 0x00000000, 0x00000000, 0x00000000, 465 0x00000000, 0x00000000, 0x00000000, 0x00000000, 466 0x00000000, 0x00000000, 0x00000000, 0x00000000, 467 0x00000000, 0x00000000, 0x00000000, 0x00000000, 468 }; 469 470 /* Packet types for GTPC */ 471 static const u32 ice_ptypes_gtpc[] = { 472 0x00000000, 0x00000000, 0x00000000, 0x00000000, 473 0x00000000, 0x00000000, 0x00000000, 0x00000000, 474 0x00000000, 0x00000000, 0x000001E0, 0x00000000, 475 0x00000000, 0x00000000, 0x00000000, 0x00000000, 476 0x00000000, 0x00000000, 0x00000000, 0x00000000, 477 0x00000000, 0x00000000, 0x00000000, 0x00000000, 478 0x00000000, 0x00000000, 0x00000000, 0x00000000, 479 0x00000000, 0x00000000, 0x00000000, 0x00000000, 480 }; 481 482 /* Packet types for GTPC with TEID */ 483 static const u32 ice_ptypes_gtpc_tid[] = { 484 0x00000000, 0x00000000, 0x00000000, 0x00000000, 485 0x00000000, 0x00000000, 0x00000000, 0x00000000, 486 0x00000000, 0x00000000, 0x00000060, 0x00000000, 487 0x00000000, 0x00000000, 0x00000000, 0x00000000, 488 0x00000000, 0x00000000, 0x00000000, 0x00000000, 489 0x00000000, 0x00000000, 0x00000000, 0x00000000, 490 0x00000000, 0x00000000, 0x00000000, 0x00000000, 491 0x00000000, 0x00000000, 0x00000000, 0x00000000, 492 }; 493 494 /* Packet types for GTPU */ 495 static const struct ice_ptype_attributes ice_attr_gtpu_session[] = { 496 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_SESSION }, 497 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, 498 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, 499 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_SESSION }, 500 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_SESSION }, 501 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_SESSION }, 502 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, 503 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, 504 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_SESSION }, 505 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_SESSION }, 506 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_SESSION }, 507 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, 508 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, 509 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_SESSION }, 510 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_SESSION }, 511 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_SESSION }, 512 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, 513 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, 514 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_SESSION }, 515 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_SESSION }, 516 }; 517 518 static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = { 519 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, 520 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 521 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 522 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 523 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 524 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, 525 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 526 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 527 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 528 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 529 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, 530 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 531 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 532 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 533 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH }, 534 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, 535 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 536 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, 537 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH }, 538 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH }, 539 }; 540 541 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = { 542 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 543 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 544 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 545 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 546 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 547 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 548 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 549 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 550 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 551 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 552 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 553 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 554 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 555 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 556 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 557 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 558 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 559 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 560 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 561 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK }, 562 }; 563 564 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = { 565 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK }, 566 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 567 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 568 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK }, 569 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK }, 570 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK }, 571 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 572 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 573 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK }, 574 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK }, 575 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK }, 576 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 577 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 578 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK }, 579 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK }, 580 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK }, 581 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 582 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK }, 583 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK }, 584 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK }, 585 }; 586 587 static const u32 ice_ptypes_gtpu[] = { 588 0x00000000, 0x00000000, 0x00000000, 0x00000000, 589 0x00000000, 0x00000000, 0x00000000, 0x00000000, 590 0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000, 591 0x00000000, 0x00000000, 0x00000000, 0x00000000, 592 0x00000000, 0x00000000, 0x00000000, 0x00000000, 593 0x00000000, 0x00000000, 0x00000000, 0x00000000, 594 0x00000000, 0x00000000, 0x00000000, 0x00000000, 595 0x00000000, 0x00000000, 0x00000000, 0x00000000, 596 }; 597 598 /* Packet types for PPPoE */ 599 static const u32 ice_ptypes_pppoe[] = { 600 0x00000000, 0x00000000, 0x00000000, 0x00000000, 601 0x00000000, 0x00000000, 0x00000000, 0x00000000, 602 0x00000000, 0x03ffe000, 0x00000000, 0x00000000, 603 0x00000000, 0x00000000, 0x00000000, 0x00000000, 604 0x00000000, 0x00000000, 0x00000000, 0x00000000, 605 0x00000000, 0x00000000, 0x00000000, 0x00000000, 606 0x00000000, 0x00000000, 0x00000000, 0x00000000, 607 0x00000000, 0x00000000, 0x00000000, 0x00000000, 608 }; 609 610 /* Packet types for packets with PFCP NODE header */ 611 static const u32 ice_ptypes_pfcp_node[] = { 612 0x00000000, 0x00000000, 0x00000000, 0x00000000, 613 0x00000000, 0x00000000, 0x00000000, 0x00000000, 614 0x00000000, 0x00000000, 0x80000000, 0x00000002, 615 0x00000000, 0x00000000, 0x00000000, 0x00000000, 616 0x00000000, 0x00000000, 0x00000000, 0x00000000, 617 0x00000000, 0x00000000, 0x00000000, 0x00000000, 618 0x00000000, 0x00000000, 0x00000000, 0x00000000, 619 0x00000000, 0x00000000, 0x00000000, 0x00000000, 620 }; 621 622 /* Packet types for packets with PFCP SESSION header */ 623 static const u32 ice_ptypes_pfcp_session[] = { 624 0x00000000, 0x00000000, 0x00000000, 0x00000000, 625 0x00000000, 0x00000000, 0x00000000, 0x00000000, 626 0x00000000, 0x00000000, 0x00000000, 0x00000005, 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 }; 633 634 /* Packet types for L2TPv3 */ 635 static const u32 ice_ptypes_l2tpv3[] = { 636 0x00000000, 0x00000000, 0x00000000, 0x00000000, 637 0x00000000, 0x00000000, 0x00000000, 0x00000000, 638 0x00000000, 0x00000000, 0x00000000, 0x00000300, 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 }; 645 646 /* Packet types for ESP */ 647 static const u32 ice_ptypes_esp[] = { 648 0x00000000, 0x00000000, 0x00000000, 0x00000000, 649 0x00000000, 0x00000003, 0x00000000, 0x00000000, 650 0x00000000, 0x00000000, 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 }; 657 658 /* Packet types for AH */ 659 static const u32 ice_ptypes_ah[] = { 660 0x00000000, 0x00000000, 0x00000000, 0x00000000, 661 0x00000000, 0x0000000C, 0x00000000, 0x00000000, 662 0x00000000, 0x00000000, 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 /* Packet types for packets with NAT_T ESP header */ 671 static const u32 ice_ptypes_nat_t_esp[] = { 672 0x00000000, 0x00000000, 0x00000000, 0x00000000, 673 0x00000000, 0x00000030, 0x00000000, 0x00000000, 674 0x00000000, 0x00000000, 0x00000000, 0x00000000, 675 0x00000000, 0x00000000, 0x00000000, 0x00000000, 676 0x00000000, 0x00000000, 0x00000000, 0x00000000, 677 0x00000000, 0x00000000, 0x00000000, 0x00000000, 678 0x00000000, 0x00000000, 0x00000000, 0x00000000, 679 0x00000000, 0x00000000, 0x00000000, 0x00000000, 680 }; 681 682 static const u32 ice_ptypes_mac_non_ip_ofos[] = { 683 0x00000846, 0x00000000, 0x00000000, 0x00000000, 684 0x00000000, 0x00000000, 0x00000000, 0x00000000, 685 0x00400000, 0x03FFF000, 0x00000000, 0x00000000, 686 0x00000000, 0x00000000, 0x00000000, 0x00000000, 687 0x00000000, 0x00000000, 0x00000000, 0x00000000, 688 0x00000000, 0x00000000, 0x00000000, 0x00000000, 689 0x00000000, 0x00000000, 0x00000000, 0x00000000, 690 0x00000000, 0x00000000, 0x00000000, 0x00000000, 691 }; 692 693 /* Manage parameters and info. used during the creation of a flow profile */ 694 struct ice_flow_prof_params { 695 enum ice_block blk; 696 u16 entry_length; /* # of bytes formatted entry will require */ 697 u8 es_cnt; 698 struct ice_flow_prof *prof; 699 700 /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0 701 * This will give us the direction flags. 702 */ 703 struct ice_fv_word es[ICE_MAX_FV_WORDS]; 704 /* attributes can be used to add attributes to a particular PTYPE */ 705 const struct ice_ptype_attributes *attr; 706 u16 attr_cnt; 707 708 u16 mask[ICE_MAX_FV_WORDS]; 709 DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX); 710 }; 711 712 #define ICE_FLOW_RSS_HDRS_INNER_MASK \ 713 (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \ 714 ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \ 715 ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \ 716 ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \ 717 ICE_FLOW_SEG_HDR_NAT_T_ESP) 718 719 #define ICE_FLOW_SEG_HDRS_L3_MASK \ 720 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP) 721 #define ICE_FLOW_SEG_HDRS_L4_MASK \ 722 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \ 723 ICE_FLOW_SEG_HDR_SCTP) 724 /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */ 725 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \ 726 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP) 727 728 /** 729 * ice_flow_val_hdrs - validates packet segments for valid protocol headers 730 * @segs: array of one or more packet segments that describe the flow 731 * @segs_cnt: number of packet segments provided 732 */ 733 static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt) 734 { 735 u8 i; 736 737 for (i = 0; i < segs_cnt; i++) { 738 /* Multiple L3 headers */ 739 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK && 740 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK)) 741 return -EINVAL; 742 743 /* Multiple L4 headers */ 744 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK && 745 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)) 746 return -EINVAL; 747 } 748 749 return 0; 750 } 751 752 /* Sizes of fixed known protocol headers without header options */ 753 #define ICE_FLOW_PROT_HDR_SZ_MAC 14 754 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN (ICE_FLOW_PROT_HDR_SZ_MAC + 2) 755 #define ICE_FLOW_PROT_HDR_SZ_IPV4 20 756 #define ICE_FLOW_PROT_HDR_SZ_IPV6 40 757 #define ICE_FLOW_PROT_HDR_SZ_ARP 28 758 #define ICE_FLOW_PROT_HDR_SZ_ICMP 8 759 #define ICE_FLOW_PROT_HDR_SZ_TCP 20 760 #define ICE_FLOW_PROT_HDR_SZ_UDP 8 761 #define ICE_FLOW_PROT_HDR_SZ_SCTP 12 762 763 /** 764 * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers 765 * @params: information about the flow to be processed 766 * @seg: index of packet segment whose header size is to be determined 767 */ 768 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg) 769 { 770 u16 sz; 771 772 /* L2 headers */ 773 sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ? 774 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC; 775 776 /* L3 headers */ 777 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) 778 sz += ICE_FLOW_PROT_HDR_SZ_IPV4; 779 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6) 780 sz += ICE_FLOW_PROT_HDR_SZ_IPV6; 781 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP) 782 sz += ICE_FLOW_PROT_HDR_SZ_ARP; 783 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK) 784 /* An L3 header is required if L4 is specified */ 785 return 0; 786 787 /* L4 headers */ 788 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP) 789 sz += ICE_FLOW_PROT_HDR_SZ_ICMP; 790 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP) 791 sz += ICE_FLOW_PROT_HDR_SZ_TCP; 792 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP) 793 sz += ICE_FLOW_PROT_HDR_SZ_UDP; 794 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP) 795 sz += ICE_FLOW_PROT_HDR_SZ_SCTP; 796 797 return sz; 798 } 799 800 /** 801 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments 802 * @params: information about the flow to be processed 803 * 804 * This function identifies the packet types associated with the protocol 805 * headers being present in packet segments of the specified flow profile. 806 */ 807 static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params) 808 { 809 struct ice_flow_prof *prof; 810 u8 i; 811 812 memset(params->ptypes, 0xff, sizeof(params->ptypes)); 813 814 prof = params->prof; 815 816 for (i = 0; i < params->prof->segs_cnt; i++) { 817 const unsigned long *src; 818 u32 hdrs; 819 820 hdrs = prof->segs[i].hdrs; 821 822 if (hdrs & ICE_FLOW_SEG_HDR_ETH) { 823 src = !i ? (const unsigned long *)ice_ptypes_mac_ofos : 824 (const unsigned long *)ice_ptypes_mac_il; 825 bitmap_and(params->ptypes, params->ptypes, src, 826 ICE_FLOW_PTYPE_MAX); 827 } 828 829 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) { 830 src = (const unsigned long *)ice_ptypes_macvlan_il; 831 bitmap_and(params->ptypes, params->ptypes, src, 832 ICE_FLOW_PTYPE_MAX); 833 } 834 835 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) { 836 bitmap_and(params->ptypes, params->ptypes, 837 (const unsigned long *)ice_ptypes_arp_of, 838 ICE_FLOW_PTYPE_MAX); 839 } 840 841 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) && 842 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) { 843 src = i ? (const unsigned long *)ice_ptypes_ipv4_il : 844 (const unsigned long *)ice_ptypes_ipv4_ofos_all; 845 bitmap_and(params->ptypes, params->ptypes, src, 846 ICE_FLOW_PTYPE_MAX); 847 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) && 848 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) { 849 src = i ? (const unsigned long *)ice_ptypes_ipv6_il : 850 (const unsigned long *)ice_ptypes_ipv6_ofos_all; 851 bitmap_and(params->ptypes, params->ptypes, src, 852 ICE_FLOW_PTYPE_MAX); 853 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) && 854 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) { 855 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 : 856 (const unsigned long *)ice_ptypes_ipv4_il_no_l4; 857 bitmap_and(params->ptypes, params->ptypes, src, 858 ICE_FLOW_PTYPE_MAX); 859 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) { 860 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos : 861 (const unsigned long *)ice_ptypes_ipv4_il; 862 bitmap_and(params->ptypes, params->ptypes, src, 863 ICE_FLOW_PTYPE_MAX); 864 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) && 865 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) { 866 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 : 867 (const unsigned long *)ice_ptypes_ipv6_il_no_l4; 868 bitmap_and(params->ptypes, params->ptypes, src, 869 ICE_FLOW_PTYPE_MAX); 870 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) { 871 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos : 872 (const unsigned long *)ice_ptypes_ipv6_il; 873 bitmap_and(params->ptypes, params->ptypes, src, 874 ICE_FLOW_PTYPE_MAX); 875 } 876 877 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) { 878 src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos; 879 bitmap_and(params->ptypes, params->ptypes, src, 880 ICE_FLOW_PTYPE_MAX); 881 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) { 882 src = (const unsigned long *)ice_ptypes_pppoe; 883 bitmap_and(params->ptypes, params->ptypes, src, 884 ICE_FLOW_PTYPE_MAX); 885 } else { 886 src = (const unsigned long *)ice_ptypes_pppoe; 887 bitmap_andnot(params->ptypes, params->ptypes, src, 888 ICE_FLOW_PTYPE_MAX); 889 } 890 891 if (hdrs & ICE_FLOW_SEG_HDR_UDP) { 892 src = (const unsigned long *)ice_ptypes_udp_il; 893 bitmap_and(params->ptypes, params->ptypes, src, 894 ICE_FLOW_PTYPE_MAX); 895 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) { 896 bitmap_and(params->ptypes, params->ptypes, 897 (const unsigned long *)ice_ptypes_tcp_il, 898 ICE_FLOW_PTYPE_MAX); 899 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) { 900 src = (const unsigned long *)ice_ptypes_sctp_il; 901 bitmap_and(params->ptypes, params->ptypes, src, 902 ICE_FLOW_PTYPE_MAX); 903 } 904 905 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) { 906 src = !i ? (const unsigned long *)ice_ptypes_icmp_of : 907 (const unsigned long *)ice_ptypes_icmp_il; 908 bitmap_and(params->ptypes, params->ptypes, src, 909 ICE_FLOW_PTYPE_MAX); 910 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) { 911 if (!i) { 912 src = (const unsigned long *)ice_ptypes_gre_of; 913 bitmap_and(params->ptypes, params->ptypes, 914 src, ICE_FLOW_PTYPE_MAX); 915 } 916 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) { 917 src = (const unsigned long *)ice_ptypes_gtpc; 918 bitmap_and(params->ptypes, params->ptypes, src, 919 ICE_FLOW_PTYPE_MAX); 920 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) { 921 src = (const unsigned long *)ice_ptypes_gtpc_tid; 922 bitmap_and(params->ptypes, params->ptypes, src, 923 ICE_FLOW_PTYPE_MAX); 924 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) { 925 src = (const unsigned long *)ice_ptypes_gtpu; 926 bitmap_and(params->ptypes, params->ptypes, src, 927 ICE_FLOW_PTYPE_MAX); 928 929 /* Attributes for GTP packet with downlink */ 930 params->attr = ice_attr_gtpu_down; 931 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down); 932 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) { 933 src = (const unsigned long *)ice_ptypes_gtpu; 934 bitmap_and(params->ptypes, params->ptypes, src, 935 ICE_FLOW_PTYPE_MAX); 936 937 /* Attributes for GTP packet with uplink */ 938 params->attr = ice_attr_gtpu_up; 939 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up); 940 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) { 941 src = (const unsigned long *)ice_ptypes_gtpu; 942 bitmap_and(params->ptypes, params->ptypes, src, 943 ICE_FLOW_PTYPE_MAX); 944 945 /* Attributes for GTP packet with Extension Header */ 946 params->attr = ice_attr_gtpu_eh; 947 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh); 948 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) { 949 src = (const unsigned long *)ice_ptypes_gtpu; 950 bitmap_and(params->ptypes, params->ptypes, src, 951 ICE_FLOW_PTYPE_MAX); 952 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) { 953 src = (const unsigned long *)ice_ptypes_l2tpv3; 954 bitmap_and(params->ptypes, params->ptypes, src, 955 ICE_FLOW_PTYPE_MAX); 956 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) { 957 src = (const unsigned long *)ice_ptypes_esp; 958 bitmap_and(params->ptypes, params->ptypes, src, 959 ICE_FLOW_PTYPE_MAX); 960 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) { 961 src = (const unsigned long *)ice_ptypes_ah; 962 bitmap_and(params->ptypes, params->ptypes, src, 963 ICE_FLOW_PTYPE_MAX); 964 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) { 965 src = (const unsigned long *)ice_ptypes_nat_t_esp; 966 bitmap_and(params->ptypes, params->ptypes, src, 967 ICE_FLOW_PTYPE_MAX); 968 } 969 970 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) { 971 if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE) 972 src = (const unsigned long *)ice_ptypes_pfcp_node; 973 else 974 src = (const unsigned long *)ice_ptypes_pfcp_session; 975 976 bitmap_and(params->ptypes, params->ptypes, src, 977 ICE_FLOW_PTYPE_MAX); 978 } else { 979 src = (const unsigned long *)ice_ptypes_pfcp_node; 980 bitmap_andnot(params->ptypes, params->ptypes, src, 981 ICE_FLOW_PTYPE_MAX); 982 983 src = (const unsigned long *)ice_ptypes_pfcp_session; 984 bitmap_andnot(params->ptypes, params->ptypes, src, 985 ICE_FLOW_PTYPE_MAX); 986 } 987 } 988 989 return 0; 990 } 991 992 /** 993 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field 994 * @hw: pointer to the HW struct 995 * @params: information about the flow to be processed 996 * @seg: packet segment index of the field to be extracted 997 * @fld: ID of field to be extracted 998 * @match: bit field of all fields 999 * 1000 * This function determines the protocol ID, offset, and size of the given 1001 * field. It then allocates one or more extraction sequence entries for the 1002 * given field, and fill the entries with protocol ID and offset information. 1003 */ 1004 static int 1005 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params, 1006 u8 seg, enum ice_flow_field fld, u64 match) 1007 { 1008 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX; 1009 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL; 1010 u8 fv_words = hw->blk[params->blk].es.fvw; 1011 struct ice_flow_fld_info *flds; 1012 u16 cnt, ese_bits, i; 1013 u16 sib_mask = 0; 1014 u16 mask; 1015 u16 off; 1016 1017 flds = params->prof->segs[seg].fields; 1018 1019 switch (fld) { 1020 case ICE_FLOW_FIELD_IDX_ETH_DA: 1021 case ICE_FLOW_FIELD_IDX_ETH_SA: 1022 case ICE_FLOW_FIELD_IDX_S_VLAN: 1023 case ICE_FLOW_FIELD_IDX_C_VLAN: 1024 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL; 1025 break; 1026 case ICE_FLOW_FIELD_IDX_ETH_TYPE: 1027 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL; 1028 break; 1029 case ICE_FLOW_FIELD_IDX_IPV4_DSCP: 1030 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 1031 break; 1032 case ICE_FLOW_FIELD_IDX_IPV6_DSCP: 1033 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 1034 break; 1035 case ICE_FLOW_FIELD_IDX_IPV4_TTL: 1036 case ICE_FLOW_FIELD_IDX_IPV4_PROT: 1037 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 1038 1039 /* TTL and PROT share the same extraction seq. entry. 1040 * Each is considered a sibling to the other in terms of sharing 1041 * the same extraction sequence entry. 1042 */ 1043 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL) 1044 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT; 1045 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT) 1046 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL; 1047 1048 /* If the sibling field is also included, that field's 1049 * mask needs to be included. 1050 */ 1051 if (match & BIT(sib)) 1052 sib_mask = ice_flds_info[sib].mask; 1053 break; 1054 case ICE_FLOW_FIELD_IDX_IPV6_TTL: 1055 case ICE_FLOW_FIELD_IDX_IPV6_PROT: 1056 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 1057 1058 /* TTL and PROT share the same extraction seq. entry. 1059 * Each is considered a sibling to the other in terms of sharing 1060 * the same extraction sequence entry. 1061 */ 1062 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL) 1063 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT; 1064 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT) 1065 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL; 1066 1067 /* If the sibling field is also included, that field's 1068 * mask needs to be included. 1069 */ 1070 if (match & BIT(sib)) 1071 sib_mask = ice_flds_info[sib].mask; 1072 break; 1073 case ICE_FLOW_FIELD_IDX_IPV4_SA: 1074 case ICE_FLOW_FIELD_IDX_IPV4_DA: 1075 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 1076 break; 1077 case ICE_FLOW_FIELD_IDX_IPV6_SA: 1078 case ICE_FLOW_FIELD_IDX_IPV6_DA: 1079 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 1080 break; 1081 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT: 1082 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT: 1083 case ICE_FLOW_FIELD_IDX_TCP_FLAGS: 1084 prot_id = ICE_PROT_TCP_IL; 1085 break; 1086 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT: 1087 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT: 1088 prot_id = ICE_PROT_UDP_IL_OR_S; 1089 break; 1090 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT: 1091 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT: 1092 prot_id = ICE_PROT_SCTP_IL; 1093 break; 1094 case ICE_FLOW_FIELD_IDX_GTPC_TEID: 1095 case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID: 1096 case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID: 1097 case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID: 1098 case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID: 1099 case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI: 1100 /* GTP is accessed through UDP OF protocol */ 1101 prot_id = ICE_PROT_UDP_OF; 1102 break; 1103 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID: 1104 prot_id = ICE_PROT_PPPOE; 1105 break; 1106 case ICE_FLOW_FIELD_IDX_PFCP_SEID: 1107 prot_id = ICE_PROT_UDP_IL_OR_S; 1108 break; 1109 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID: 1110 prot_id = ICE_PROT_L2TPV3; 1111 break; 1112 case ICE_FLOW_FIELD_IDX_ESP_SPI: 1113 prot_id = ICE_PROT_ESP_F; 1114 break; 1115 case ICE_FLOW_FIELD_IDX_AH_SPI: 1116 prot_id = ICE_PROT_ESP_2; 1117 break; 1118 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI: 1119 prot_id = ICE_PROT_UDP_IL_OR_S; 1120 break; 1121 case ICE_FLOW_FIELD_IDX_ARP_SIP: 1122 case ICE_FLOW_FIELD_IDX_ARP_DIP: 1123 case ICE_FLOW_FIELD_IDX_ARP_SHA: 1124 case ICE_FLOW_FIELD_IDX_ARP_DHA: 1125 case ICE_FLOW_FIELD_IDX_ARP_OP: 1126 prot_id = ICE_PROT_ARP_OF; 1127 break; 1128 case ICE_FLOW_FIELD_IDX_ICMP_TYPE: 1129 case ICE_FLOW_FIELD_IDX_ICMP_CODE: 1130 /* ICMP type and code share the same extraction seq. entry */ 1131 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ? 1132 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL; 1133 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ? 1134 ICE_FLOW_FIELD_IDX_ICMP_CODE : 1135 ICE_FLOW_FIELD_IDX_ICMP_TYPE; 1136 break; 1137 case ICE_FLOW_FIELD_IDX_GRE_KEYID: 1138 prot_id = ICE_PROT_GRE_OF; 1139 break; 1140 default: 1141 return -EOPNOTSUPP; 1142 } 1143 1144 /* Each extraction sequence entry is a word in size, and extracts a 1145 * word-aligned offset from a protocol header. 1146 */ 1147 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE; 1148 1149 flds[fld].xtrct.prot_id = prot_id; 1150 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) * 1151 ICE_FLOW_FV_EXTRACT_SZ; 1152 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits); 1153 flds[fld].xtrct.idx = params->es_cnt; 1154 flds[fld].xtrct.mask = ice_flds_info[fld].mask; 1155 1156 /* Adjust the next field-entry index after accommodating the number of 1157 * entries this field consumes 1158 */ 1159 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size, 1160 ese_bits); 1161 1162 /* Fill in the extraction sequence entries needed for this field */ 1163 off = flds[fld].xtrct.off; 1164 mask = flds[fld].xtrct.mask; 1165 for (i = 0; i < cnt; i++) { 1166 /* Only consume an extraction sequence entry if there is no 1167 * sibling field associated with this field or the sibling entry 1168 * already extracts the word shared with this field. 1169 */ 1170 if (sib == ICE_FLOW_FIELD_IDX_MAX || 1171 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL || 1172 flds[sib].xtrct.off != off) { 1173 u8 idx; 1174 1175 /* Make sure the number of extraction sequence required 1176 * does not exceed the block's capability 1177 */ 1178 if (params->es_cnt >= fv_words) 1179 return -ENOSPC; 1180 1181 /* some blocks require a reversed field vector layout */ 1182 if (hw->blk[params->blk].es.reverse) 1183 idx = fv_words - params->es_cnt - 1; 1184 else 1185 idx = params->es_cnt; 1186 1187 params->es[idx].prot_id = prot_id; 1188 params->es[idx].off = off; 1189 params->mask[idx] = mask | sib_mask; 1190 params->es_cnt++; 1191 } 1192 1193 off += ICE_FLOW_FV_EXTRACT_SZ; 1194 } 1195 1196 return 0; 1197 } 1198 1199 /** 1200 * ice_flow_xtract_raws - Create extract sequence entries for raw bytes 1201 * @hw: pointer to the HW struct 1202 * @params: information about the flow to be processed 1203 * @seg: index of packet segment whose raw fields are to be extracted 1204 */ 1205 static int 1206 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params, 1207 u8 seg) 1208 { 1209 u16 fv_words; 1210 u16 hdrs_sz; 1211 u8 i; 1212 1213 if (!params->prof->segs[seg].raws_cnt) 1214 return 0; 1215 1216 if (params->prof->segs[seg].raws_cnt > 1217 ARRAY_SIZE(params->prof->segs[seg].raws)) 1218 return -ENOSPC; 1219 1220 /* Offsets within the segment headers are not supported */ 1221 hdrs_sz = ice_flow_calc_seg_sz(params, seg); 1222 if (!hdrs_sz) 1223 return -EINVAL; 1224 1225 fv_words = hw->blk[params->blk].es.fvw; 1226 1227 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) { 1228 struct ice_flow_seg_fld_raw *raw; 1229 u16 off, cnt, j; 1230 1231 raw = ¶ms->prof->segs[seg].raws[i]; 1232 1233 /* Storing extraction information */ 1234 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S; 1235 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) * 1236 ICE_FLOW_FV_EXTRACT_SZ; 1237 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) * 1238 BITS_PER_BYTE; 1239 raw->info.xtrct.idx = params->es_cnt; 1240 1241 /* Determine the number of field vector entries this raw field 1242 * consumes. 1243 */ 1244 cnt = DIV_ROUND_UP(raw->info.xtrct.disp + 1245 (raw->info.src.last * BITS_PER_BYTE), 1246 (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE)); 1247 off = raw->info.xtrct.off; 1248 for (j = 0; j < cnt; j++) { 1249 u16 idx; 1250 1251 /* Make sure the number of extraction sequence required 1252 * does not exceed the block's capability 1253 */ 1254 if (params->es_cnt >= hw->blk[params->blk].es.count || 1255 params->es_cnt >= ICE_MAX_FV_WORDS) 1256 return -ENOSPC; 1257 1258 /* some blocks require a reversed field vector layout */ 1259 if (hw->blk[params->blk].es.reverse) 1260 idx = fv_words - params->es_cnt - 1; 1261 else 1262 idx = params->es_cnt; 1263 1264 params->es[idx].prot_id = raw->info.xtrct.prot_id; 1265 params->es[idx].off = off; 1266 params->es_cnt++; 1267 off += ICE_FLOW_FV_EXTRACT_SZ; 1268 } 1269 } 1270 1271 return 0; 1272 } 1273 1274 /** 1275 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments 1276 * @hw: pointer to the HW struct 1277 * @params: information about the flow to be processed 1278 * 1279 * This function iterates through all matched fields in the given segments, and 1280 * creates an extraction sequence for the fields. 1281 */ 1282 static int 1283 ice_flow_create_xtrct_seq(struct ice_hw *hw, 1284 struct ice_flow_prof_params *params) 1285 { 1286 struct ice_flow_prof *prof = params->prof; 1287 int status = 0; 1288 u8 i; 1289 1290 for (i = 0; i < prof->segs_cnt; i++) { 1291 u64 match = params->prof->segs[i].match; 1292 enum ice_flow_field j; 1293 1294 for_each_set_bit(j, (unsigned long *)&match, 1295 ICE_FLOW_FIELD_IDX_MAX) { 1296 status = ice_flow_xtract_fld(hw, params, i, j, match); 1297 if (status) 1298 return status; 1299 clear_bit(j, (unsigned long *)&match); 1300 } 1301 1302 /* Process raw matching bytes */ 1303 status = ice_flow_xtract_raws(hw, params, i); 1304 if (status) 1305 return status; 1306 } 1307 1308 return status; 1309 } 1310 1311 /** 1312 * ice_flow_proc_segs - process all packet segments associated with a profile 1313 * @hw: pointer to the HW struct 1314 * @params: information about the flow to be processed 1315 */ 1316 static int 1317 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params) 1318 { 1319 int status; 1320 1321 status = ice_flow_proc_seg_hdrs(params); 1322 if (status) 1323 return status; 1324 1325 status = ice_flow_create_xtrct_seq(hw, params); 1326 if (status) 1327 return status; 1328 1329 switch (params->blk) { 1330 case ICE_BLK_FD: 1331 case ICE_BLK_RSS: 1332 status = 0; 1333 break; 1334 default: 1335 return -EOPNOTSUPP; 1336 } 1337 1338 return status; 1339 } 1340 1341 #define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001 1342 #define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002 1343 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004 1344 #define ICE_FLOW_FIND_PROF_CHK_SYMM 0x00000008 1345 1346 /** 1347 * ice_flow_find_prof_conds - Find a profile matching headers and conditions 1348 * @hw: pointer to the HW struct 1349 * @blk: classification stage 1350 * @dir: flow direction 1351 * @segs: array of one or more packet segments that describe the flow 1352 * @segs_cnt: number of packet segments provided 1353 * @symm: symmetric setting for RSS profiles 1354 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI) 1355 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*) 1356 */ 1357 static struct ice_flow_prof * 1358 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk, 1359 enum ice_flow_dir dir, struct ice_flow_seg_info *segs, 1360 u8 segs_cnt, bool symm, u16 vsi_handle, u32 conds) 1361 { 1362 struct ice_flow_prof *p, *prof = NULL; 1363 1364 mutex_lock(&hw->fl_profs_locks[blk]); 1365 list_for_each_entry(p, &hw->fl_profs[blk], l_entry) 1366 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) && 1367 segs_cnt && segs_cnt == p->segs_cnt) { 1368 u8 i; 1369 1370 /* Check for profile-VSI association if specified */ 1371 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) && 1372 ice_is_vsi_valid(hw, vsi_handle) && 1373 !test_bit(vsi_handle, p->vsis)) 1374 continue; 1375 1376 /* Check for symmetric settings */ 1377 if ((conds & ICE_FLOW_FIND_PROF_CHK_SYMM) && 1378 p->symm != symm) 1379 continue; 1380 1381 /* Protocol headers must be checked. Matched fields are 1382 * checked if specified. 1383 */ 1384 for (i = 0; i < segs_cnt; i++) 1385 if (segs[i].hdrs != p->segs[i].hdrs || 1386 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) && 1387 segs[i].match != p->segs[i].match)) 1388 break; 1389 1390 /* A match is found if all segments are matched */ 1391 if (i == segs_cnt) { 1392 prof = p; 1393 break; 1394 } 1395 } 1396 mutex_unlock(&hw->fl_profs_locks[blk]); 1397 1398 return prof; 1399 } 1400 1401 /** 1402 * ice_flow_find_prof_id - Look up a profile with given profile ID 1403 * @hw: pointer to the HW struct 1404 * @blk: classification stage 1405 * @prof_id: unique ID to identify this flow profile 1406 */ 1407 static struct ice_flow_prof * 1408 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id) 1409 { 1410 struct ice_flow_prof *p; 1411 1412 list_for_each_entry(p, &hw->fl_profs[blk], l_entry) 1413 if (p->id == prof_id) 1414 return p; 1415 1416 return NULL; 1417 } 1418 1419 /** 1420 * ice_flow_rem_entry_sync - Remove a flow entry 1421 * @hw: pointer to the HW struct 1422 * @blk: classification stage 1423 * @entry: flow entry to be removed 1424 */ 1425 static int 1426 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk, 1427 struct ice_flow_entry *entry) 1428 { 1429 if (!entry) 1430 return -EINVAL; 1431 1432 list_del(&entry->l_entry); 1433 1434 devm_kfree(ice_hw_to_dev(hw), entry); 1435 1436 return 0; 1437 } 1438 1439 /** 1440 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields 1441 * @hw: pointer to the HW struct 1442 * @blk: classification stage 1443 * @dir: flow direction 1444 * @segs: array of one or more packet segments that describe the flow 1445 * @segs_cnt: number of packet segments provided 1446 * @symm: symmetric setting for RSS profiles 1447 * @prof: stores the returned flow profile added 1448 * 1449 * Assumption: the caller has acquired the lock to the profile list 1450 */ 1451 static int 1452 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk, 1453 enum ice_flow_dir dir, 1454 struct ice_flow_seg_info *segs, u8 segs_cnt, 1455 bool symm, struct ice_flow_prof **prof) 1456 { 1457 struct ice_flow_prof_params *params; 1458 struct ice_prof_id *ids; 1459 int status; 1460 u64 prof_id; 1461 u8 i; 1462 1463 if (!prof) 1464 return -EINVAL; 1465 1466 ids = &hw->blk[blk].prof_id; 1467 prof_id = find_first_zero_bit(ids->id, ids->count); 1468 if (prof_id >= ids->count) 1469 return -ENOSPC; 1470 1471 params = kzalloc(sizeof(*params), GFP_KERNEL); 1472 if (!params) 1473 return -ENOMEM; 1474 1475 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof), 1476 GFP_KERNEL); 1477 if (!params->prof) { 1478 status = -ENOMEM; 1479 goto free_params; 1480 } 1481 1482 /* initialize extraction sequence to all invalid (0xff) */ 1483 for (i = 0; i < ICE_MAX_FV_WORDS; i++) { 1484 params->es[i].prot_id = ICE_PROT_INVALID; 1485 params->es[i].off = ICE_FV_OFFSET_INVAL; 1486 } 1487 1488 params->blk = blk; 1489 params->prof->id = prof_id; 1490 params->prof->dir = dir; 1491 params->prof->segs_cnt = segs_cnt; 1492 params->prof->symm = symm; 1493 1494 /* Make a copy of the segments that need to be persistent in the flow 1495 * profile instance 1496 */ 1497 for (i = 0; i < segs_cnt; i++) 1498 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs)); 1499 1500 status = ice_flow_proc_segs(hw, params); 1501 if (status) { 1502 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n"); 1503 goto out; 1504 } 1505 1506 /* Add a HW profile for this flow profile */ 1507 status = ice_add_prof(hw, blk, prof_id, params->ptypes, 1508 params->attr, params->attr_cnt, params->es, 1509 params->mask, symm, true); 1510 if (status) { 1511 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n"); 1512 goto out; 1513 } 1514 1515 INIT_LIST_HEAD(¶ms->prof->entries); 1516 mutex_init(¶ms->prof->entries_lock); 1517 set_bit(prof_id, ids->id); 1518 *prof = params->prof; 1519 1520 out: 1521 if (status) 1522 devm_kfree(ice_hw_to_dev(hw), params->prof); 1523 free_params: 1524 kfree(params); 1525 1526 return status; 1527 } 1528 1529 /** 1530 * ice_flow_rem_prof_sync - remove a flow profile 1531 * @hw: pointer to the hardware structure 1532 * @blk: classification stage 1533 * @prof: pointer to flow profile to remove 1534 * 1535 * Assumption: the caller has acquired the lock to the profile list 1536 */ 1537 static int 1538 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk, 1539 struct ice_flow_prof *prof) 1540 { 1541 int status; 1542 1543 /* Remove all remaining flow entries before removing the flow profile */ 1544 if (!list_empty(&prof->entries)) { 1545 struct ice_flow_entry *e, *t; 1546 1547 mutex_lock(&prof->entries_lock); 1548 1549 list_for_each_entry_safe(e, t, &prof->entries, l_entry) { 1550 status = ice_flow_rem_entry_sync(hw, blk, e); 1551 if (status) 1552 break; 1553 } 1554 1555 mutex_unlock(&prof->entries_lock); 1556 } 1557 1558 /* Remove all hardware profiles associated with this flow profile */ 1559 status = ice_rem_prof(hw, blk, prof->id); 1560 if (!status) { 1561 clear_bit(prof->id, hw->blk[blk].prof_id.id); 1562 list_del(&prof->l_entry); 1563 mutex_destroy(&prof->entries_lock); 1564 devm_kfree(ice_hw_to_dev(hw), prof); 1565 } 1566 1567 return status; 1568 } 1569 1570 /** 1571 * ice_flow_assoc_prof - associate a VSI with a flow profile 1572 * @hw: pointer to the hardware structure 1573 * @blk: classification stage 1574 * @prof: pointer to flow profile 1575 * @vsi_handle: software VSI handle 1576 * 1577 * Assumption: the caller has acquired the lock to the profile list 1578 * and the software VSI handle has been validated 1579 */ 1580 static int 1581 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk, 1582 struct ice_flow_prof *prof, u16 vsi_handle) 1583 { 1584 int status = 0; 1585 1586 if (!test_bit(vsi_handle, prof->vsis)) { 1587 status = ice_add_prof_id_flow(hw, blk, 1588 ice_get_hw_vsi_num(hw, 1589 vsi_handle), 1590 prof->id); 1591 if (!status) 1592 set_bit(vsi_handle, prof->vsis); 1593 else 1594 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n", 1595 status); 1596 } 1597 1598 return status; 1599 } 1600 1601 /** 1602 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile 1603 * @hw: pointer to the hardware structure 1604 * @blk: classification stage 1605 * @prof: pointer to flow profile 1606 * @vsi_handle: software VSI handle 1607 * 1608 * Assumption: the caller has acquired the lock to the profile list 1609 * and the software VSI handle has been validated 1610 */ 1611 static int 1612 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk, 1613 struct ice_flow_prof *prof, u16 vsi_handle) 1614 { 1615 int status = 0; 1616 1617 if (test_bit(vsi_handle, prof->vsis)) { 1618 status = ice_rem_prof_id_flow(hw, blk, 1619 ice_get_hw_vsi_num(hw, 1620 vsi_handle), 1621 prof->id); 1622 if (!status) 1623 clear_bit(vsi_handle, prof->vsis); 1624 else 1625 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n", 1626 status); 1627 } 1628 1629 return status; 1630 } 1631 1632 #define FLAG_GTP_EH_PDU_LINK BIT_ULL(13) 1633 #define FLAG_GTP_EH_PDU BIT_ULL(14) 1634 1635 #define HI_BYTE_IN_WORD GENMASK(15, 8) 1636 #define LO_BYTE_IN_WORD GENMASK(7, 0) 1637 1638 #define FLAG_GTPU_MSK \ 1639 (FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK) 1640 #define FLAG_GTPU_UP \ 1641 (FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK) 1642 #define FLAG_GTPU_DW FLAG_GTP_EH_PDU 1643 1644 /** 1645 * ice_flow_set_parser_prof - Set flow profile based on the parsed profile info 1646 * @hw: pointer to the HW struct 1647 * @dest_vsi: dest VSI 1648 * @fdir_vsi: fdir programming VSI 1649 * @prof: stores parsed profile info from raw flow 1650 * @blk: classification blk 1651 * 1652 * Return: 0 on success or negative errno on failure. 1653 */ 1654 int 1655 ice_flow_set_parser_prof(struct ice_hw *hw, u16 dest_vsi, u16 fdir_vsi, 1656 struct ice_parser_profile *prof, enum ice_block blk) 1657 { 1658 u64 id = find_first_bit(prof->ptypes, ICE_FLOW_PTYPE_MAX); 1659 struct ice_flow_prof_params *params __free(kfree); 1660 u8 fv_words = hw->blk[blk].es.fvw; 1661 int status; 1662 int i, idx; 1663 1664 params = kzalloc(sizeof(*params), GFP_KERNEL); 1665 if (!params) 1666 return -ENOMEM; 1667 1668 for (i = 0; i < ICE_MAX_FV_WORDS; i++) { 1669 params->es[i].prot_id = ICE_PROT_INVALID; 1670 params->es[i].off = ICE_FV_OFFSET_INVAL; 1671 } 1672 1673 for (i = 0; i < prof->fv_num; i++) { 1674 if (hw->blk[blk].es.reverse) 1675 idx = fv_words - i - 1; 1676 else 1677 idx = i; 1678 params->es[idx].prot_id = prof->fv[i].proto_id; 1679 params->es[idx].off = prof->fv[i].offset; 1680 params->mask[idx] = (((prof->fv[i].msk) << BITS_PER_BYTE) & 1681 HI_BYTE_IN_WORD) | 1682 (((prof->fv[i].msk) >> BITS_PER_BYTE) & 1683 LO_BYTE_IN_WORD); 1684 } 1685 1686 switch (prof->flags) { 1687 case FLAG_GTPU_DW: 1688 params->attr = ice_attr_gtpu_down; 1689 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down); 1690 break; 1691 case FLAG_GTPU_UP: 1692 params->attr = ice_attr_gtpu_up; 1693 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up); 1694 break; 1695 default: 1696 if (prof->flags_msk & FLAG_GTPU_MSK) { 1697 params->attr = ice_attr_gtpu_session; 1698 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session); 1699 } 1700 break; 1701 } 1702 1703 status = ice_add_prof(hw, blk, id, prof->ptypes, 1704 params->attr, params->attr_cnt, 1705 params->es, params->mask, false, false); 1706 if (status) 1707 return status; 1708 1709 status = ice_flow_assoc_fdir_prof(hw, blk, dest_vsi, fdir_vsi, id); 1710 if (status) 1711 ice_rem_prof(hw, blk, id); 1712 1713 return status; 1714 } 1715 1716 /** 1717 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields 1718 * @hw: pointer to the HW struct 1719 * @blk: classification stage 1720 * @dir: flow direction 1721 * @segs: array of one or more packet segments that describe the flow 1722 * @segs_cnt: number of packet segments provided 1723 * @symm: symmetric setting for RSS profiles 1724 * @prof: stores the returned flow profile added 1725 */ 1726 int 1727 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir, 1728 struct ice_flow_seg_info *segs, u8 segs_cnt, 1729 bool symm, struct ice_flow_prof **prof) 1730 { 1731 int status; 1732 1733 if (segs_cnt > ICE_FLOW_SEG_MAX) 1734 return -ENOSPC; 1735 1736 if (!segs_cnt) 1737 return -EINVAL; 1738 1739 if (!segs) 1740 return -EINVAL; 1741 1742 status = ice_flow_val_hdrs(segs, segs_cnt); 1743 if (status) 1744 return status; 1745 1746 mutex_lock(&hw->fl_profs_locks[blk]); 1747 1748 status = ice_flow_add_prof_sync(hw, blk, dir, segs, segs_cnt, 1749 symm, prof); 1750 if (!status) 1751 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]); 1752 1753 mutex_unlock(&hw->fl_profs_locks[blk]); 1754 1755 return status; 1756 } 1757 1758 /** 1759 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it 1760 * @hw: pointer to the HW struct 1761 * @blk: the block for which the flow profile is to be removed 1762 * @prof_id: unique ID of the flow profile to be removed 1763 */ 1764 int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id) 1765 { 1766 struct ice_flow_prof *prof; 1767 int status; 1768 1769 mutex_lock(&hw->fl_profs_locks[blk]); 1770 1771 prof = ice_flow_find_prof_id(hw, blk, prof_id); 1772 if (!prof) { 1773 status = -ENOENT; 1774 goto out; 1775 } 1776 1777 /* prof becomes invalid after the call */ 1778 status = ice_flow_rem_prof_sync(hw, blk, prof); 1779 1780 out: 1781 mutex_unlock(&hw->fl_profs_locks[blk]); 1782 1783 return status; 1784 } 1785 1786 /** 1787 * ice_flow_add_entry - Add a flow entry 1788 * @hw: pointer to the HW struct 1789 * @blk: classification stage 1790 * @prof_id: ID of the profile to add a new flow entry to 1791 * @entry_id: unique ID to identify this flow entry 1792 * @vsi_handle: software VSI handle for the flow entry 1793 * @prio: priority of the flow entry 1794 * @data: pointer to a data buffer containing flow entry's match values/masks 1795 * @entry_h: pointer to buffer that receives the new flow entry's handle 1796 */ 1797 int 1798 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id, 1799 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio, 1800 void *data, u64 *entry_h) 1801 { 1802 struct ice_flow_entry *e = NULL; 1803 struct ice_flow_prof *prof; 1804 int status; 1805 1806 /* No flow entry data is expected for RSS */ 1807 if (!entry_h || (!data && blk != ICE_BLK_RSS)) 1808 return -EINVAL; 1809 1810 if (!ice_is_vsi_valid(hw, vsi_handle)) 1811 return -EINVAL; 1812 1813 mutex_lock(&hw->fl_profs_locks[blk]); 1814 1815 prof = ice_flow_find_prof_id(hw, blk, prof_id); 1816 if (!prof) { 1817 status = -ENOENT; 1818 } else { 1819 /* Allocate memory for the entry being added and associate 1820 * the VSI to the found flow profile 1821 */ 1822 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL); 1823 if (!e) 1824 status = -ENOMEM; 1825 else 1826 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle); 1827 } 1828 1829 mutex_unlock(&hw->fl_profs_locks[blk]); 1830 if (status) 1831 goto out; 1832 1833 e->id = entry_id; 1834 e->vsi_handle = vsi_handle; 1835 e->prof = prof; 1836 e->priority = prio; 1837 1838 switch (blk) { 1839 case ICE_BLK_FD: 1840 case ICE_BLK_RSS: 1841 break; 1842 default: 1843 status = -EOPNOTSUPP; 1844 goto out; 1845 } 1846 1847 mutex_lock(&prof->entries_lock); 1848 list_add(&e->l_entry, &prof->entries); 1849 mutex_unlock(&prof->entries_lock); 1850 1851 *entry_h = ICE_FLOW_ENTRY_HNDL(e); 1852 1853 out: 1854 if (status) 1855 devm_kfree(ice_hw_to_dev(hw), e); 1856 1857 return status; 1858 } 1859 1860 /** 1861 * ice_flow_rem_entry - Remove a flow entry 1862 * @hw: pointer to the HW struct 1863 * @blk: classification stage 1864 * @entry_h: handle to the flow entry to be removed 1865 */ 1866 int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h) 1867 { 1868 struct ice_flow_entry *entry; 1869 struct ice_flow_prof *prof; 1870 int status = 0; 1871 1872 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL) 1873 return -EINVAL; 1874 1875 entry = ICE_FLOW_ENTRY_PTR(entry_h); 1876 1877 /* Retain the pointer to the flow profile as the entry will be freed */ 1878 prof = entry->prof; 1879 1880 if (prof) { 1881 mutex_lock(&prof->entries_lock); 1882 status = ice_flow_rem_entry_sync(hw, blk, entry); 1883 mutex_unlock(&prof->entries_lock); 1884 } 1885 1886 return status; 1887 } 1888 1889 /** 1890 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer 1891 * @seg: packet segment the field being set belongs to 1892 * @fld: field to be set 1893 * @field_type: type of the field 1894 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 1895 * entry's input buffer 1896 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's 1897 * input buffer 1898 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from 1899 * entry's input buffer 1900 * 1901 * This helper function stores information of a field being matched, including 1902 * the type of the field and the locations of the value to match, the mask, and 1903 * the upper-bound value in the start of the input buffer for a flow entry. 1904 * This function should only be used for fixed-size data structures. 1905 * 1906 * This function also opportunistically determines the protocol headers to be 1907 * present based on the fields being set. Some fields cannot be used alone to 1908 * determine the protocol headers present. Sometimes, fields for particular 1909 * protocol headers are not matched. In those cases, the protocol headers 1910 * must be explicitly set. 1911 */ 1912 static void 1913 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 1914 enum ice_flow_fld_match_type field_type, u16 val_loc, 1915 u16 mask_loc, u16 last_loc) 1916 { 1917 u64 bit = BIT_ULL(fld); 1918 1919 seg->match |= bit; 1920 if (field_type == ICE_FLOW_FLD_TYPE_RANGE) 1921 seg->range |= bit; 1922 1923 seg->fields[fld].type = field_type; 1924 seg->fields[fld].src.val = val_loc; 1925 seg->fields[fld].src.mask = mask_loc; 1926 seg->fields[fld].src.last = last_loc; 1927 1928 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr); 1929 } 1930 1931 /** 1932 * ice_flow_set_fld - specifies locations of field from entry's input buffer 1933 * @seg: packet segment the field being set belongs to 1934 * @fld: field to be set 1935 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 1936 * entry's input buffer 1937 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's 1938 * input buffer 1939 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from 1940 * entry's input buffer 1941 * @range: indicate if field being matched is to be in a range 1942 * 1943 * This function specifies the locations, in the form of byte offsets from the 1944 * start of the input buffer for a flow entry, from where the value to match, 1945 * the mask value, and upper value can be extracted. These locations are then 1946 * stored in the flow profile. When adding a flow entry associated with the 1947 * flow profile, these locations will be used to quickly extract the values and 1948 * create the content of a match entry. This function should only be used for 1949 * fixed-size data structures. 1950 */ 1951 void 1952 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 1953 u16 val_loc, u16 mask_loc, u16 last_loc, bool range) 1954 { 1955 enum ice_flow_fld_match_type t = range ? 1956 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG; 1957 1958 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc); 1959 } 1960 1961 /** 1962 * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf 1963 * @seg: packet segment the field being set belongs to 1964 * @off: offset of the raw field from the beginning of the segment in bytes 1965 * @len: length of the raw pattern to be matched 1966 * @val_loc: location of the value to match from entry's input buffer 1967 * @mask_loc: location of mask value from entry's input buffer 1968 * 1969 * This function specifies the offset of the raw field to be match from the 1970 * beginning of the specified packet segment, and the locations, in the form of 1971 * byte offsets from the start of the input buffer for a flow entry, from where 1972 * the value to match and the mask value to be extracted. These locations are 1973 * then stored in the flow profile. When adding flow entries to the associated 1974 * flow profile, these locations can be used to quickly extract the values to 1975 * create the content of a match entry. This function should only be used for 1976 * fixed-size data structures. 1977 */ 1978 void 1979 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len, 1980 u16 val_loc, u16 mask_loc) 1981 { 1982 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) { 1983 seg->raws[seg->raws_cnt].off = off; 1984 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE; 1985 seg->raws[seg->raws_cnt].info.src.val = val_loc; 1986 seg->raws[seg->raws_cnt].info.src.mask = mask_loc; 1987 /* The "last" field is used to store the length of the field */ 1988 seg->raws[seg->raws_cnt].info.src.last = len; 1989 } 1990 1991 /* Overflows of "raws" will be handled as an error condition later in 1992 * the flow when this information is processed. 1993 */ 1994 seg->raws_cnt++; 1995 } 1996 1997 /** 1998 * ice_flow_rem_vsi_prof - remove VSI from flow profile 1999 * @hw: pointer to the hardware structure 2000 * @vsi_handle: software VSI handle 2001 * @prof_id: unique ID to identify this flow profile 2002 * 2003 * This function removes the flow entries associated to the input 2004 * VSI handle and disassociate the VSI from the flow profile. 2005 */ 2006 int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id) 2007 { 2008 struct ice_flow_prof *prof; 2009 int status = 0; 2010 2011 if (!ice_is_vsi_valid(hw, vsi_handle)) 2012 return -EINVAL; 2013 2014 /* find flow profile pointer with input package block and profile ID */ 2015 prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id); 2016 if (!prof) { 2017 ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n", 2018 prof_id); 2019 return -ENOENT; 2020 } 2021 2022 /* Remove all remaining flow entries before removing the flow profile */ 2023 if (!list_empty(&prof->entries)) { 2024 struct ice_flow_entry *e, *t; 2025 2026 mutex_lock(&prof->entries_lock); 2027 list_for_each_entry_safe(e, t, &prof->entries, l_entry) { 2028 if (e->vsi_handle != vsi_handle) 2029 continue; 2030 2031 status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e); 2032 if (status) 2033 break; 2034 } 2035 mutex_unlock(&prof->entries_lock); 2036 } 2037 if (status) 2038 return status; 2039 2040 /* disassociate the flow profile from sw VSI handle */ 2041 status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle); 2042 if (status) 2043 ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n", 2044 status); 2045 return status; 2046 } 2047 2048 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \ 2049 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN) 2050 2051 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \ 2052 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6) 2053 2054 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \ 2055 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP) 2056 2057 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \ 2058 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \ 2059 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \ 2060 ICE_FLOW_RSS_SEG_HDR_L4_MASKS) 2061 2062 /** 2063 * ice_flow_set_rss_seg_info - setup packet segments for RSS 2064 * @segs: pointer to the flow field segment(s) 2065 * @seg_cnt: segment count 2066 * @cfg: configure parameters 2067 * 2068 * Helper function to extract fields from hash bitmap and use flow 2069 * header value to set flow field segment for further use in flow 2070 * profile entry or removal. 2071 */ 2072 static int 2073 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt, 2074 const struct ice_rss_hash_cfg *cfg) 2075 { 2076 struct ice_flow_seg_info *seg; 2077 u64 val; 2078 u16 i; 2079 2080 /* set inner most segment */ 2081 seg = &segs[seg_cnt - 1]; 2082 2083 for_each_set_bit(i, (const unsigned long *)&cfg->hash_flds, 2084 (u16)ICE_FLOW_FIELD_IDX_MAX) 2085 ice_flow_set_fld(seg, (enum ice_flow_field)i, 2086 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, 2087 ICE_FLOW_FLD_OFF_INVAL, false); 2088 2089 ICE_FLOW_SET_HDRS(seg, cfg->addl_hdrs); 2090 2091 /* set outer most header */ 2092 if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4) 2093 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 | 2094 ICE_FLOW_SEG_HDR_IPV_OTHER; 2095 else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6) 2096 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 | 2097 ICE_FLOW_SEG_HDR_IPV_OTHER; 2098 2099 if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS & 2100 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER) 2101 return -EINVAL; 2102 2103 val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS); 2104 if (val && !is_power_of_2(val)) 2105 return -EIO; 2106 2107 val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS); 2108 if (val && !is_power_of_2(val)) 2109 return -EIO; 2110 2111 return 0; 2112 } 2113 2114 /** 2115 * ice_rem_vsi_rss_list - remove VSI from RSS list 2116 * @hw: pointer to the hardware structure 2117 * @vsi_handle: software VSI handle 2118 * 2119 * Remove the VSI from all RSS configurations in the list. 2120 */ 2121 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle) 2122 { 2123 struct ice_rss_cfg *r, *tmp; 2124 2125 if (list_empty(&hw->rss_list_head)) 2126 return; 2127 2128 mutex_lock(&hw->rss_locks); 2129 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry) 2130 if (test_and_clear_bit(vsi_handle, r->vsis)) 2131 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) { 2132 list_del(&r->l_entry); 2133 devm_kfree(ice_hw_to_dev(hw), r); 2134 } 2135 mutex_unlock(&hw->rss_locks); 2136 } 2137 2138 /** 2139 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI 2140 * @hw: pointer to the hardware structure 2141 * @vsi_handle: software VSI handle 2142 * 2143 * This function will iterate through all flow profiles and disassociate 2144 * the VSI from that profile. If the flow profile has no VSIs it will 2145 * be removed. 2146 */ 2147 int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle) 2148 { 2149 const enum ice_block blk = ICE_BLK_RSS; 2150 struct ice_flow_prof *p, *t; 2151 int status = 0; 2152 2153 if (!ice_is_vsi_valid(hw, vsi_handle)) 2154 return -EINVAL; 2155 2156 if (list_empty(&hw->fl_profs[blk])) 2157 return 0; 2158 2159 mutex_lock(&hw->rss_locks); 2160 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry) 2161 if (test_bit(vsi_handle, p->vsis)) { 2162 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle); 2163 if (status) 2164 break; 2165 2166 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) { 2167 status = ice_flow_rem_prof(hw, blk, p->id); 2168 if (status) 2169 break; 2170 } 2171 } 2172 mutex_unlock(&hw->rss_locks); 2173 2174 return status; 2175 } 2176 2177 /** 2178 * ice_get_rss_hdr_type - get a RSS profile's header type 2179 * @prof: RSS flow profile 2180 */ 2181 static enum ice_rss_cfg_hdr_type 2182 ice_get_rss_hdr_type(struct ice_flow_prof *prof) 2183 { 2184 if (prof->segs_cnt == ICE_FLOW_SEG_SINGLE) { 2185 return ICE_RSS_OUTER_HEADERS; 2186 } else if (prof->segs_cnt == ICE_FLOW_SEG_MAX) { 2187 const struct ice_flow_seg_info *s; 2188 2189 s = &prof->segs[ICE_RSS_OUTER_HEADERS]; 2190 if (s->hdrs == ICE_FLOW_SEG_HDR_NONE) 2191 return ICE_RSS_INNER_HEADERS; 2192 if (s->hdrs & ICE_FLOW_SEG_HDR_IPV4) 2193 return ICE_RSS_INNER_HEADERS_W_OUTER_IPV4; 2194 if (s->hdrs & ICE_FLOW_SEG_HDR_IPV6) 2195 return ICE_RSS_INNER_HEADERS_W_OUTER_IPV6; 2196 } 2197 2198 return ICE_RSS_ANY_HEADERS; 2199 } 2200 2201 static bool 2202 ice_rss_match_prof(struct ice_rss_cfg *r, struct ice_flow_prof *prof, 2203 enum ice_rss_cfg_hdr_type hdr_type) 2204 { 2205 return (r->hash.hdr_type == hdr_type && 2206 r->hash.hash_flds == prof->segs[prof->segs_cnt - 1].match && 2207 r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs); 2208 } 2209 2210 /** 2211 * ice_rem_rss_list - remove RSS configuration from list 2212 * @hw: pointer to the hardware structure 2213 * @vsi_handle: software VSI handle 2214 * @prof: pointer to flow profile 2215 * 2216 * Assumption: lock has already been acquired for RSS list 2217 */ 2218 static void 2219 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof) 2220 { 2221 enum ice_rss_cfg_hdr_type hdr_type; 2222 struct ice_rss_cfg *r, *tmp; 2223 2224 /* Search for RSS hash fields associated to the VSI that match the 2225 * hash configurations associated to the flow profile. If found 2226 * remove from the RSS entry list of the VSI context and delete entry. 2227 */ 2228 hdr_type = ice_get_rss_hdr_type(prof); 2229 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry) 2230 if (ice_rss_match_prof(r, prof, hdr_type)) { 2231 clear_bit(vsi_handle, r->vsis); 2232 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) { 2233 list_del(&r->l_entry); 2234 devm_kfree(ice_hw_to_dev(hw), r); 2235 } 2236 return; 2237 } 2238 } 2239 2240 /** 2241 * ice_add_rss_list - add RSS configuration to list 2242 * @hw: pointer to the hardware structure 2243 * @vsi_handle: software VSI handle 2244 * @prof: pointer to flow profile 2245 * 2246 * Assumption: lock has already been acquired for RSS list 2247 */ 2248 static int 2249 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof) 2250 { 2251 enum ice_rss_cfg_hdr_type hdr_type; 2252 struct ice_rss_cfg *r, *rss_cfg; 2253 2254 hdr_type = ice_get_rss_hdr_type(prof); 2255 list_for_each_entry(r, &hw->rss_list_head, l_entry) 2256 if (ice_rss_match_prof(r, prof, hdr_type)) { 2257 set_bit(vsi_handle, r->vsis); 2258 return 0; 2259 } 2260 2261 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg), 2262 GFP_KERNEL); 2263 if (!rss_cfg) 2264 return -ENOMEM; 2265 2266 rss_cfg->hash.hash_flds = prof->segs[prof->segs_cnt - 1].match; 2267 rss_cfg->hash.addl_hdrs = prof->segs[prof->segs_cnt - 1].hdrs; 2268 rss_cfg->hash.hdr_type = hdr_type; 2269 rss_cfg->hash.symm = prof->symm; 2270 set_bit(vsi_handle, rss_cfg->vsis); 2271 2272 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head); 2273 2274 return 0; 2275 } 2276 2277 /** 2278 * ice_rss_config_xor_word - set the HSYMM registers for one input set word 2279 * @hw: pointer to the hardware structure 2280 * @prof_id: RSS hardware profile id 2281 * @src: the FV index used by the protocol's source field 2282 * @dst: the FV index used by the protocol's destination field 2283 * 2284 * Write to the HSYMM register with the index of @src FV the value of the @dst 2285 * FV index. This will tell the hardware to XOR HSYMM[src] with INSET[dst] 2286 * while calculating the RSS input set. 2287 */ 2288 static void 2289 ice_rss_config_xor_word(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst) 2290 { 2291 u32 val, reg, bits_shift; 2292 u8 reg_idx; 2293 2294 reg_idx = src / GLQF_HSYMM_REG_SIZE; 2295 bits_shift = ((src % GLQF_HSYMM_REG_SIZE) << 3); 2296 val = dst | GLQF_HSYMM_ENABLE_BIT; 2297 2298 reg = rd32(hw, GLQF_HSYMM(prof_id, reg_idx)); 2299 reg = (reg & ~(0xff << bits_shift)) | (val << bits_shift); 2300 wr32(hw, GLQF_HSYMM(prof_id, reg_idx), reg); 2301 } 2302 2303 /** 2304 * ice_rss_config_xor - set the symmetric registers for a profile's protocol 2305 * @hw: pointer to the hardware structure 2306 * @prof_id: RSS hardware profile id 2307 * @src: the FV index used by the protocol's source field 2308 * @dst: the FV index used by the protocol's destination field 2309 * @len: length of the source/destination fields in words 2310 */ 2311 static void 2312 ice_rss_config_xor(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst, u8 len) 2313 { 2314 int fv_last_word = 2315 ICE_FLOW_SW_FIELD_VECTOR_MAX / ICE_FLOW_FV_EXTRACT_SZ - 1; 2316 int i; 2317 2318 for (i = 0; i < len; i++) { 2319 ice_rss_config_xor_word(hw, prof_id, 2320 /* Yes, field vector in GLQF_HSYMM and 2321 * GLQF_HINSET is inversed! 2322 */ 2323 fv_last_word - (src + i), 2324 fv_last_word - (dst + i)); 2325 ice_rss_config_xor_word(hw, prof_id, 2326 fv_last_word - (dst + i), 2327 fv_last_word - (src + i)); 2328 } 2329 } 2330 2331 /** 2332 * ice_rss_set_symm - set the symmetric settings for an RSS profile 2333 * @hw: pointer to the hardware structure 2334 * @prof: pointer to flow profile 2335 * 2336 * The symmetric hash will result from XORing the protocol's fields with 2337 * indexes in GLQF_HSYMM and GLQF_HINSET. This function configures the profile's 2338 * GLQF_HSYMM registers. 2339 */ 2340 static void ice_rss_set_symm(struct ice_hw *hw, struct ice_flow_prof *prof) 2341 { 2342 struct ice_prof_map *map; 2343 u8 prof_id, m; 2344 2345 mutex_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock); 2346 map = ice_search_prof_id(hw, ICE_BLK_RSS, prof->id); 2347 if (map) 2348 prof_id = map->prof_id; 2349 mutex_unlock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock); 2350 2351 if (!map) 2352 return; 2353 2354 /* clear to default */ 2355 for (m = 0; m < GLQF_HSYMM_REG_PER_PROF; m++) 2356 wr32(hw, GLQF_HSYMM(prof_id, m), 0); 2357 2358 if (prof->symm) { 2359 struct ice_flow_seg_xtrct *ipv4_src, *ipv4_dst; 2360 struct ice_flow_seg_xtrct *ipv6_src, *ipv6_dst; 2361 struct ice_flow_seg_xtrct *sctp_src, *sctp_dst; 2362 struct ice_flow_seg_xtrct *tcp_src, *tcp_dst; 2363 struct ice_flow_seg_xtrct *udp_src, *udp_dst; 2364 struct ice_flow_seg_info *seg; 2365 2366 seg = &prof->segs[prof->segs_cnt - 1]; 2367 2368 ipv4_src = &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_SA].xtrct; 2369 ipv4_dst = &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_DA].xtrct; 2370 2371 ipv6_src = &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_SA].xtrct; 2372 ipv6_dst = &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_DA].xtrct; 2373 2374 tcp_src = &seg->fields[ICE_FLOW_FIELD_IDX_TCP_SRC_PORT].xtrct; 2375 tcp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_TCP_DST_PORT].xtrct; 2376 2377 udp_src = &seg->fields[ICE_FLOW_FIELD_IDX_UDP_SRC_PORT].xtrct; 2378 udp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_UDP_DST_PORT].xtrct; 2379 2380 sctp_src = &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT].xtrct; 2381 sctp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_DST_PORT].xtrct; 2382 2383 /* xor IPv4 */ 2384 if (ipv4_src->prot_id != 0 && ipv4_dst->prot_id != 0) 2385 ice_rss_config_xor(hw, prof_id, 2386 ipv4_src->idx, ipv4_dst->idx, 2); 2387 2388 /* xor IPv6 */ 2389 if (ipv6_src->prot_id != 0 && ipv6_dst->prot_id != 0) 2390 ice_rss_config_xor(hw, prof_id, 2391 ipv6_src->idx, ipv6_dst->idx, 8); 2392 2393 /* xor TCP */ 2394 if (tcp_src->prot_id != 0 && tcp_dst->prot_id != 0) 2395 ice_rss_config_xor(hw, prof_id, 2396 tcp_src->idx, tcp_dst->idx, 1); 2397 2398 /* xor UDP */ 2399 if (udp_src->prot_id != 0 && udp_dst->prot_id != 0) 2400 ice_rss_config_xor(hw, prof_id, 2401 udp_src->idx, udp_dst->idx, 1); 2402 2403 /* xor SCTP */ 2404 if (sctp_src->prot_id != 0 && sctp_dst->prot_id != 0) 2405 ice_rss_config_xor(hw, prof_id, 2406 sctp_src->idx, sctp_dst->idx, 1); 2407 } 2408 } 2409 2410 /** 2411 * ice_rss_cfg_raw_symm - Configure symmetric RSS for a raw parser profile 2412 * @hw: device HW 2413 * @prof: parser profile describing extracted FV (field vector) entries 2414 * @prof_id: RSS profile identifier used to program symmetry registers 2415 * 2416 * The routine scans the parser profile's FV entries and looks for 2417 * direction-sensitive pairs (L3 src/dst, L4 src/dst). When a pair is found, 2418 * it programs XOR-based symmetry so that flows hash identically regardless 2419 * of packet direction. This preserves CPU affinity for the same 5-tuple. 2420 * 2421 * Notes: 2422 * - The size of each logical field (IPv4/IPv6 address, L4 port) is expressed 2423 * in units of ICE_FLOW_FV_EXTRACT_SZ so we can step across fv[] correctly. 2424 * - We guard against out-of-bounds access before looking at fv[i + len]. 2425 */ 2426 static void ice_rss_cfg_raw_symm(struct ice_hw *hw, 2427 const struct ice_parser_profile *prof, 2428 u64 prof_id) 2429 { 2430 for (size_t i = 0; i < prof->fv_num; i++) { 2431 u8 proto_id = prof->fv[i].proto_id; 2432 u16 src_off = 0, dst_off = 0; 2433 size_t src_idx, dst_idx; 2434 bool is_matched = false; 2435 unsigned int len = 0; 2436 2437 switch (proto_id) { 2438 /* IPv4 address pairs (outer/inner variants) */ 2439 case ICE_PROT_IPV4_OF_OR_S: 2440 case ICE_PROT_IPV4_IL: 2441 case ICE_PROT_IPV4_IL_IL: 2442 len = ICE_FLOW_FLD_SZ_IPV4_ADDR / 2443 ICE_FLOW_FV_EXTRACT_SZ; 2444 src_off = ICE_FLOW_FIELD_IPV4_SRC_OFFSET; 2445 dst_off = ICE_FLOW_FIELD_IPV4_DST_OFFSET; 2446 break; 2447 2448 /* IPv6 address pairs (outer/inner variants) */ 2449 case ICE_PROT_IPV6_OF_OR_S: 2450 case ICE_PROT_IPV6_IL: 2451 case ICE_PROT_IPV6_IL_IL: 2452 len = ICE_FLOW_FLD_SZ_IPV6_ADDR / 2453 ICE_FLOW_FV_EXTRACT_SZ; 2454 src_off = ICE_FLOW_FIELD_IPV6_SRC_OFFSET; 2455 dst_off = ICE_FLOW_FIELD_IPV6_DST_OFFSET; 2456 break; 2457 2458 /* L4 port pairs (TCP/UDP/SCTP) */ 2459 case ICE_PROT_TCP_IL: 2460 case ICE_PROT_UDP_IL_OR_S: 2461 case ICE_PROT_SCTP_IL: 2462 len = ICE_FLOW_FLD_SZ_PORT / ICE_FLOW_FV_EXTRACT_SZ; 2463 src_off = ICE_FLOW_FIELD_SRC_PORT_OFFSET; 2464 dst_off = ICE_FLOW_FIELD_DST_PORT_OFFSET; 2465 break; 2466 2467 default: 2468 continue; 2469 } 2470 2471 /* Bounds check before accessing fv[i + len]. */ 2472 if (i + len >= prof->fv_num) 2473 continue; 2474 2475 /* Verify src/dst pairing for this protocol id. */ 2476 is_matched = prof->fv[i].offset == src_off && 2477 prof->fv[i + len].proto_id == proto_id && 2478 prof->fv[i + len].offset == dst_off; 2479 if (!is_matched) 2480 continue; 2481 2482 /* Program XOR symmetry for this field pair. */ 2483 src_idx = i; 2484 dst_idx = i + len; 2485 2486 ice_rss_config_xor(hw, prof_id, src_idx, dst_idx, len); 2487 2488 /* Skip over the pair we just handled; the loop's ++i advances 2489 * one more element, hence the --i after the jump. 2490 */ 2491 i += (2 * len); 2492 /* not strictly needed; keeps static analyzers happy */ 2493 if (i == 0) 2494 break; 2495 --i; 2496 } 2497 } 2498 2499 /* Max registers index per packet profile */ 2500 #define ICE_SYMM_REG_INDEX_MAX 6 2501 2502 /** 2503 * ice_rss_update_raw_symm - update symmetric hash configuration 2504 * for raw pattern 2505 * @hw: pointer to the hardware structure 2506 * @cfg: configure parameters for raw pattern 2507 * @id: profile tracking ID 2508 * 2509 * Update symmetric hash configuration for raw pattern if required. 2510 * Otherwise only clear to default. 2511 */ 2512 void 2513 ice_rss_update_raw_symm(struct ice_hw *hw, 2514 struct ice_rss_raw_cfg *cfg, u64 id) 2515 { 2516 struct ice_prof_map *map; 2517 u8 prof_id, m; 2518 2519 mutex_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock); 2520 map = ice_search_prof_id(hw, ICE_BLK_RSS, id); 2521 if (map) 2522 prof_id = map->prof_id; 2523 mutex_unlock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock); 2524 if (!map) 2525 return; 2526 /* clear to default */ 2527 for (m = 0; m < ICE_SYMM_REG_INDEX_MAX; m++) 2528 wr32(hw, GLQF_HSYMM(prof_id, m), 0); 2529 2530 if (cfg->symm) 2531 ice_rss_cfg_raw_symm(hw, &cfg->prof, prof_id); 2532 } 2533 2534 /** 2535 * ice_add_rss_cfg_sync - add an RSS configuration 2536 * @hw: pointer to the hardware structure 2537 * @vsi_handle: software VSI handle 2538 * @cfg: configure parameters 2539 * 2540 * Assumption: lock has already been acquired for RSS list 2541 */ 2542 static int 2543 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, 2544 const struct ice_rss_hash_cfg *cfg) 2545 { 2546 const enum ice_block blk = ICE_BLK_RSS; 2547 struct ice_flow_prof *prof = NULL; 2548 struct ice_flow_seg_info *segs; 2549 u8 segs_cnt; 2550 int status; 2551 2552 segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ? 2553 ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX; 2554 2555 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL); 2556 if (!segs) 2557 return -ENOMEM; 2558 2559 /* Construct the packet segment info from the hashed fields */ 2560 status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg); 2561 if (status) 2562 goto exit; 2563 2564 /* Search for a flow profile that has matching headers, hash fields, 2565 * symm and has the input VSI associated to it. If found, no further 2566 * operations required and exit. 2567 */ 2568 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2569 cfg->symm, vsi_handle, 2570 ICE_FLOW_FIND_PROF_CHK_FLDS | 2571 ICE_FLOW_FIND_PROF_CHK_SYMM | 2572 ICE_FLOW_FIND_PROF_CHK_VSI); 2573 if (prof) 2574 goto exit; 2575 2576 /* Check if a flow profile exists with the same protocol headers and 2577 * associated with the input VSI. If so disassociate the VSI from 2578 * this profile. The VSI will be added to a new profile created with 2579 * the protocol header and new hash field configuration. 2580 */ 2581 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2582 cfg->symm, vsi_handle, 2583 ICE_FLOW_FIND_PROF_CHK_VSI); 2584 if (prof) { 2585 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle); 2586 if (!status) 2587 ice_rem_rss_list(hw, vsi_handle, prof); 2588 else 2589 goto exit; 2590 2591 /* Remove profile if it has no VSIs associated */ 2592 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) { 2593 status = ice_flow_rem_prof(hw, blk, prof->id); 2594 if (status) 2595 goto exit; 2596 } 2597 } 2598 2599 /* Search for a profile that has the same match fields and symmetric 2600 * setting. If this exists then associate the VSI to this profile. 2601 */ 2602 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2603 cfg->symm, vsi_handle, 2604 ICE_FLOW_FIND_PROF_CHK_SYMM | 2605 ICE_FLOW_FIND_PROF_CHK_FLDS); 2606 if (prof) { 2607 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle); 2608 if (!status) 2609 status = ice_add_rss_list(hw, vsi_handle, prof); 2610 goto exit; 2611 } 2612 2613 /* Create a new flow profile with packet segment information. */ 2614 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX, 2615 segs, segs_cnt, cfg->symm, &prof); 2616 if (status) 2617 goto exit; 2618 2619 prof->symm = cfg->symm; 2620 ice_rss_set_symm(hw, prof); 2621 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle); 2622 /* If association to a new flow profile failed then this profile can 2623 * be removed. 2624 */ 2625 if (status) { 2626 ice_flow_rem_prof(hw, blk, prof->id); 2627 goto exit; 2628 } 2629 2630 status = ice_add_rss_list(hw, vsi_handle, prof); 2631 2632 exit: 2633 kfree(segs); 2634 return status; 2635 } 2636 2637 /** 2638 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields 2639 * @hw: pointer to the hardware structure 2640 * @vsi: VSI to add the RSS configuration to 2641 * @cfg: configure parameters 2642 * 2643 * This function will generate a flow profile based on fields associated with 2644 * the input fields to hash on, the flow type and use the VSI number to add 2645 * a flow entry to the profile. 2646 */ 2647 int 2648 ice_add_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi, 2649 const struct ice_rss_hash_cfg *cfg) 2650 { 2651 struct ice_rss_hash_cfg local_cfg; 2652 u16 vsi_handle; 2653 int status; 2654 2655 if (!vsi) 2656 return -EINVAL; 2657 2658 vsi_handle = vsi->idx; 2659 if (!ice_is_vsi_valid(hw, vsi_handle) || 2660 !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS || 2661 cfg->hash_flds == ICE_HASH_INVALID) 2662 return -EINVAL; 2663 2664 mutex_lock(&hw->rss_locks); 2665 local_cfg = *cfg; 2666 if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) { 2667 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg); 2668 } else { 2669 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS; 2670 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg); 2671 if (!status) { 2672 local_cfg.hdr_type = ICE_RSS_INNER_HEADERS; 2673 status = ice_add_rss_cfg_sync(hw, vsi_handle, 2674 &local_cfg); 2675 } 2676 } 2677 mutex_unlock(&hw->rss_locks); 2678 2679 return status; 2680 } 2681 2682 /** 2683 * ice_rem_rss_cfg_sync - remove an existing RSS configuration 2684 * @hw: pointer to the hardware structure 2685 * @vsi_handle: software VSI handle 2686 * @cfg: configure parameters 2687 * 2688 * Assumption: lock has already been acquired for RSS list 2689 */ 2690 static int 2691 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, 2692 const struct ice_rss_hash_cfg *cfg) 2693 { 2694 const enum ice_block blk = ICE_BLK_RSS; 2695 struct ice_flow_seg_info *segs; 2696 struct ice_flow_prof *prof; 2697 u8 segs_cnt; 2698 int status; 2699 2700 segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ? 2701 ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX; 2702 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL); 2703 if (!segs) 2704 return -ENOMEM; 2705 2706 /* Construct the packet segment info from the hashed fields */ 2707 status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg); 2708 if (status) 2709 goto out; 2710 2711 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2712 cfg->symm, vsi_handle, 2713 ICE_FLOW_FIND_PROF_CHK_FLDS); 2714 if (!prof) { 2715 status = -ENOENT; 2716 goto out; 2717 } 2718 2719 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle); 2720 if (status) 2721 goto out; 2722 2723 /* Remove RSS configuration from VSI context before deleting 2724 * the flow profile. 2725 */ 2726 ice_rem_rss_list(hw, vsi_handle, prof); 2727 2728 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) 2729 status = ice_flow_rem_prof(hw, blk, prof->id); 2730 2731 out: 2732 kfree(segs); 2733 return status; 2734 } 2735 2736 /** 2737 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields 2738 * @hw: pointer to the hardware structure 2739 * @vsi_handle: software VSI handle 2740 * @cfg: configure parameters 2741 * 2742 * This function will lookup the flow profile based on the input 2743 * hash field bitmap, iterate through the profile entry list of 2744 * that profile and find entry associated with input VSI to be 2745 * removed. Calls are made to underlying flow apis which will in 2746 * turn build or update buffers for RSS XLT1 section. 2747 */ 2748 int 2749 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, 2750 const struct ice_rss_hash_cfg *cfg) 2751 { 2752 struct ice_rss_hash_cfg local_cfg; 2753 int status; 2754 2755 if (!ice_is_vsi_valid(hw, vsi_handle) || 2756 !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS || 2757 cfg->hash_flds == ICE_HASH_INVALID) 2758 return -EINVAL; 2759 2760 mutex_lock(&hw->rss_locks); 2761 local_cfg = *cfg; 2762 if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) { 2763 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg); 2764 } else { 2765 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS; 2766 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg); 2767 if (!status) { 2768 local_cfg.hdr_type = ICE_RSS_INNER_HEADERS; 2769 status = ice_rem_rss_cfg_sync(hw, vsi_handle, 2770 &local_cfg); 2771 } 2772 } 2773 mutex_unlock(&hw->rss_locks); 2774 2775 return status; 2776 } 2777 2778 /* Mapping of AVF hash bit fields to an L3-L4 hash combination. 2779 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash, 2780 * convert its values to their appropriate flow L3, L4 values. 2781 */ 2782 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \ 2783 (BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_OTHER) | \ 2784 BIT_ULL(LIBIE_FILTER_PCTYPE_FRAG_IPV4)) 2785 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \ 2786 (BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK) | \ 2787 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_TCP)) 2788 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \ 2789 (BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | \ 2790 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) | \ 2791 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_UDP)) 2792 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \ 2793 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \ 2794 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_SCTP)) 2795 2796 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \ 2797 (BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_OTHER) | \ 2798 BIT_ULL(LIBIE_FILTER_PCTYPE_FRAG_IPV6)) 2799 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \ 2800 (BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | \ 2801 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) | \ 2802 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_UDP)) 2803 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \ 2804 (BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK) | \ 2805 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_TCP)) 2806 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \ 2807 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \ 2808 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_SCTP)) 2809 2810 /** 2811 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver 2812 * @hw: pointer to the hardware structure 2813 * @vsi: VF's VSI 2814 * @avf_hash: hash bit fields (LIBIE_FILTER_PCTYPE_*) to configure 2815 * 2816 * This function will take the hash bitmap provided by the AVF driver via a 2817 * message, convert it to ICE-compatible values, and configure RSS flow 2818 * profiles. 2819 */ 2820 int ice_add_avf_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi, u64 avf_hash) 2821 { 2822 struct ice_rss_hash_cfg hcfg; 2823 u16 vsi_handle; 2824 int status = 0; 2825 u64 hash_flds; 2826 2827 if (!vsi) 2828 return -EINVAL; 2829 2830 vsi_handle = vsi->idx; 2831 if (!avf_hash || !ice_is_vsi_valid(hw, vsi_handle)) 2832 return -EINVAL; 2833 2834 /* Make sure no unsupported bits are specified */ 2835 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS | 2836 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)) 2837 return -EIO; 2838 2839 hash_flds = avf_hash; 2840 2841 /* Always create an L3 RSS configuration for any L4 RSS configuration */ 2842 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) 2843 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS; 2844 2845 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) 2846 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS; 2847 2848 /* Create the corresponding RSS configuration for each valid hash bit */ 2849 while (hash_flds) { 2850 u64 rss_hash = ICE_HASH_INVALID; 2851 2852 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) { 2853 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) { 2854 rss_hash = ICE_FLOW_HASH_IPV4; 2855 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS; 2856 } else if (hash_flds & 2857 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) { 2858 rss_hash = ICE_FLOW_HASH_IPV4 | 2859 ICE_FLOW_HASH_TCP_PORT; 2860 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS; 2861 } else if (hash_flds & 2862 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) { 2863 rss_hash = ICE_FLOW_HASH_IPV4 | 2864 ICE_FLOW_HASH_UDP_PORT; 2865 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS; 2866 } else if (hash_flds & 2867 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_SCTP)) { 2868 rss_hash = ICE_FLOW_HASH_IPV4 | 2869 ICE_FLOW_HASH_SCTP_PORT; 2870 hash_flds &= 2871 ~BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV4_SCTP); 2872 } 2873 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) { 2874 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) { 2875 rss_hash = ICE_FLOW_HASH_IPV6; 2876 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS; 2877 } else if (hash_flds & 2878 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) { 2879 rss_hash = ICE_FLOW_HASH_IPV6 | 2880 ICE_FLOW_HASH_TCP_PORT; 2881 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS; 2882 } else if (hash_flds & 2883 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) { 2884 rss_hash = ICE_FLOW_HASH_IPV6 | 2885 ICE_FLOW_HASH_UDP_PORT; 2886 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS; 2887 } else if (hash_flds & 2888 BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_SCTP)) { 2889 rss_hash = ICE_FLOW_HASH_IPV6 | 2890 ICE_FLOW_HASH_SCTP_PORT; 2891 hash_flds &= 2892 ~BIT_ULL(LIBIE_FILTER_PCTYPE_NONF_IPV6_SCTP); 2893 } 2894 } 2895 2896 if (rss_hash == ICE_HASH_INVALID) 2897 return -EIO; 2898 2899 hcfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE; 2900 hcfg.hash_flds = rss_hash; 2901 hcfg.hdr_type = ICE_RSS_ANY_HEADERS; 2902 hcfg.symm = false; 2903 status = ice_add_rss_cfg(hw, vsi, &hcfg); 2904 if (status) 2905 break; 2906 } 2907 2908 return status; 2909 } 2910 2911 static bool rss_cfg_symm_valid(u64 hfld) 2912 { 2913 return !((!!(hfld & ICE_FLOW_HASH_FLD_IPV4_SA) ^ 2914 !!(hfld & ICE_FLOW_HASH_FLD_IPV4_DA)) || 2915 (!!(hfld & ICE_FLOW_HASH_FLD_IPV6_SA) ^ 2916 !!(hfld & ICE_FLOW_HASH_FLD_IPV6_DA)) || 2917 (!!(hfld & ICE_FLOW_HASH_FLD_TCP_SRC_PORT) ^ 2918 !!(hfld & ICE_FLOW_HASH_FLD_TCP_DST_PORT)) || 2919 (!!(hfld & ICE_FLOW_HASH_FLD_UDP_SRC_PORT) ^ 2920 !!(hfld & ICE_FLOW_HASH_FLD_UDP_DST_PORT)) || 2921 (!!(hfld & ICE_FLOW_HASH_FLD_SCTP_SRC_PORT) ^ 2922 !!(hfld & ICE_FLOW_HASH_FLD_SCTP_DST_PORT))); 2923 } 2924 2925 /** 2926 * ice_set_rss_cfg_symm - set symmtery for all VSI's RSS configurations 2927 * @hw: pointer to the hardware structure 2928 * @vsi: VSI to set/unset Symmetric RSS 2929 * @symm: TRUE to set Symmetric RSS hashing 2930 */ 2931 int ice_set_rss_cfg_symm(struct ice_hw *hw, struct ice_vsi *vsi, bool symm) 2932 { 2933 struct ice_rss_hash_cfg local; 2934 struct ice_rss_cfg *r, *tmp; 2935 u16 vsi_handle = vsi->idx; 2936 int status = 0; 2937 2938 if (!ice_is_vsi_valid(hw, vsi_handle)) 2939 return -EINVAL; 2940 2941 mutex_lock(&hw->rss_locks); 2942 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry) { 2943 if (test_bit(vsi_handle, r->vsis) && r->hash.symm != symm) { 2944 local = r->hash; 2945 local.symm = symm; 2946 if (symm && !rss_cfg_symm_valid(r->hash.hash_flds)) 2947 continue; 2948 2949 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local); 2950 if (status) 2951 break; 2952 } 2953 } 2954 mutex_unlock(&hw->rss_locks); 2955 2956 return status; 2957 } 2958 2959 /** 2960 * ice_replay_rss_cfg - replay RSS configurations associated with VSI 2961 * @hw: pointer to the hardware structure 2962 * @vsi_handle: software VSI handle 2963 */ 2964 int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle) 2965 { 2966 struct ice_rss_cfg *r; 2967 int status = 0; 2968 2969 if (!ice_is_vsi_valid(hw, vsi_handle)) 2970 return -EINVAL; 2971 2972 mutex_lock(&hw->rss_locks); 2973 list_for_each_entry(r, &hw->rss_list_head, l_entry) { 2974 if (test_bit(vsi_handle, r->vsis)) { 2975 status = ice_add_rss_cfg_sync(hw, vsi_handle, &r->hash); 2976 if (status) 2977 break; 2978 } 2979 } 2980 mutex_unlock(&hw->rss_locks); 2981 2982 return status; 2983 } 2984 2985 /** 2986 * ice_get_rss_cfg - returns hashed fields for the given header types 2987 * @hw: pointer to the hardware structure 2988 * @vsi_handle: software VSI handle 2989 * @hdrs: protocol header type 2990 * @symm: whether the RSS is symmetric (bool, output) 2991 * 2992 * This function will return the match fields of the first instance of flow 2993 * profile having the given header types and containing input VSI 2994 */ 2995 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs, bool *symm) 2996 { 2997 u64 rss_hash = ICE_HASH_INVALID; 2998 struct ice_rss_cfg *r; 2999 3000 /* verify if the protocol header is non zero and VSI is valid */ 3001 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle)) 3002 return ICE_HASH_INVALID; 3003 3004 mutex_lock(&hw->rss_locks); 3005 list_for_each_entry(r, &hw->rss_list_head, l_entry) 3006 if (test_bit(vsi_handle, r->vsis) && 3007 r->hash.addl_hdrs == hdrs) { 3008 rss_hash = r->hash.hash_flds; 3009 *symm = r->hash.symm; 3010 break; 3011 } 3012 mutex_unlock(&hw->rss_locks); 3013 3014 return rss_hash; 3015 } 3016