0001
0002
0003
0004 #include "ice_common.h"
0005 #include "ice_flow.h"
0006 #include <net/gre.h>
0007
0008
0009 struct ice_flow_field_info {
0010 enum ice_flow_seg_hdr hdr;
0011 s16 off;
0012 u16 size;
0013 u16 mask;
0014 };
0015
0016 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
0017 .hdr = _hdr, \
0018 .off = (_offset_bytes) * BITS_PER_BYTE, \
0019 .size = (_size_bytes) * BITS_PER_BYTE, \
0020 .mask = 0, \
0021 }
0022
0023 #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
0024 .hdr = _hdr, \
0025 .off = (_offset_bytes) * BITS_PER_BYTE, \
0026 .size = (_size_bytes) * BITS_PER_BYTE, \
0027 .mask = _mask, \
0028 }
0029
0030
0031 static const
0032 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
0033
0034
0035 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
0036
0037 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
0038
0039 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, sizeof(__be16)),
0040
0041 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, sizeof(__be16)),
0042
0043 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, sizeof(__be16)),
0044
0045
0046 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, 1, 0x00fc),
0047
0048 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, 1, 0x0ff0),
0049
0050 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0xff00),
0051
0052 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0x00ff),
0053
0054 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0x00ff),
0055
0056 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0xff00),
0057
0058 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)),
0059
0060 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)),
0061
0062 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)),
0063
0064 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)),
0065
0066
0067 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)),
0068
0069 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)),
0070
0071 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)),
0072
0073 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)),
0074
0075 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, sizeof(__be16)),
0076
0077 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)),
0078
0079 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, 1),
0080
0081
0082 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)),
0083
0084 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, sizeof(struct in_addr)),
0085
0086 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
0087
0088 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
0089
0090 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, sizeof(__be16)),
0091
0092
0093 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, 1),
0094
0095 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, 1),
0096
0097
0098 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12,
0099 sizeof_field(struct gre_full_hdr, key)),
0100
0101
0102 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12, sizeof(__be32)),
0103
0104 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12, sizeof(__be32)),
0105
0106 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12, sizeof(__be32)),
0107
0108 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16),
0109 0x3f00),
0110
0111 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, sizeof(__be32)),
0112
0113 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, sizeof(__be32)),
0114
0115
0116 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
0117
0118
0119 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)),
0120
0121
0122 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)),
0123
0124
0125 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)),
0126
0127
0128 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
0129
0130
0131 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
0132 };
0133
0134
0135
0136
0137
0138 static const u32 ice_ptypes_mac_ofos[] = {
0139 0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
0140 0x0000077E, 0x00000000, 0x00000000, 0x00000000,
0141 0x00400000, 0x03FFF000, 0x7FFFFFE0, 0x00000000,
0142 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0143 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0144 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0145 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0146 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0147 };
0148
0149
0150 static const u32 ice_ptypes_macvlan_il[] = {
0151 0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
0152 0x0000077E, 0x00000000, 0x00000000, 0x00000000,
0153 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0154 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0155 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0156 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0157 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0158 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0159 };
0160
0161
0162
0163
0164 static const u32 ice_ptypes_ipv4_ofos[] = {
0165 0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
0166 0x00000000, 0x00000155, 0x00000000, 0x00000000,
0167 0x00000000, 0x000FC000, 0x00000000, 0x00000000,
0168 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0169 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0170 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0171 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0172 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0173 };
0174
0175
0176
0177
0178 static const u32 ice_ptypes_ipv4_ofos_all[] = {
0179 0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
0180 0x00000000, 0x00000155, 0x00000000, 0x00000000,
0181 0x00000000, 0x000FC000, 0x83E0F800, 0x00000101,
0182 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0183 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0184 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0185 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0186 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0187 };
0188
0189
0190 static const u32 ice_ptypes_ipv4_il[] = {
0191 0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
0192 0x0000000E, 0x00000000, 0x00000000, 0x00000000,
0193 0x00000000, 0x00000000, 0x001FF800, 0x00000000,
0194 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0195 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0196 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0197 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0198 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0199 };
0200
0201
0202
0203
0204 static const u32 ice_ptypes_ipv6_ofos[] = {
0205 0x00000000, 0x00000000, 0x77000000, 0x10002000,
0206 0x00000000, 0x000002AA, 0x00000000, 0x00000000,
0207 0x00000000, 0x03F00000, 0x00000000, 0x00000000,
0208 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0209 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0210 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0211 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0212 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0213 };
0214
0215
0216
0217
0218 static const u32 ice_ptypes_ipv6_ofos_all[] = {
0219 0x00000000, 0x00000000, 0x77000000, 0x10002000,
0220 0x00000000, 0x000002AA, 0x00000000, 0x00000000,
0221 0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206,
0222 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0223 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0224 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0225 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0226 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0227 };
0228
0229
0230 static const u32 ice_ptypes_ipv6_il[] = {
0231 0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
0232 0x00000770, 0x00000000, 0x00000000, 0x00000000,
0233 0x00000000, 0x00000000, 0x7FE00000, 0x00000000,
0234 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0235 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0236 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0237 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0238 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0239 };
0240
0241
0242 static const u32 ice_ptypes_ipv4_ofos_no_l4[] = {
0243 0x10C00000, 0x04000800, 0x00000000, 0x00000000,
0244 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0245 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0246 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0247 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0248 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0249 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0250 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0251 };
0252
0253
0254 static const u32 ice_ptypes_arp_of[] = {
0255 0x00000800, 0x00000000, 0x00000000, 0x00000000,
0256 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0257 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0258 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0259 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0260 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0261 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0262 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0263 };
0264
0265
0266 static const u32 ice_ptypes_ipv4_il_no_l4[] = {
0267 0x60000000, 0x18043008, 0x80000002, 0x6010c021,
0268 0x00000008, 0x00000000, 0x00000000, 0x00000000,
0269 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0270 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0271 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0272 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0273 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0274 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0275 };
0276
0277
0278 static const u32 ice_ptypes_ipv6_ofos_no_l4[] = {
0279 0x00000000, 0x00000000, 0x43000000, 0x10002000,
0280 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0281 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0282 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0283 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0284 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0285 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0286 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0287 };
0288
0289
0290 static const u32 ice_ptypes_ipv6_il_no_l4[] = {
0291 0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
0292 0x00000430, 0x00000000, 0x00000000, 0x00000000,
0293 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0294 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0295 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0296 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0297 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0298 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0299 };
0300
0301
0302
0303
0304 static const u32 ice_ptypes_udp_il[] = {
0305 0x81000000, 0x20204040, 0x04000010, 0x80810102,
0306 0x00000040, 0x00000000, 0x00000000, 0x00000000,
0307 0x00000000, 0x00410000, 0x90842000, 0x00000007,
0308 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0309 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0310 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0311 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0312 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0313 };
0314
0315
0316 static const u32 ice_ptypes_tcp_il[] = {
0317 0x04000000, 0x80810102, 0x10000040, 0x02040408,
0318 0x00000102, 0x00000000, 0x00000000, 0x00000000,
0319 0x00000000, 0x00820000, 0x21084000, 0x00000000,
0320 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0321 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0322 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0323 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0324 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0325 };
0326
0327
0328 static const u32 ice_ptypes_sctp_il[] = {
0329 0x08000000, 0x01020204, 0x20000081, 0x04080810,
0330 0x00000204, 0x00000000, 0x00000000, 0x00000000,
0331 0x00000000, 0x01040000, 0x00000000, 0x00000000,
0332 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0333 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0334 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0335 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0336 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0337 };
0338
0339
0340 static const u32 ice_ptypes_icmp_of[] = {
0341 0x10000000, 0x00000000, 0x00000000, 0x00000000,
0342 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0343 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0344 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0345 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0346 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0347 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0348 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0349 };
0350
0351
0352 static const u32 ice_ptypes_icmp_il[] = {
0353 0x00000000, 0x02040408, 0x40000102, 0x08101020,
0354 0x00000408, 0x00000000, 0x00000000, 0x00000000,
0355 0x00000000, 0x00000000, 0x42108000, 0x00000000,
0356 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0357 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0358 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0359 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0360 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0361 };
0362
0363
0364 static const u32 ice_ptypes_gre_of[] = {
0365 0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
0366 0x0000017E, 0x00000000, 0x00000000, 0x00000000,
0367 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0368 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0369 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0370 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0371 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0372 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0373 };
0374
0375
0376 static const u32 ice_ptypes_mac_il[] = {
0377 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0378 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0379 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0380 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0381 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0382 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0383 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0384 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0385 };
0386
0387
0388 static const u32 ice_ptypes_gtpc[] = {
0389 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0390 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0391 0x00000000, 0x00000000, 0x00000180, 0x00000000,
0392 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0393 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0394 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0395 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0396 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0397 };
0398
0399
0400 static const u32 ice_ptypes_gtpc_tid[] = {
0401 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0402 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0403 0x00000000, 0x00000000, 0x00000060, 0x00000000,
0404 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0405 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0406 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0407 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0408 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0409 };
0410
0411
0412 static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
0413 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
0414 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
0415 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
0416 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
0417 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
0418 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
0419 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
0420 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
0421 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
0422 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
0423 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
0424 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
0425 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
0426 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
0427 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
0428 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
0429 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
0430 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
0431 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
0432 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
0433 };
0434
0435 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
0436 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0437 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0438 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0439 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0440 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0441 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0442 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0443 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0444 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0445 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0446 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0447 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0448 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0449 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0450 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0451 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0452 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0453 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0454 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0455 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
0456 };
0457
0458 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
0459 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
0460 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
0461 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
0462 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
0463 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
0464 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
0465 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
0466 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
0467 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
0468 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
0469 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
0470 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
0471 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
0472 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
0473 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
0474 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
0475 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
0476 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
0477 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
0478 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
0479 };
0480
0481 static const u32 ice_ptypes_gtpu[] = {
0482 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0483 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0484 0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
0485 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0486 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0487 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0488 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0489 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0490 };
0491
0492
0493 static const u32 ice_ptypes_pppoe[] = {
0494 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0495 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0496 0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
0497 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0498 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0499 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0500 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0501 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0502 };
0503
0504
0505 static const u32 ice_ptypes_pfcp_node[] = {
0506 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0507 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0508 0x00000000, 0x00000000, 0x80000000, 0x00000002,
0509 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0510 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0511 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0512 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0513 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0514 };
0515
0516
0517 static const u32 ice_ptypes_pfcp_session[] = {
0518 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0519 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0520 0x00000000, 0x00000000, 0x00000000, 0x00000005,
0521 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0522 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0523 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0524 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0525 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0526 };
0527
0528
0529 static const u32 ice_ptypes_l2tpv3[] = {
0530 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0531 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0532 0x00000000, 0x00000000, 0x00000000, 0x00000300,
0533 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0534 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0535 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0536 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0537 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0538 };
0539
0540
0541 static const u32 ice_ptypes_esp[] = {
0542 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0543 0x00000000, 0x00000003, 0x00000000, 0x00000000,
0544 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0545 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0546 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0547 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0548 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0549 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0550 };
0551
0552
0553 static const u32 ice_ptypes_ah[] = {
0554 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0555 0x00000000, 0x0000000C, 0x00000000, 0x00000000,
0556 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0557 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0558 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0559 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0560 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0561 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0562 };
0563
0564
0565 static const u32 ice_ptypes_nat_t_esp[] = {
0566 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0567 0x00000000, 0x00000030, 0x00000000, 0x00000000,
0568 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0569 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0570 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0571 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0572 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0573 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0574 };
0575
0576 static const u32 ice_ptypes_mac_non_ip_ofos[] = {
0577 0x00000846, 0x00000000, 0x00000000, 0x00000000,
0578 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0579 0x00400000, 0x03FFF000, 0x00000000, 0x00000000,
0580 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0581 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0582 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0583 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0584 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0585 };
0586
0587
0588 struct ice_flow_prof_params {
0589 enum ice_block blk;
0590 u16 entry_length;
0591 u8 es_cnt;
0592 struct ice_flow_prof *prof;
0593
0594
0595
0596
0597 struct ice_fv_word es[ICE_MAX_FV_WORDS];
0598
0599 const struct ice_ptype_attributes *attr;
0600 u16 attr_cnt;
0601
0602 u16 mask[ICE_MAX_FV_WORDS];
0603 DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
0604 };
0605
0606 #define ICE_FLOW_RSS_HDRS_INNER_MASK \
0607 (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
0608 ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
0609 ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
0610 ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
0611 ICE_FLOW_SEG_HDR_NAT_T_ESP)
0612
0613 #define ICE_FLOW_SEG_HDRS_L3_MASK \
0614 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
0615 #define ICE_FLOW_SEG_HDRS_L4_MASK \
0616 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
0617 ICE_FLOW_SEG_HDR_SCTP)
0618
0619 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \
0620 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
0621
0622
0623
0624
0625
0626
0627 static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
0628 {
0629 u8 i;
0630
0631 for (i = 0; i < segs_cnt; i++) {
0632
0633 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
0634 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
0635 return -EINVAL;
0636
0637
0638 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
0639 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
0640 return -EINVAL;
0641 }
0642
0643 return 0;
0644 }
0645
0646
0647 #define ICE_FLOW_PROT_HDR_SZ_MAC 14
0648 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN (ICE_FLOW_PROT_HDR_SZ_MAC + 2)
0649 #define ICE_FLOW_PROT_HDR_SZ_IPV4 20
0650 #define ICE_FLOW_PROT_HDR_SZ_IPV6 40
0651 #define ICE_FLOW_PROT_HDR_SZ_ARP 28
0652 #define ICE_FLOW_PROT_HDR_SZ_ICMP 8
0653 #define ICE_FLOW_PROT_HDR_SZ_TCP 20
0654 #define ICE_FLOW_PROT_HDR_SZ_UDP 8
0655 #define ICE_FLOW_PROT_HDR_SZ_SCTP 12
0656
0657
0658
0659
0660
0661
0662 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
0663 {
0664 u16 sz;
0665
0666
0667 sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
0668 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
0669
0670
0671 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
0672 sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
0673 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
0674 sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
0675 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
0676 sz += ICE_FLOW_PROT_HDR_SZ_ARP;
0677 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
0678
0679 return 0;
0680
0681
0682 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
0683 sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
0684 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
0685 sz += ICE_FLOW_PROT_HDR_SZ_TCP;
0686 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
0687 sz += ICE_FLOW_PROT_HDR_SZ_UDP;
0688 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
0689 sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
0690
0691 return sz;
0692 }
0693
0694
0695
0696
0697
0698
0699
0700
0701 static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
0702 {
0703 struct ice_flow_prof *prof;
0704 u8 i;
0705
0706 memset(params->ptypes, 0xff, sizeof(params->ptypes));
0707
0708 prof = params->prof;
0709
0710 for (i = 0; i < params->prof->segs_cnt; i++) {
0711 const unsigned long *src;
0712 u32 hdrs;
0713
0714 hdrs = prof->segs[i].hdrs;
0715
0716 if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
0717 src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
0718 (const unsigned long *)ice_ptypes_mac_il;
0719 bitmap_and(params->ptypes, params->ptypes, src,
0720 ICE_FLOW_PTYPE_MAX);
0721 }
0722
0723 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
0724 src = (const unsigned long *)ice_ptypes_macvlan_il;
0725 bitmap_and(params->ptypes, params->ptypes, src,
0726 ICE_FLOW_PTYPE_MAX);
0727 }
0728
0729 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
0730 bitmap_and(params->ptypes, params->ptypes,
0731 (const unsigned long *)ice_ptypes_arp_of,
0732 ICE_FLOW_PTYPE_MAX);
0733 }
0734
0735 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
0736 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
0737 src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
0738 (const unsigned long *)ice_ptypes_ipv4_ofos_all;
0739 bitmap_and(params->ptypes, params->ptypes, src,
0740 ICE_FLOW_PTYPE_MAX);
0741 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
0742 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
0743 src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
0744 (const unsigned long *)ice_ptypes_ipv6_ofos_all;
0745 bitmap_and(params->ptypes, params->ptypes, src,
0746 ICE_FLOW_PTYPE_MAX);
0747 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
0748 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
0749 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
0750 (const unsigned long *)ice_ptypes_ipv4_il_no_l4;
0751 bitmap_and(params->ptypes, params->ptypes, src,
0752 ICE_FLOW_PTYPE_MAX);
0753 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
0754 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
0755 (const unsigned long *)ice_ptypes_ipv4_il;
0756 bitmap_and(params->ptypes, params->ptypes, src,
0757 ICE_FLOW_PTYPE_MAX);
0758 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
0759 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
0760 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
0761 (const unsigned long *)ice_ptypes_ipv6_il_no_l4;
0762 bitmap_and(params->ptypes, params->ptypes, src,
0763 ICE_FLOW_PTYPE_MAX);
0764 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
0765 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
0766 (const unsigned long *)ice_ptypes_ipv6_il;
0767 bitmap_and(params->ptypes, params->ptypes, src,
0768 ICE_FLOW_PTYPE_MAX);
0769 }
0770
0771 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
0772 src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
0773 bitmap_and(params->ptypes, params->ptypes, src,
0774 ICE_FLOW_PTYPE_MAX);
0775 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
0776 src = (const unsigned long *)ice_ptypes_pppoe;
0777 bitmap_and(params->ptypes, params->ptypes, src,
0778 ICE_FLOW_PTYPE_MAX);
0779 } else {
0780 src = (const unsigned long *)ice_ptypes_pppoe;
0781 bitmap_andnot(params->ptypes, params->ptypes, src,
0782 ICE_FLOW_PTYPE_MAX);
0783 }
0784
0785 if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
0786 src = (const unsigned long *)ice_ptypes_udp_il;
0787 bitmap_and(params->ptypes, params->ptypes, src,
0788 ICE_FLOW_PTYPE_MAX);
0789 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
0790 bitmap_and(params->ptypes, params->ptypes,
0791 (const unsigned long *)ice_ptypes_tcp_il,
0792 ICE_FLOW_PTYPE_MAX);
0793 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
0794 src = (const unsigned long *)ice_ptypes_sctp_il;
0795 bitmap_and(params->ptypes, params->ptypes, src,
0796 ICE_FLOW_PTYPE_MAX);
0797 }
0798
0799 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
0800 src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
0801 (const unsigned long *)ice_ptypes_icmp_il;
0802 bitmap_and(params->ptypes, params->ptypes, src,
0803 ICE_FLOW_PTYPE_MAX);
0804 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
0805 if (!i) {
0806 src = (const unsigned long *)ice_ptypes_gre_of;
0807 bitmap_and(params->ptypes, params->ptypes,
0808 src, ICE_FLOW_PTYPE_MAX);
0809 }
0810 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
0811 src = (const unsigned long *)ice_ptypes_gtpc;
0812 bitmap_and(params->ptypes, params->ptypes, src,
0813 ICE_FLOW_PTYPE_MAX);
0814 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
0815 src = (const unsigned long *)ice_ptypes_gtpc_tid;
0816 bitmap_and(params->ptypes, params->ptypes, src,
0817 ICE_FLOW_PTYPE_MAX);
0818 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
0819 src = (const unsigned long *)ice_ptypes_gtpu;
0820 bitmap_and(params->ptypes, params->ptypes, src,
0821 ICE_FLOW_PTYPE_MAX);
0822
0823
0824 params->attr = ice_attr_gtpu_down;
0825 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
0826 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
0827 src = (const unsigned long *)ice_ptypes_gtpu;
0828 bitmap_and(params->ptypes, params->ptypes, src,
0829 ICE_FLOW_PTYPE_MAX);
0830
0831
0832 params->attr = ice_attr_gtpu_up;
0833 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
0834 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
0835 src = (const unsigned long *)ice_ptypes_gtpu;
0836 bitmap_and(params->ptypes, params->ptypes, src,
0837 ICE_FLOW_PTYPE_MAX);
0838
0839
0840 params->attr = ice_attr_gtpu_eh;
0841 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
0842 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
0843 src = (const unsigned long *)ice_ptypes_gtpu;
0844 bitmap_and(params->ptypes, params->ptypes, src,
0845 ICE_FLOW_PTYPE_MAX);
0846 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
0847 src = (const unsigned long *)ice_ptypes_l2tpv3;
0848 bitmap_and(params->ptypes, params->ptypes, src,
0849 ICE_FLOW_PTYPE_MAX);
0850 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
0851 src = (const unsigned long *)ice_ptypes_esp;
0852 bitmap_and(params->ptypes, params->ptypes, src,
0853 ICE_FLOW_PTYPE_MAX);
0854 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
0855 src = (const unsigned long *)ice_ptypes_ah;
0856 bitmap_and(params->ptypes, params->ptypes, src,
0857 ICE_FLOW_PTYPE_MAX);
0858 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
0859 src = (const unsigned long *)ice_ptypes_nat_t_esp;
0860 bitmap_and(params->ptypes, params->ptypes, src,
0861 ICE_FLOW_PTYPE_MAX);
0862 }
0863
0864 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
0865 if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
0866 src = (const unsigned long *)ice_ptypes_pfcp_node;
0867 else
0868 src = (const unsigned long *)ice_ptypes_pfcp_session;
0869
0870 bitmap_and(params->ptypes, params->ptypes, src,
0871 ICE_FLOW_PTYPE_MAX);
0872 } else {
0873 src = (const unsigned long *)ice_ptypes_pfcp_node;
0874 bitmap_andnot(params->ptypes, params->ptypes, src,
0875 ICE_FLOW_PTYPE_MAX);
0876
0877 src = (const unsigned long *)ice_ptypes_pfcp_session;
0878 bitmap_andnot(params->ptypes, params->ptypes, src,
0879 ICE_FLOW_PTYPE_MAX);
0880 }
0881 }
0882
0883 return 0;
0884 }
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898 static int
0899 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
0900 u8 seg, enum ice_flow_field fld, u64 match)
0901 {
0902 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
0903 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
0904 u8 fv_words = hw->blk[params->blk].es.fvw;
0905 struct ice_flow_fld_info *flds;
0906 u16 cnt, ese_bits, i;
0907 u16 sib_mask = 0;
0908 u16 mask;
0909 u16 off;
0910
0911 flds = params->prof->segs[seg].fields;
0912
0913 switch (fld) {
0914 case ICE_FLOW_FIELD_IDX_ETH_DA:
0915 case ICE_FLOW_FIELD_IDX_ETH_SA:
0916 case ICE_FLOW_FIELD_IDX_S_VLAN:
0917 case ICE_FLOW_FIELD_IDX_C_VLAN:
0918 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
0919 break;
0920 case ICE_FLOW_FIELD_IDX_ETH_TYPE:
0921 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
0922 break;
0923 case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
0924 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
0925 break;
0926 case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
0927 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
0928 break;
0929 case ICE_FLOW_FIELD_IDX_IPV4_TTL:
0930 case ICE_FLOW_FIELD_IDX_IPV4_PROT:
0931 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
0932
0933
0934
0935
0936
0937 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
0938 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
0939 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
0940 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
0941
0942
0943
0944
0945 if (match & BIT(sib))
0946 sib_mask = ice_flds_info[sib].mask;
0947 break;
0948 case ICE_FLOW_FIELD_IDX_IPV6_TTL:
0949 case ICE_FLOW_FIELD_IDX_IPV6_PROT:
0950 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
0951
0952
0953
0954
0955
0956 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
0957 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
0958 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
0959 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
0960
0961
0962
0963
0964 if (match & BIT(sib))
0965 sib_mask = ice_flds_info[sib].mask;
0966 break;
0967 case ICE_FLOW_FIELD_IDX_IPV4_SA:
0968 case ICE_FLOW_FIELD_IDX_IPV4_DA:
0969 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
0970 break;
0971 case ICE_FLOW_FIELD_IDX_IPV6_SA:
0972 case ICE_FLOW_FIELD_IDX_IPV6_DA:
0973 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
0974 break;
0975 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
0976 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
0977 case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
0978 prot_id = ICE_PROT_TCP_IL;
0979 break;
0980 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
0981 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
0982 prot_id = ICE_PROT_UDP_IL_OR_S;
0983 break;
0984 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
0985 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
0986 prot_id = ICE_PROT_SCTP_IL;
0987 break;
0988 case ICE_FLOW_FIELD_IDX_GTPC_TEID:
0989 case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
0990 case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
0991 case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
0992 case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
0993 case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
0994
0995 prot_id = ICE_PROT_UDP_OF;
0996 break;
0997 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
0998 prot_id = ICE_PROT_PPPOE;
0999 break;
1000 case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1001 prot_id = ICE_PROT_UDP_IL_OR_S;
1002 break;
1003 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1004 prot_id = ICE_PROT_L2TPV3;
1005 break;
1006 case ICE_FLOW_FIELD_IDX_ESP_SPI:
1007 prot_id = ICE_PROT_ESP_F;
1008 break;
1009 case ICE_FLOW_FIELD_IDX_AH_SPI:
1010 prot_id = ICE_PROT_ESP_2;
1011 break;
1012 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1013 prot_id = ICE_PROT_UDP_IL_OR_S;
1014 break;
1015 case ICE_FLOW_FIELD_IDX_ARP_SIP:
1016 case ICE_FLOW_FIELD_IDX_ARP_DIP:
1017 case ICE_FLOW_FIELD_IDX_ARP_SHA:
1018 case ICE_FLOW_FIELD_IDX_ARP_DHA:
1019 case ICE_FLOW_FIELD_IDX_ARP_OP:
1020 prot_id = ICE_PROT_ARP_OF;
1021 break;
1022 case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1023 case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1024
1025 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1026 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1027 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1028 ICE_FLOW_FIELD_IDX_ICMP_CODE :
1029 ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1030 break;
1031 case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1032 prot_id = ICE_PROT_GRE_OF;
1033 break;
1034 default:
1035 return -EOPNOTSUPP;
1036 }
1037
1038
1039
1040
1041 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1042
1043 flds[fld].xtrct.prot_id = prot_id;
1044 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1045 ICE_FLOW_FV_EXTRACT_SZ;
1046 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1047 flds[fld].xtrct.idx = params->es_cnt;
1048 flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1049
1050
1051
1052
1053 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1054 ese_bits);
1055
1056
1057 off = flds[fld].xtrct.off;
1058 mask = flds[fld].xtrct.mask;
1059 for (i = 0; i < cnt; i++) {
1060
1061
1062
1063
1064 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1065 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1066 flds[sib].xtrct.off != off) {
1067 u8 idx;
1068
1069
1070
1071
1072 if (params->es_cnt >= fv_words)
1073 return -ENOSPC;
1074
1075
1076 if (hw->blk[params->blk].es.reverse)
1077 idx = fv_words - params->es_cnt - 1;
1078 else
1079 idx = params->es_cnt;
1080
1081 params->es[idx].prot_id = prot_id;
1082 params->es[idx].off = off;
1083 params->mask[idx] = mask | sib_mask;
1084 params->es_cnt++;
1085 }
1086
1087 off += ICE_FLOW_FV_EXTRACT_SZ;
1088 }
1089
1090 return 0;
1091 }
1092
1093
1094
1095
1096
1097
1098
1099 static int
1100 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1101 u8 seg)
1102 {
1103 u16 fv_words;
1104 u16 hdrs_sz;
1105 u8 i;
1106
1107 if (!params->prof->segs[seg].raws_cnt)
1108 return 0;
1109
1110 if (params->prof->segs[seg].raws_cnt >
1111 ARRAY_SIZE(params->prof->segs[seg].raws))
1112 return -ENOSPC;
1113
1114
1115 hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1116 if (!hdrs_sz)
1117 return -EINVAL;
1118
1119 fv_words = hw->blk[params->blk].es.fvw;
1120
1121 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1122 struct ice_flow_seg_fld_raw *raw;
1123 u16 off, cnt, j;
1124
1125 raw = ¶ms->prof->segs[seg].raws[i];
1126
1127
1128 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1129 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1130 ICE_FLOW_FV_EXTRACT_SZ;
1131 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1132 BITS_PER_BYTE;
1133 raw->info.xtrct.idx = params->es_cnt;
1134
1135
1136
1137
1138 cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1139 (raw->info.src.last * BITS_PER_BYTE),
1140 (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1141 off = raw->info.xtrct.off;
1142 for (j = 0; j < cnt; j++) {
1143 u16 idx;
1144
1145
1146
1147
1148 if (params->es_cnt >= hw->blk[params->blk].es.count ||
1149 params->es_cnt >= ICE_MAX_FV_WORDS)
1150 return -ENOSPC;
1151
1152
1153 if (hw->blk[params->blk].es.reverse)
1154 idx = fv_words - params->es_cnt - 1;
1155 else
1156 idx = params->es_cnt;
1157
1158 params->es[idx].prot_id = raw->info.xtrct.prot_id;
1159 params->es[idx].off = off;
1160 params->es_cnt++;
1161 off += ICE_FLOW_FV_EXTRACT_SZ;
1162 }
1163 }
1164
1165 return 0;
1166 }
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176 static int
1177 ice_flow_create_xtrct_seq(struct ice_hw *hw,
1178 struct ice_flow_prof_params *params)
1179 {
1180 struct ice_flow_prof *prof = params->prof;
1181 int status = 0;
1182 u8 i;
1183
1184 for (i = 0; i < prof->segs_cnt; i++) {
1185 u64 match = params->prof->segs[i].match;
1186 enum ice_flow_field j;
1187
1188 for_each_set_bit(j, (unsigned long *)&match,
1189 ICE_FLOW_FIELD_IDX_MAX) {
1190 status = ice_flow_xtract_fld(hw, params, i, j, match);
1191 if (status)
1192 return status;
1193 clear_bit(j, (unsigned long *)&match);
1194 }
1195
1196
1197 status = ice_flow_xtract_raws(hw, params, i);
1198 if (status)
1199 return status;
1200 }
1201
1202 return status;
1203 }
1204
1205
1206
1207
1208
1209
1210 static int
1211 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1212 {
1213 int status;
1214
1215 status = ice_flow_proc_seg_hdrs(params);
1216 if (status)
1217 return status;
1218
1219 status = ice_flow_create_xtrct_seq(hw, params);
1220 if (status)
1221 return status;
1222
1223 switch (params->blk) {
1224 case ICE_BLK_FD:
1225 case ICE_BLK_RSS:
1226 status = 0;
1227 break;
1228 default:
1229 return -EOPNOTSUPP;
1230 }
1231
1232 return status;
1233 }
1234
1235 #define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001
1236 #define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002
1237 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249 static struct ice_flow_prof *
1250 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1251 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1252 u8 segs_cnt, u16 vsi_handle, u32 conds)
1253 {
1254 struct ice_flow_prof *p, *prof = NULL;
1255
1256 mutex_lock(&hw->fl_profs_locks[blk]);
1257 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1258 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1259 segs_cnt && segs_cnt == p->segs_cnt) {
1260 u8 i;
1261
1262
1263 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1264 ice_is_vsi_valid(hw, vsi_handle) &&
1265 !test_bit(vsi_handle, p->vsis))
1266 continue;
1267
1268
1269
1270
1271 for (i = 0; i < segs_cnt; i++)
1272 if (segs[i].hdrs != p->segs[i].hdrs ||
1273 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1274 segs[i].match != p->segs[i].match))
1275 break;
1276
1277
1278 if (i == segs_cnt) {
1279 prof = p;
1280 break;
1281 }
1282 }
1283 mutex_unlock(&hw->fl_profs_locks[blk]);
1284
1285 return prof;
1286 }
1287
1288
1289
1290
1291
1292
1293
1294 static struct ice_flow_prof *
1295 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1296 {
1297 struct ice_flow_prof *p;
1298
1299 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1300 if (p->id == prof_id)
1301 return p;
1302
1303 return NULL;
1304 }
1305
1306
1307
1308
1309
1310
1311 static void
1312 ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1313 {
1314 if (!entry)
1315 return;
1316
1317 if (entry->entry)
1318 devm_kfree(ice_hw_to_dev(hw), entry->entry);
1319
1320 devm_kfree(ice_hw_to_dev(hw), entry);
1321 }
1322
1323
1324
1325
1326
1327
1328
1329 static int
1330 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1331 struct ice_flow_entry *entry)
1332 {
1333 if (!entry)
1334 return -EINVAL;
1335
1336 list_del(&entry->l_entry);
1337
1338 ice_dealloc_flow_entry(hw, entry);
1339
1340 return 0;
1341 }
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355 static int
1356 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1357 enum ice_flow_dir dir, u64 prof_id,
1358 struct ice_flow_seg_info *segs, u8 segs_cnt,
1359 struct ice_flow_prof **prof)
1360 {
1361 struct ice_flow_prof_params *params;
1362 int status;
1363 u8 i;
1364
1365 if (!prof)
1366 return -EINVAL;
1367
1368 params = kzalloc(sizeof(*params), GFP_KERNEL);
1369 if (!params)
1370 return -ENOMEM;
1371
1372 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1373 GFP_KERNEL);
1374 if (!params->prof) {
1375 status = -ENOMEM;
1376 goto free_params;
1377 }
1378
1379
1380 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1381 params->es[i].prot_id = ICE_PROT_INVALID;
1382 params->es[i].off = ICE_FV_OFFSET_INVAL;
1383 }
1384
1385 params->blk = blk;
1386 params->prof->id = prof_id;
1387 params->prof->dir = dir;
1388 params->prof->segs_cnt = segs_cnt;
1389
1390
1391
1392
1393 for (i = 0; i < segs_cnt; i++)
1394 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs));
1395
1396 status = ice_flow_proc_segs(hw, params);
1397 if (status) {
1398 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1399 goto out;
1400 }
1401
1402
1403 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1404 params->attr, params->attr_cnt, params->es,
1405 params->mask);
1406 if (status) {
1407 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1408 goto out;
1409 }
1410
1411 INIT_LIST_HEAD(¶ms->prof->entries);
1412 mutex_init(¶ms->prof->entries_lock);
1413 *prof = params->prof;
1414
1415 out:
1416 if (status)
1417 devm_kfree(ice_hw_to_dev(hw), params->prof);
1418 free_params:
1419 kfree(params);
1420
1421 return status;
1422 }
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432 static int
1433 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1434 struct ice_flow_prof *prof)
1435 {
1436 int status;
1437
1438
1439 if (!list_empty(&prof->entries)) {
1440 struct ice_flow_entry *e, *t;
1441
1442 mutex_lock(&prof->entries_lock);
1443
1444 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1445 status = ice_flow_rem_entry_sync(hw, blk, e);
1446 if (status)
1447 break;
1448 }
1449
1450 mutex_unlock(&prof->entries_lock);
1451 }
1452
1453
1454 status = ice_rem_prof(hw, blk, prof->id);
1455 if (!status) {
1456 list_del(&prof->l_entry);
1457 mutex_destroy(&prof->entries_lock);
1458 devm_kfree(ice_hw_to_dev(hw), prof);
1459 }
1460
1461 return status;
1462 }
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474 static int
1475 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1476 struct ice_flow_prof *prof, u16 vsi_handle)
1477 {
1478 int status = 0;
1479
1480 if (!test_bit(vsi_handle, prof->vsis)) {
1481 status = ice_add_prof_id_flow(hw, blk,
1482 ice_get_hw_vsi_num(hw,
1483 vsi_handle),
1484 prof->id);
1485 if (!status)
1486 set_bit(vsi_handle, prof->vsis);
1487 else
1488 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1489 status);
1490 }
1491
1492 return status;
1493 }
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505 static int
1506 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1507 struct ice_flow_prof *prof, u16 vsi_handle)
1508 {
1509 int status = 0;
1510
1511 if (test_bit(vsi_handle, prof->vsis)) {
1512 status = ice_rem_prof_id_flow(hw, blk,
1513 ice_get_hw_vsi_num(hw,
1514 vsi_handle),
1515 prof->id);
1516 if (!status)
1517 clear_bit(vsi_handle, prof->vsis);
1518 else
1519 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1520 status);
1521 }
1522
1523 return status;
1524 }
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536 int
1537 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1538 u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1539 struct ice_flow_prof **prof)
1540 {
1541 int status;
1542
1543 if (segs_cnt > ICE_FLOW_SEG_MAX)
1544 return -ENOSPC;
1545
1546 if (!segs_cnt)
1547 return -EINVAL;
1548
1549 if (!segs)
1550 return -EINVAL;
1551
1552 status = ice_flow_val_hdrs(segs, segs_cnt);
1553 if (status)
1554 return status;
1555
1556 mutex_lock(&hw->fl_profs_locks[blk]);
1557
1558 status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1559 prof);
1560 if (!status)
1561 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1562
1563 mutex_unlock(&hw->fl_profs_locks[blk]);
1564
1565 return status;
1566 }
1567
1568
1569
1570
1571
1572
1573
1574 int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1575 {
1576 struct ice_flow_prof *prof;
1577 int status;
1578
1579 mutex_lock(&hw->fl_profs_locks[blk]);
1580
1581 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1582 if (!prof) {
1583 status = -ENOENT;
1584 goto out;
1585 }
1586
1587
1588 status = ice_flow_rem_prof_sync(hw, blk, prof);
1589
1590 out:
1591 mutex_unlock(&hw->fl_profs_locks[blk]);
1592
1593 return status;
1594 }
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607 int
1608 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1609 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1610 void *data, u64 *entry_h)
1611 {
1612 struct ice_flow_entry *e = NULL;
1613 struct ice_flow_prof *prof;
1614 int status;
1615
1616
1617 if (!entry_h || (!data && blk != ICE_BLK_RSS))
1618 return -EINVAL;
1619
1620 if (!ice_is_vsi_valid(hw, vsi_handle))
1621 return -EINVAL;
1622
1623 mutex_lock(&hw->fl_profs_locks[blk]);
1624
1625 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1626 if (!prof) {
1627 status = -ENOENT;
1628 } else {
1629
1630
1631
1632 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1633 if (!e)
1634 status = -ENOMEM;
1635 else
1636 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1637 }
1638
1639 mutex_unlock(&hw->fl_profs_locks[blk]);
1640 if (status)
1641 goto out;
1642
1643 e->id = entry_id;
1644 e->vsi_handle = vsi_handle;
1645 e->prof = prof;
1646 e->priority = prio;
1647
1648 switch (blk) {
1649 case ICE_BLK_FD:
1650 case ICE_BLK_RSS:
1651 break;
1652 default:
1653 status = -EOPNOTSUPP;
1654 goto out;
1655 }
1656
1657 mutex_lock(&prof->entries_lock);
1658 list_add(&e->l_entry, &prof->entries);
1659 mutex_unlock(&prof->entries_lock);
1660
1661 *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1662
1663 out:
1664 if (status && e) {
1665 if (e->entry)
1666 devm_kfree(ice_hw_to_dev(hw), e->entry);
1667 devm_kfree(ice_hw_to_dev(hw), e);
1668 }
1669
1670 return status;
1671 }
1672
1673
1674
1675
1676
1677
1678
1679 int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1680 {
1681 struct ice_flow_entry *entry;
1682 struct ice_flow_prof *prof;
1683 int status = 0;
1684
1685 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1686 return -EINVAL;
1687
1688 entry = ICE_FLOW_ENTRY_PTR(entry_h);
1689
1690
1691 prof = entry->prof;
1692
1693 if (prof) {
1694 mutex_lock(&prof->entries_lock);
1695 status = ice_flow_rem_entry_sync(hw, blk, entry);
1696 mutex_unlock(&prof->entries_lock);
1697 }
1698
1699 return status;
1700 }
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725 static void
1726 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1727 enum ice_flow_fld_match_type field_type, u16 val_loc,
1728 u16 mask_loc, u16 last_loc)
1729 {
1730 u64 bit = BIT_ULL(fld);
1731
1732 seg->match |= bit;
1733 if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1734 seg->range |= bit;
1735
1736 seg->fields[fld].type = field_type;
1737 seg->fields[fld].src.val = val_loc;
1738 seg->fields[fld].src.mask = mask_loc;
1739 seg->fields[fld].src.last = last_loc;
1740
1741 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1742 }
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764 void
1765 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1766 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1767 {
1768 enum ice_flow_fld_match_type t = range ?
1769 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1770
1771 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1772 }
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791 void
1792 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1793 u16 val_loc, u16 mask_loc)
1794 {
1795 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1796 seg->raws[seg->raws_cnt].off = off;
1797 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1798 seg->raws[seg->raws_cnt].info.src.val = val_loc;
1799 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1800
1801 seg->raws[seg->raws_cnt].info.src.last = len;
1802 }
1803
1804
1805
1806
1807 seg->raws_cnt++;
1808 }
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819 int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id)
1820 {
1821 struct ice_flow_prof *prof;
1822 int status = 0;
1823
1824 if (!ice_is_vsi_valid(hw, vsi_handle))
1825 return -EINVAL;
1826
1827
1828 prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
1829 if (!prof) {
1830 ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n",
1831 prof_id);
1832 return -ENOENT;
1833 }
1834
1835
1836 if (!list_empty(&prof->entries)) {
1837 struct ice_flow_entry *e, *t;
1838
1839 mutex_lock(&prof->entries_lock);
1840 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1841 if (e->vsi_handle != vsi_handle)
1842 continue;
1843
1844 status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e);
1845 if (status)
1846 break;
1847 }
1848 mutex_unlock(&prof->entries_lock);
1849 }
1850 if (status)
1851 return status;
1852
1853
1854 status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle);
1855 if (status)
1856 ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n",
1857 status);
1858 return status;
1859 }
1860
1861 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1862 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1863
1864 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1865 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1866
1867 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1868 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1869
1870 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1871 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1872 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1873 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885 static int
1886 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1887 u32 flow_hdr)
1888 {
1889 u64 val;
1890 u8 i;
1891
1892 for_each_set_bit(i, (unsigned long *)&hash_fields,
1893 ICE_FLOW_FIELD_IDX_MAX)
1894 ice_flow_set_fld(segs, (enum ice_flow_field)i,
1895 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1896 ICE_FLOW_FLD_OFF_INVAL, false);
1897
1898 ICE_FLOW_SET_HDRS(segs, flow_hdr);
1899
1900 if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1901 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
1902 return -EINVAL;
1903
1904 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1905 if (val && !is_power_of_2(val))
1906 return -EIO;
1907
1908 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1909 if (val && !is_power_of_2(val))
1910 return -EIO;
1911
1912 return 0;
1913 }
1914
1915
1916
1917
1918
1919
1920
1921
1922 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1923 {
1924 struct ice_rss_cfg *r, *tmp;
1925
1926 if (list_empty(&hw->rss_list_head))
1927 return;
1928
1929 mutex_lock(&hw->rss_locks);
1930 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1931 if (test_and_clear_bit(vsi_handle, r->vsis))
1932 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1933 list_del(&r->l_entry);
1934 devm_kfree(ice_hw_to_dev(hw), r);
1935 }
1936 mutex_unlock(&hw->rss_locks);
1937 }
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948 int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1949 {
1950 const enum ice_block blk = ICE_BLK_RSS;
1951 struct ice_flow_prof *p, *t;
1952 int status = 0;
1953
1954 if (!ice_is_vsi_valid(hw, vsi_handle))
1955 return -EINVAL;
1956
1957 if (list_empty(&hw->fl_profs[blk]))
1958 return 0;
1959
1960 mutex_lock(&hw->rss_locks);
1961 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
1962 if (test_bit(vsi_handle, p->vsis)) {
1963 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1964 if (status)
1965 break;
1966
1967 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
1968 status = ice_flow_rem_prof(hw, blk, p->id);
1969 if (status)
1970 break;
1971 }
1972 }
1973 mutex_unlock(&hw->rss_locks);
1974
1975 return status;
1976 }
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986 static void
1987 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1988 {
1989 struct ice_rss_cfg *r, *tmp;
1990
1991
1992
1993
1994
1995 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1996 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1997 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1998 clear_bit(vsi_handle, r->vsis);
1999 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
2000 list_del(&r->l_entry);
2001 devm_kfree(ice_hw_to_dev(hw), r);
2002 }
2003 return;
2004 }
2005 }
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015 static int
2016 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2017 {
2018 struct ice_rss_cfg *r, *rss_cfg;
2019
2020 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2021 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
2022 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
2023 set_bit(vsi_handle, r->vsis);
2024 return 0;
2025 }
2026
2027 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
2028 GFP_KERNEL);
2029 if (!rss_cfg)
2030 return -ENOMEM;
2031
2032 rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
2033 rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
2034 set_bit(vsi_handle, rss_cfg->vsis);
2035
2036 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
2037
2038 return 0;
2039 }
2040
2041 #define ICE_FLOW_PROF_HASH_S 0
2042 #define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
2043 #define ICE_FLOW_PROF_HDR_S 32
2044 #define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
2045 #define ICE_FLOW_PROF_ENCAP_S 63
2046 #define ICE_FLOW_PROF_ENCAP_M (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
2047
2048 #define ICE_RSS_OUTER_HEADERS 1
2049 #define ICE_RSS_INNER_HEADERS 2
2050
2051
2052
2053
2054
2055
2056 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
2057 ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
2058 (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
2059 ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071 static int
2072 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2073 u32 addl_hdrs, u8 segs_cnt)
2074 {
2075 const enum ice_block blk = ICE_BLK_RSS;
2076 struct ice_flow_prof *prof = NULL;
2077 struct ice_flow_seg_info *segs;
2078 int status;
2079
2080 if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2081 return -EINVAL;
2082
2083 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2084 if (!segs)
2085 return -ENOMEM;
2086
2087
2088 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2089 addl_hdrs);
2090 if (status)
2091 goto exit;
2092
2093
2094
2095
2096
2097 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2098 vsi_handle,
2099 ICE_FLOW_FIND_PROF_CHK_FLDS |
2100 ICE_FLOW_FIND_PROF_CHK_VSI);
2101 if (prof)
2102 goto exit;
2103
2104
2105
2106
2107
2108
2109 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2110 vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2111 if (prof) {
2112 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2113 if (!status)
2114 ice_rem_rss_list(hw, vsi_handle, prof);
2115 else
2116 goto exit;
2117
2118
2119 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2120 status = ice_flow_rem_prof(hw, blk, prof->id);
2121 if (status)
2122 goto exit;
2123 }
2124 }
2125
2126
2127
2128
2129 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2130 vsi_handle,
2131 ICE_FLOW_FIND_PROF_CHK_FLDS);
2132 if (prof) {
2133 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2134 if (!status)
2135 status = ice_add_rss_list(hw, vsi_handle, prof);
2136 goto exit;
2137 }
2138
2139
2140
2141
2142 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2143 ICE_FLOW_GEN_PROFID(hashed_flds,
2144 segs[segs_cnt - 1].hdrs,
2145 segs_cnt),
2146 segs, segs_cnt, &prof);
2147 if (status)
2148 goto exit;
2149
2150 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2151
2152
2153
2154 if (status) {
2155 ice_flow_rem_prof(hw, blk, prof->id);
2156 goto exit;
2157 }
2158
2159 status = ice_add_rss_list(hw, vsi_handle, prof);
2160
2161 exit:
2162 kfree(segs);
2163 return status;
2164 }
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177 int
2178 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2179 u32 addl_hdrs)
2180 {
2181 int status;
2182
2183 if (hashed_flds == ICE_HASH_INVALID ||
2184 !ice_is_vsi_valid(hw, vsi_handle))
2185 return -EINVAL;
2186
2187 mutex_lock(&hw->rss_locks);
2188 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2189 ICE_RSS_OUTER_HEADERS);
2190 if (!status)
2191 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2192 addl_hdrs, ICE_RSS_INNER_HEADERS);
2193 mutex_unlock(&hw->rss_locks);
2194
2195 return status;
2196 }
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208 static int
2209 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2210 u32 addl_hdrs, u8 segs_cnt)
2211 {
2212 const enum ice_block blk = ICE_BLK_RSS;
2213 struct ice_flow_seg_info *segs;
2214 struct ice_flow_prof *prof;
2215 int status;
2216
2217 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2218 if (!segs)
2219 return -ENOMEM;
2220
2221
2222 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2223 addl_hdrs);
2224 if (status)
2225 goto out;
2226
2227 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2228 vsi_handle,
2229 ICE_FLOW_FIND_PROF_CHK_FLDS);
2230 if (!prof) {
2231 status = -ENOENT;
2232 goto out;
2233 }
2234
2235 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2236 if (status)
2237 goto out;
2238
2239
2240
2241
2242 ice_rem_rss_list(hw, vsi_handle, prof);
2243
2244 if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2245 status = ice_flow_rem_prof(hw, blk, prof->id);
2246
2247 out:
2248 kfree(segs);
2249 return status;
2250 }
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265 int __maybe_unused
2266 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2267 u32 addl_hdrs)
2268 {
2269 int status;
2270
2271 if (hashed_flds == ICE_HASH_INVALID ||
2272 !ice_is_vsi_valid(hw, vsi_handle))
2273 return -EINVAL;
2274
2275 mutex_lock(&hw->rss_locks);
2276 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2277 ICE_RSS_OUTER_HEADERS);
2278 if (!status)
2279 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2280 addl_hdrs, ICE_RSS_INNER_HEADERS);
2281 mutex_unlock(&hw->rss_locks);
2282
2283 return status;
2284 }
2285
2286
2287
2288
2289
2290 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2291 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2292 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2293 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2294 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2295 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2296 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2297 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2298 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2299 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2300 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2301 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2302 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2303
2304 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2305 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2306 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2307 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2308 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2309 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2310 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2311 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2312 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2313 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2314 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2315 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2316 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328 int ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
2329 {
2330 int status = 0;
2331 u64 hash_flds;
2332
2333 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2334 !ice_is_vsi_valid(hw, vsi_handle))
2335 return -EINVAL;
2336
2337
2338 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2339 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2340 return -EIO;
2341
2342 hash_flds = avf_hash;
2343
2344
2345 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2346 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2347
2348 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2349 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2350
2351
2352 while (hash_flds) {
2353 u64 rss_hash = ICE_HASH_INVALID;
2354
2355 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2356 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2357 rss_hash = ICE_FLOW_HASH_IPV4;
2358 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2359 } else if (hash_flds &
2360 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2361 rss_hash = ICE_FLOW_HASH_IPV4 |
2362 ICE_FLOW_HASH_TCP_PORT;
2363 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2364 } else if (hash_flds &
2365 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2366 rss_hash = ICE_FLOW_HASH_IPV4 |
2367 ICE_FLOW_HASH_UDP_PORT;
2368 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2369 } else if (hash_flds &
2370 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2371 rss_hash = ICE_FLOW_HASH_IPV4 |
2372 ICE_FLOW_HASH_SCTP_PORT;
2373 hash_flds &=
2374 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2375 }
2376 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2377 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2378 rss_hash = ICE_FLOW_HASH_IPV6;
2379 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2380 } else if (hash_flds &
2381 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2382 rss_hash = ICE_FLOW_HASH_IPV6 |
2383 ICE_FLOW_HASH_TCP_PORT;
2384 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2385 } else if (hash_flds &
2386 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2387 rss_hash = ICE_FLOW_HASH_IPV6 |
2388 ICE_FLOW_HASH_UDP_PORT;
2389 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2390 } else if (hash_flds &
2391 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2392 rss_hash = ICE_FLOW_HASH_IPV6 |
2393 ICE_FLOW_HASH_SCTP_PORT;
2394 hash_flds &=
2395 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2396 }
2397 }
2398
2399 if (rss_hash == ICE_HASH_INVALID)
2400 return -EIO;
2401
2402 status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
2403 ICE_FLOW_SEG_HDR_NONE);
2404 if (status)
2405 break;
2406 }
2407
2408 return status;
2409 }
2410
2411
2412
2413
2414
2415
2416 int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2417 {
2418 struct ice_rss_cfg *r;
2419 int status = 0;
2420
2421 if (!ice_is_vsi_valid(hw, vsi_handle))
2422 return -EINVAL;
2423
2424 mutex_lock(&hw->rss_locks);
2425 list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2426 if (test_bit(vsi_handle, r->vsis)) {
2427 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2428 r->hashed_flds,
2429 r->packet_hdr,
2430 ICE_RSS_OUTER_HEADERS);
2431 if (status)
2432 break;
2433 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2434 r->hashed_flds,
2435 r->packet_hdr,
2436 ICE_RSS_INNER_HEADERS);
2437 if (status)
2438 break;
2439 }
2440 }
2441 mutex_unlock(&hw->rss_locks);
2442
2443 return status;
2444 }
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2456 {
2457 u64 rss_hash = ICE_HASH_INVALID;
2458 struct ice_rss_cfg *r;
2459
2460
2461 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2462 return ICE_HASH_INVALID;
2463
2464 mutex_lock(&hw->rss_locks);
2465 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2466 if (test_bit(vsi_handle, r->vsis) &&
2467 r->packet_hdr == hdrs) {
2468 rss_hash = r->hashed_flds;
2469 break;
2470 }
2471 mutex_unlock(&hw->rss_locks);
2472
2473 return rss_hash;
2474 }